Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5edd962
docs(cua-driver): define native plugin rebuild profile contract
f-trycua Sep 10, 2026
9cc151e
build(cua-driver): prepare immutable Hyprland profile kits
f-trycua Sep 10, 2026
d66f191
build(cua-driver): pin measured Omarchy profile and header selection
f-trycua Sep 10, 2026
5b2f506
build(cua-driver): match native CMake pkgconf query semantics
f-trycua Sep 10, 2026
5452684
test(cua-driver): observe primary input independently on production p…
f-trycua Sep 10, 2026
bd13242
test(cua-driver): parse native Wayland clock timestamps
f-trycua Sep 10, 2026
d083bb6
test(cua-driver): retain known destroyed-buffer wire events
f-trycua Sep 10, 2026
6cb6c98
test(cua-driver): add opt-in Inkscape fault qualification profile
f-trycua Sep 10, 2026
67edb4f
docs(cua-driver): explain Inkscape package qualification profile
f-trycua Sep 10, 2026
74beef6
test(cua-driver): distinguish unchanged primary motion notifications
f-trycua Sep 10, 2026
0d44bbd
test(cua-driver): reject recycled primary observer identities
f-trycua Sep 10, 2026
59919bb
build(cua-driver): export pinned profile download recipes
f-trycua Sep 10, 2026
6bfab64
test(cua-driver): retain Inkscape status in bounded fault snapshots
f-trycua Sep 10, 2026
8fec3f6
test(cua-driver): qualify same-client agent conflict refusal
f-trycua Sep 10, 2026
a949373
test(cua-driver): gate desktop faults on observed drag motion
f-trycua Sep 10, 2026
807f43f
test(cua-driver): verify retained inert fault recovery
f-trycua Sep 10, 2026
5295fb6
test(cua-driver): scope fault snapshots to observing runtime
f-trycua Sep 10, 2026
b4b7d10
test(cua-driver): verify inert pointer recovery across desktop faults
f-trycua Sep 10, 2026
fa6a1ec
test(cua-driver): verify terminal connection cleanup on primary takeover
f-trycua Sep 10, 2026
e25ecd1
test(cua-driver): model bounded primary hover motion after idle
f-trycua Sep 10, 2026
0fbab0e
test(cua-driver): verify target-loss connection retirement
f-trycua Sep 10, 2026
1a9c498
build(cua-driver): bind repaired plugin source in profile kits
f-trycua Sep 10, 2026
e4dfabb
test(cua-driver): separate pixel selection from menu grounding
f-trycua Sep 10, 2026
136ceee
test(cua-driver): verify inert target-recovery retirement
f-trycua Sep 10, 2026
43682d8
docs(cua-driver): describe reviewed profile source selection
f-trycua Sep 10, 2026
2c7766f
Merge remote-tracking branch 'origin/main' into build/omarchy-native-…
f-trycua Sep 10, 2026
90b594d
docs(cua-driver): align primary observer duplicate contract
f-trycua Sep 10, 2026
a9a1481
Merge remote-tracking branch 'origin/main' into build/omarchy-native-…
f-trycua Sep 10, 2026
3617afa
Merge remote-tracking branch 'origin/main' into build/omarchy-native-…
f-trycua Sep 10, 2026
67f89ce
build(cua-driver): bind Omarchy profile to released 0.26.1 source
f-trycua Sep 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions libs/cua-driver/docs/test-harnesses-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ semantic AT-SPI actions are separate.
See [production proof preparation](../hyprland-plugin/tests/production-proof.md)
for the bounded plans and their limits.

The explicit [Inkscape-only qualification profile](../hyprland-plugin/tests/production-inkscape-profile.md)
supports a bounded packaging candidate using exact Inkscape `1.4.4-6`, with
independent native clients, two app lanes, separate SVG oracles, and third-owner
capacity refusal. It preserves the default Calc/Inkscape profile and the native
all-suite gate. Product, harness, kit, and mapped module identities remain
separate; adding the profile records no new native passing result and does not
let diagnostic trace evidence certify trace-disabled package bytes.

Three complete repetitions of the long Python Calc/Inkscape plan, including
the 34 policy cases across both apps, are no longer a merge requirement.
Extended Python stress runs remain diagnostics for specific unresolved
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Profile kit: original source bytes and separately committed packaging tooling.
# shellcheck shell=bash disable=SC2034,SC2154
pkgname=cua-hyprland-plugin
pkgver=@DRIVER_VERSION@
pkgrel=@PKGREL@
pkgdesc='Cua input candidate for reviewed profile @PROFILE_ID@'
arch=('x86_64')
url='https://github.com/trycua/cua'
license=('MIT')
depends=('hyprland=@HYPRLAND_PACKAGE@' @RUNTIME_DEPENDS@ 'python>=3.11' 'binutils')
makedepends=('cmake>=3.30' 'ninja' 'pkgconf' 'gcc')
options=('!strip' '!debug' '!lto')
_stem='@STEM@'
_archive_sha256='@ARCHIVE_SHA256@'
_kit_sha256='@KIT_SHA256@'
_profile_sha256='@PROFILE_SHA256@'
_verifier_sha256='@VERIFIER_SHA256@'
_cxx="${CUA_RELEASE_CXX:-/usr/bin/g++}"
source=("${_stem}.tar.gz" 'KIT-PROVENANCE.json' 'PROFILE.json' 'profile_verify.py')
sha256sums=('@ARCHIVE_SHA256@' '@KIT_SHA256@' '@PROFILE_SHA256@' '@VERIFIER_SHA256@')

_verify() {
# Explicit checks still apply to --skipinteg, --noextract and --repackage.
printf '%s %s\n' "$_archive_sha256" "$startdir/${_stem}.tar.gz" | sha256sum -c - || return 1
printf '%s %s\n' "$_kit_sha256" "$startdir/KIT-PROVENANCE.json" | sha256sum -c - || return 1
printf '%s %s\n' "$_profile_sha256" "$startdir/PROFILE.json" | sha256sum -c - || return 1
printf '%s %s\n' "$_verifier_sha256" "$startdir/profile_verify.py" | sha256sum -c - || return 1
python3 "$startdir/profile_verify.py" --kit "$startdir" --kit-sha256 "$_kit_sha256" \
--archive "$startdir/${_stem}.tar.gz" --source "$srcdir/$_stem" --cxx "$_cxx" "$@"
}

prepare() {
_verify
}

build() {
_verify || return 1
cmake -S "$srcdir/$_stem" -B "$srcdir/build" -G Ninja \
-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 \
-DCUA_HYPRLAND_EXPECTED_VERSION=0.56.2 \
-DCUA_HYPRLAND_INPUT=ON -DCUA_HYPRLAND_TEST_INPUT=OFF \
-DCUA_HYPRLAND_INPUT_TRACE=OFF -DCUA_HYPRLAND_TEST_OPERATOR_KEY= || return 1
cmake --build "$srcdir/build"
}

check() {
_verify || return 1
(
unset LD_PRELOAD FAKEROOTKEY FAKED_MODE
ctest --test-dir "$srcdir/build" --output-on-failure --no-tests=error
)
}

package() {
check || return 1
_verify --build "$srcdir/build" --output "$srcdir/BUILD-PROVENANCE.json" || return 1
install -Dm755 "$srcdir/build/cua-hyprland-plugin.so" \
"$pkgdir/usr/lib/cua/hyprland/cua-hyprland-plugin.so" || return 1
install -Dm644 "$srcdir/$_stem/LICENSE.md" \
"$pkgdir/usr/share/licenses/$pkgname/LICENSE" || return 1
install -Dm644 "$srcdir/$_stem/SOURCE-PROVENANCE.json" \
"$pkgdir/usr/share/$pkgname/SOURCE-PROVENANCE.json" || return 1
local name
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 "$startdir/$name" "$pkgdir/usr/share/$pkgname/$name" || return 1
done
}
120 changes: 120 additions & 0 deletions libs/cua-driver/hyprland-plugin/packaging/release/PROFILE-USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Build a reviewed native-profile package

This kit builds the plugin source selected in `PROFILE.json` for one explicitly
reviewed native profile. Schema 1 selects the original Driver 0.24.0 source;
schema 2 can select a separately reviewed source revision and Driver version.
The selected archive and its embedded manifest and verifier retain their
original bytes. The recipe uses `profile_verify.py` from this kit. It does not
invoke the embedded verifier or rewrite source files.

The kit, source, and native profile have separate identities. `PROFILE.json`
contains the profile ID, kit version, package release, source checksums, and
measured compiler, compositor, header-tree and shared-runtime identities.
`KIT-PROVENANCE.json` binds that profile's exact bytes to the committed tooling
and fixed production build options. `SHA256SUMS` includes the recipe, tooling,
profile, manifests and original source archive. None of these files asserts
native certification; use separately reviewed evidence for the exact package
bytes and environment before rollout.

## Prepare and inspect the kit

Obtain the kit and its outer checksum from the reviewed distribution channel.
Do not accept a newly downloaded profile because its values match your machine.
Verify the outer archive checksum against the independently reviewed value,
then extract into a dedicated empty directory and run:

```sh
sha256sum -c SHA256SUMS
```

Review `PKGBUILD`, `PROFILE.json`, and `KIT-PROVENANCE.json`. Retain the reviewed
SHA-256 of `KIT-PROVENANCE.json` separately for lifecycle and consumer checks.
Checksums establish agreement with reviewed files, not publisher authenticity.

Run `makepkg` as an ordinary user. The original source tarball is already in the
kit; no Git checkout or network source resolution is needed. The matching native
compiler, headers, runtime, CMake, Ninja, Python, pkg-config and binutils must
already be installed. To select a compiler outside `/usr/bin/g++`, set
`CUA_RELEASE_CXX` to its absolute path. The kit neither installs a compiler nor
changes runtime search paths or the desktop environment.

The recipe checks exact native package versions, compositor and compiler bytes,
GCC version/date and emitted ELF comment, the package-owned Hyprland header tree,
and matching shared-runtime bytes. These profiles require Hyprland 0.56.2
headers. CMake enables production input, disables experimental input and tracing,
and builds the bundled tests. Packaging runs CTest even with `--nocheck` or
`--repackage`; skipping makepkg integrity checks does not skip the recipe checks.

Build with the system `/usr/bin/pkgconf` and package-owned
`/usr/share/pkgconfig/hyprland.pc`. The canonical Hyprland header tree must lead
pkg-config's include selection: its hashed `protocols` directory may precede
the root, and the root must precede any external include directory. Other
include roots must be real paths under `/usr/include`. Clear pkg-config/CMake
routing overrides, compiler include-path
variables such as `CPATH` and `CPLUS_INCLUDE_PATH`, and flags that inject include
paths, headers, sysroots, toolchains or response files. Ordinary makepkg
optimization and hardening flags remain supported. The verifier refuses these
overrides instead of silently discarding them. It records the actual pkgconf
executable, `.pc` file digests and flags in build provenance, and checks CMake's
cached Hyprland flags against that same canonical selection. Queries use CMake's
fixed `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1` and `PKG_CONFIG_ALLOW_SYSTEM_LIBS=1`
semantics, preserving system `-I/usr/include` and `-L/usr/lib` flags for exact
cache comparison. Only the exact leading `/usr/include` system root is admitted
before the hashed Hyprland directories; an alternate `/usr/include/src` tree is
refused. Caller-supplied pkg-config overrides are still rejected. These are targeted
build-selection checks, not a sandbox for arbitrary build environments.

## Qualify package transactions

In a disposable matching Arch environment, with ordinary-user build tools and
previously authorized noninteractive sudo for isolated ALPM roots, run the
following command. Replace `SOURCE_REVISION` and `DRIVER_VERSION` with the exact
`source.revision` and `source.driver_version` from the reviewed `PROFILE.json`:

```sh
python3 lifecycle.py --kit . \
--revision SOURCE_REVISION \
--driver-version DRIVER_VERSION --kit-sha256 REVIEWED_KIT_PROVENANCE_SHA256 \
--output NEW_EVIDENCE_DIRECTORY
```

Add `--cxx /absolute/compiler/path` when needed. The runner validates the fresh
kit, builds the package, and checks its exact payload and provenance. It performs
install, remove, reinstall, and a paired dependency-refusal control in new
isolated ALPM roots. Dependency fixtures contain metadata only; native checks
are performed by the recipe. It does not alter the host package database or load
the module. A pass records kit/profile, package and payload hashes in `RESULT.json`.
Retain logs locally for review. Live activation, restart, upgrade, rollback and
native input qualification remain separate gates.

## Check and activate an installed package

Before installing, upgrading, rolling back, or removing the package, save work
and exit the Hyprland session. Use `pacman -U` from a text console with the exact
reviewed package file. Keep the prior package, matching dependencies and evidence
for rollback. Do not replace or unload the module inside a running compositor.

Installation includes the module, license, source/build/kit/profile provenance,
and the optional verifier. It has no hooks, autoload or configuration edits.
With Python 3.11+, binutils (`readelf`) and the system `ldd` available, check the
installed package using the previously reviewed kit-provenance digest:

```sh
python3 /usr/share/cua-hyprland-plugin/profile_verify.py \
--kit /usr/share/cua-hyprland-plugin \
--kit-sha256 REVIEWED_KIT_PROVENANCE_SHA256 \
--consumer /usr/lib/cua/hyprland/cua-hyprland-plugin.so
```

This check needs no compiler, headers, or pkg-config. It verifies the reviewed
profile/tooling identity, module and build provenance, exact installed ABI package
versions, compositor bytes/compiler comment, and compositor/module shared-runtime
bytes. It does not prove that a running compositor mapped these bytes or that
input works. Run it before deliberate activation in a fresh session. Follow the
separately qualified activation procedure and verify application results.

When ABI dependencies change, obtain a matching qualified package. If none is
available, exit the graphical session, remove the optional plugin package,
update the desktop and verify a fresh session. Disabling input alone does not
remove package dependencies. Rollback requires the matching saved package and
native environment followed by a fresh compositor session.
56 changes: 56 additions & 0 deletions libs/cua-driver/hyprland-plugin/packaging/release/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
# Pinned source release

For separately reviewed native profiles, see
[profile-based rebuilds](profile-contract.md) and
[profile kit usage](PROFILE-USAGE.md). Schema 1 preserves the original Driver
0.24.0 source archive; schema 2 supports a separately reviewed source revision.
The source archive generator described below remains separate from profile kits.

Prepare a profile kit only after committing the packaging tooling and reviewing
the measured profile:

```sh
python3 libs/cua-driver/hyprland-plugin/packaging/release/profile_bundle.py \
--repo . --tooling-revision FULL_TOOLING_COMMIT_SHA \
--profile REVIEWED_PROFILE.json --source-archive ORIGINAL_SOURCE.tar.gz \
--output NEW_OUTPUT_DIRECTORY
```

The executing generator/verifier must match that tooling commit. The generator
copies the supplied source archive byte-for-byte and emits one deterministic
kit archive plus its checksum. Its filename includes the original source
identity, profile ID, numeric kit version, full profile digest and tooling SHA.
It never publishes assets or overwrites an existing output directory.

Profile schema 1 requires these fields; all digests are lowercase SHA-256:

- `profile_id`: lowercase hyphen-separated identifier; `kit_version`: numeric
`major.minor.patch`; `package_release`: integer at least 2; `architecture`:
`x86_64`.
- `source`: `revision` = `4b3396d9fe4bd3cf723b0eb8db83c18a8764b520`,
`driver_version` = `0.24.0`, `archive_sha256` and `manifest_sha256` measured
from the reviewed original archive and its embedded `SOURCE-PROVENANCE.json`.
- `hyprland`: exact `package_version`, `header_version` = `0.56.2`, compositor
executable `sha256`, and `headers_sha256`.
- `compiler`: full GCC `version` including date, exact `comment` (the string
`GCC: (GNU) ` followed by that version), and executable `sha256`.
- `runtime`: resolved `basename`, file `sha256`, and `packages`, a mapping of
relevant installed ABI package names (for example `gcc-libs`, `libstdc++`,
`hyprutils` or `aquamarine`) to exact versions. Include only packages needed
by the measured selected ABI contract, including the shared-runtime owner;
do not copy an entire OS package list. `hyprland` is modeled separately.
Python and binutils are consumer-tool dependencies supplied by the recipe.

`headers_sha256` hashes the canonical JSON mapping of every package-owned file
under `/usr/include/hyprland/` from relative path to file SHA-256, serialized
with `json.dumps(mapping, sort_keys=True, indent=2) + "\n"`. The native verifier
also requires the on-disk header-tree file inventory to match `pacman -Qlq
hyprland` exactly, including plugin API headers. Symlinks are refused.
`profile_verify.header_inventory_sha256()` computes this inventory digest; it
does not accept or update a profile.

Keep the profile bytes immutable once reviewed. Assign a new monotonically
increasing `package_release` for every distributed rebuild at Driver 0.24.0,
including a profile or tooling change; a kit label alone cannot enforce ALPM
ordering. The archive digest and full profile/tooling identifiers distinguish
candidate artifacts. Distribution owners must enforce unique package revisions
and bind published package bytes to their native qualification evidence.

This directory prepares a standalone Arch recipe and source archive for the
production input candidate. It does not certify native behavior or publish
assets. The existing `../arch/PKGBUILD` remains a discovery-only local recipe.
Expand Down
Loading
Loading