release: correct ZUPT 5.2.3 integration

This commit is contained in:
Cristian Cezar Moisés 2026-08-31 15:33:17 -03:00
commit 09dc804b3e
31 changed files with 336 additions and 187 deletions

View file

@ -286,21 +286,25 @@ jobs:
DIST_DIR="$RUNNER_TEMP/release-deb" RUN_CHECKS=1 bash packaging/build-deb.sh
- name: Build and content-test the GUI DEB
run: |
version=$(sed -n 's/^#define ZUPT_VERSION_STRING "\([^"]*\)".*/\1/p' include/zupt.h)
test -n "$version"
mkdir -p "$RUNNER_TEMP/release-gui-deb"
DIST_DIR="$RUNNER_TEMP/release-gui-deb" bash packaging/build-gui-deb.sh
gui_deb="$RUNNER_TEMP/release-gui-deb/zupt-gui_5.2.2_all.deb"
gui_deb="$RUNNER_TEMP/release-gui-deb/zupt-gui_${version}_all.deb"
test -s "$gui_deb"
test "$(dpkg-deb -f "$gui_deb" Package)" = zupt-gui
test "$(dpkg-deb -f "$gui_deb" Version)" = 5.2.2
test "$(dpkg-deb -f "$gui_deb" Version)" = "$version"
test "$(dpkg-deb -f "$gui_deb" Architecture)" = all
- name: Install, functionally test and uninstall the DEBs
run: |
version=$(sed -n 's/^#define ZUPT_VERSION_STRING "\([^"]*\)".*/\1/p' include/zupt.h)
test -n "$version"
deb=$(find "$RUNNER_TEMP/release-deb" -maxdepth 1 -type f -name '*.deb' -print -quit)
gui_deb="$RUNNER_TEMP/release-gui-deb/zupt-gui_5.2.2_all.deb"
gui_deb="$RUNNER_TEMP/release-gui-deb/zupt-gui_${version}_all.deb"
test -n "$deb" && test -s "$gui_deb"
sudo apt-get install -y "$deb" "$gui_deb"
bash scripts/test-installed-zupt.sh /usr/bin/zupt
QT_QPA_PLATFORM=offscreen zupt-gui --version | grep -Fx "zupt-gui 5.2.2"
QT_QPA_PLATFORM=offscreen zupt-gui --version | grep -Fx "zupt-gui $version"
test ! -e /usr/bin/vaptvupt
sudo apt-get purge -y zupt-gui zupt
test ! -e /usr/bin/zupt-gui
@ -338,8 +342,13 @@ jobs:
fetch-depth: 0
lfs: false
submodules: false
- name: Trust the exact checked-out workspace
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Install native openSUSE tooling
run: |
if rpm -q busybox-gawk >/dev/null 2>&1; then
zypper --non-interactive remove busybox-gawk
fi
zypper --non-interactive install --no-recommends \
bash binutils cpio coreutils diffutils file findutils gawk gcc git-core grep gzip \
libxml2-tools make osc obs-service-obs_scm obs-service-recompress \
@ -433,6 +442,8 @@ jobs:
fetch-depth: 0
lfs: false
submodules: false
- name: Trust the exact checked-out workspace
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Install native build, package, audit and GUI runtime tools
run: |
dnf install -y \
@ -440,16 +451,19 @@ jobs:
python3 python3-pyside6 rpm-build rpmdevtools tar unzip
- name: Build and content-test the GUI RPM and source RPM
run: |
version=$(sed -n 's/^#define ZUPT_VERSION_STRING "\([^"]*\)".*/\1/p' include/zupt.h)
test -n "$version"
mkdir -p "$RUNNER_TEMP/release-gui-rpm"
DIST_DIR="$RUNNER_TEMP/release-gui-rpm" bash packaging/build-gui-rpm.sh
test -s "$RUNNER_TEMP/release-gui-rpm/zupt-gui-5.2.2-1.noarch.rpm"
test -s "$RUNNER_TEMP/release-gui-rpm/zupt-gui-5.2.2-1.src.rpm"
test "$(rpm -qp --qf '%{NAME}' "$RUNNER_TEMP/release-gui-rpm/zupt-gui-5.2.2-1.noarch.rpm")" = zupt-gui
test "$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "$RUNNER_TEMP/release-gui-rpm/zupt-gui-5.2.2-1.noarch.rpm")" = 5.2.2-1
test "$(rpm -qp --qf '%{ARCH}' "$RUNNER_TEMP/release-gui-rpm/zupt-gui-5.2.2-1.noarch.rpm")" = noarch
rpm -qp --requires "$RUNNER_TEMP/release-gui-rpm/zupt-gui-5.2.2-1.noarch.rpm" | \
grep -Fx 'zupt >= 5.2.2'
test "$(rpm -qp --qf '%{NAME}' "$RUNNER_TEMP/release-gui-rpm/zupt-gui-5.2.2-1.src.rpm")" = zupt-gui
gui_rpm="$RUNNER_TEMP/release-gui-rpm/zupt-gui-$version-1.noarch.rpm"
gui_srpm="$RUNNER_TEMP/release-gui-rpm/zupt-gui-$version-1.src.rpm"
test -s "$gui_rpm"
test -s "$gui_srpm"
test "$(rpm -qp --qf '%{NAME}' "$gui_rpm")" = zupt-gui
test "$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "$gui_rpm")" = "$version-1"
test "$(rpm -qp --qf '%{ARCH}' "$gui_rpm")" = noarch
rpm -qp --requires "$gui_rpm" | grep -Fx "zupt >= $version"
test "$(rpm -qp --qf '%{NAME}' "$gui_srpm")" = zupt-gui
- name: Build the matching Fedora CLI RPM
run: |
version=$(sed -n 's/^#define ZUPT_VERSION_STRING "\([^"]*\)".*/\1/p' include/zupt.h)
@ -459,14 +473,16 @@ jobs:
rpmbuild --define "_topdir $core_top" -ba packaging/rpm/zupt.spec
- name: Install and functionally test the GUI with the packaged CLI
run: |
version=$(sed -n 's/^#define ZUPT_VERSION_STRING "\([^"]*\)".*/\1/p' include/zupt.h)
test -n "$version"
core_rpm=$(find "$RUNNER_TEMP/core-rpmbuild/RPMS" -type f \
-name 'zupt-5.2.2-1.*.rpm' ! -name '*-debuginfo-*' \
-name "zupt-$version-1.*.rpm" ! -name '*-debuginfo-*' \
! -name '*-debugsource-*' -print -quit)
gui_rpm="$RUNNER_TEMP/release-gui-rpm/zupt-gui-5.2.2-1.noarch.rpm"
gui_rpm="$RUNNER_TEMP/release-gui-rpm/zupt-gui-$version-1.noarch.rpm"
test -n "$core_rpm" && test -s "$gui_rpm"
dnf install -y "$core_rpm" "$gui_rpm"
bash scripts/test-installed-zupt.sh /usr/bin/zupt
QT_QPA_PLATFORM=offscreen zupt-gui --version | grep -Fx 'zupt-gui 5.2.2'
QT_QPA_PLATFORM=offscreen zupt-gui --version | grep -Fx "zupt-gui $version"
test ! -e /usr/bin/vaptvupt
dnf remove -y zupt-gui zupt
test ! -e /usr/bin/zupt-gui

View file

@ -11,7 +11,7 @@ on:
required: true
type: number
tag:
description: Existing annotated release tag, for example v5.2.2
description: Existing annotated release tag, for example v5.2.3
required: true
type: string

View file

@ -1,12 +1,12 @@
<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
# ZUPT 5.2.2 audit guide and finding history
# ZUPT 5.2.3 audit guide and finding history
This document describes review surfaces and reproducible checks. It is an
upstream self-review, not an independent audit, certification, or guarantee.
`SECURITY.md` defines reporting policy and `THREAT_MODEL.md` defines the
security boundary.
## 5.2.2 scope
## 5.2.3 scope
The baseline scope is the source-only CLI and its bundled source codec:
@ -28,8 +28,9 @@ output.
## Source-only review
Release 5.2.2 removes incomplete SDK/PQBOX header snapshots and build
expectations for a local precompiled library. Git and new upstream source
The 5.2.3 baseline retains the source-only boundary introduced in 5.2.2, which
removed incomplete SDK/PQBOX header snapshots and local precompiled-library
expectations. Git and new upstream source
archives are intended to contain no compiled executable, object, shared/static
library, distribution package, unsafe symlink, or unresolved Git LFS pointer.
@ -41,10 +42,10 @@ scripts/check-source-only.sh
# committed Git tree or immutable tag
scripts/check-source-only.sh --tag HEAD
scripts/check-source-only.sh --tag v5.2.2
scripts/check-source-only.sh --tag v5.2.3
# generated source archive
scripts/check-source-only.sh --archive /path/to/zupt-5.2.2.tar.gz
scripts/check-source-only.sh --archive /path/to/zupt-5.2.3.tar.gz
```
The scanner checks extensions and magic bytes, nested archives, symlink targets,
@ -103,11 +104,13 @@ This table identifies evidence layers rather than results. Missing tools, OBS
access, other architectures, Leap, and SLE must not be reported as passing
without evidence.
## Committed-candidate local Linux evidence
## Prior 5.2.2 committed-candidate local Linux evidence
The following upstream self-audit results apply to commit `ff99770` on the
recorded local Linux environments. They are not an independent certification,
a result for later commits, or evidence that release assets have been published.
The following upstream self-audit results apply only to the 5.2.2 candidate at
commit `ff99770` on the recorded local Linux environments. The immutable 5.2.2
tag was not promoted after post-tag CI integration failures. These results are
not independent certification, a 5.2.3 result, or evidence that release assets
were published.
| Gate | Result | Recorded evidence |
|---|---|---|
@ -120,11 +123,11 @@ a result for later commits, or evidence that release assets have been published.
| Mutation fuzzing | PASS | 1,000 mutation iterations completed without a sanitizer-detected crash. |
An earlier off-screen GUI smoke run remains supporting evidence, but is not
represented as an exact-`ff99770` GUI-package result. Native Windows and macOS
gates, hosted GitHub CI and release promotion, authenticated OBS validation,
and resolution of the openSUSE automatic `debugsource` rpmlint `no-binary`
finding remain pending. The immutable tag and its final artifacts must not be
described as released until those applicable gates complete.
represented as an exact-`ff99770` GUI-package result. The exact 5.2.3 candidate
must repeat the required suite. Native Windows and macOS gates, hosted GitHub CI
and release promotion, authenticated OBS validation, and resolution of the
openSUSE automatic `debugsource` rpmlint `no-binary` finding remain pending
until recorded otherwise.
## Cryptographic review boundary
@ -143,7 +146,7 @@ AES implementation has documented cache-timing risk on hostile shared hardware.
The following entries are retained as release history. Their regression tests
should be rerun, but the historical resolution does not itself constitute a
5.2.2 test result.
5.2.3 test result.
| First corrected | Severity | Finding | Resolution recorded at the time |
|---|---|---|---|
@ -184,12 +187,12 @@ include SHA-256 checksums. The gated GUI set adds the architecture-independent
DEB, noarch/source RPM, and source-only portable GUI ZIP. Package gates include
exact payload/dependency and installed off-screen integration checks; the
portable ZIP additionally receives source scans, an exact safe-member allowlist,
and an extracted launcher test. An AppImage is not promoted by the 5.2.2
and an extracted launcher test. An AppImage is not promoted by the 5.2.3
policy; AppDir and Flatpak bundles, GUI platform installers, and bare
Linux/Windows executables are also excluded. Windows ZIP and macOS DMG outputs
remain CLI-only.
No Wine result is retained as release evidence for 5.2.2. Cross-compilation
No Wine result is retained as release evidence for 5.2.3. Cross-compilation
does not establish native-Windows behavior. Extended-length/device namespace
paths, raw UNC output roots, and mapped/network-drive output are unsupported;
the native Windows workflow remains a publication gate for the ZIP containing

View file

@ -1,5 +1,33 @@
# ZUPT Changelog
## [5.2.3] — 2026-08-31 — Corrective release integration
Corrective successor to the immutable `v5.2.2` candidate. Post-tag CI
integration failures prevented 5.2.2 asset promotion; the tag and its historical
record remain unchanged.
- Carry the 5.2.2 source-only, security, naming, format, and compatibility work
forward without a new archive-format version, codec release, or SDK ABI.
- Realign current source, package, workflow, documentation, artifact, and tag
version references to 5.2.3. Release binaries remain outside Git and source
archives.
- Make `zupt-gui --version` emit the stable machine-readable line
`zupt-gui 5.2.3`, and cover that contract in GUI/package regressions.
- Derive Debian and Fedora GUI integration paths, package metadata checks, and
CLI dependency checks from the authoritative version header instead of a
prior-release literal.
- Repair native RPM container gates: persist the exact checked-out workspace as
a Git safe directory, and remove Tumbleweed's conflicting `busybox-gawk`
before installing the native `gawk`/RPM toolchain.
- Require a new exact-`v5.2.3` source archive and checksum set plus fresh hosted
CI, native Windows/macOS, package, and promotion evidence. Prior local 5.2.2
results do not transfer automatically.
- Keep authenticated OBS/Factory validation pending. The automatic openSUSE
`debugsource` rpmlint `no-binary` finding remains unresolved and unsuppressed.
- Continue to exclude AppImage/AppDir/Flatpak, GUI platform installers, and bare
executables from the promoted set; retain the notice-bearing CLI archives and
source-only portable GUI ZIP policy.
## [5.2.2] — 2026-08-31 — ZUPT identity, source-only upstream tree, and openSUSE packaging

View file

@ -1,4 +1,4 @@
# Distributing ZUPT 5.2.2
# Distributing ZUPT 5.2.3
This document describes the packaging material maintained in the ZUPT
source repository. A recipe in `packaging/` is not evidence that a package has
@ -14,6 +14,10 @@ https://github.com/cristiancmoises/zupt
GitHub is the canonical source and release host. Packaging must never fetch
`zupt-web` or substitute an asset from another project.
The `v5.2.2` tag is immutable but remained a non-promoted candidate after
post-tag CI integration failures. Corrective packages and release assets must
use `v5.2.3`; never move or overwrite the 5.2.2 tag or its checksums.
## Source-only boundary
Git, `git archive`, and the upstream source tarball contain source code,
@ -42,7 +46,7 @@ Audit the current tree or a generated archive with:
```sh
scripts/check-source-only.sh
scripts/check-source-only.sh --archive /path/to/zupt-5.2.2.tar.gz
scripts/check-source-only.sh --archive /path/to/zupt-5.2.3.tar.gz
```
The scanner reports paths, not file contents, and exits nonzero on a violation.
@ -56,8 +60,8 @@ the commit omits Git's commit-ID PAX header:
```sh
SOURCE_DATE_EPOCH="$(git show -s --format=%ct HEAD)" \
make DIST_TARBALL=/tmp/zupt-5.2.2.tar.gz dist
sha256sum /tmp/zupt-5.2.2.tar.gz
make DIST_TARBALL=/tmp/zupt-5.2.3.tar.gz dist
sha256sum /tmp/zupt-5.2.3.tar.gz
```
With identical committed input and `SOURCE_DATE_EPOCH`, repeated exports must
@ -103,12 +107,12 @@ private-library RPATH.
| openSUSE / OBS | `packaging/opensuse/` | source and binary RPM through OBS |
| Debian / Ubuntu | `packaging/debian/`, `packaging/build-deb.sh` | Debian metadata and binary DEB after the target gate |
| RPM release artifact | `packaging/opensuse/zupt.spec`, `packaging/build-rpm.sh` | source and binary RPM after the target gate |
| GUI DEB | `packaging/build-gui-deb.sh` | `zupt-gui_5.2.2_all.deb` after payload/dependency and installed integration gates |
| GUI RPM | `packaging/build-gui-rpm.sh` | `zupt-gui-5.2.2-1.noarch.rpm` and matching `.src.rpm` after package and installed integration gates |
| Linux CLI archive | `.github/workflows/ci.yml` | `zupt-5.2.2-linux-x86_64.tar.xz` with notices after dependency, member, and extracted functional gates |
| Portable GUI source | `packaging/portable/`, `.github/workflows/ci.yml` | `zupt-gui-5.2.2-portable.zip` after source scan, member allowlist, and extracted off-screen integration gate |
| GUI DEB | `packaging/build-gui-deb.sh` | `zupt-gui_5.2.3_all.deb` after payload/dependency and installed integration gates |
| GUI RPM | `packaging/build-gui-rpm.sh` | `zupt-gui-5.2.3-1.noarch.rpm` and matching `.src.rpm` after package and installed integration gates |
| Linux CLI archive | `.github/workflows/ci.yml` | `zupt-5.2.3-linux-x86_64.tar.xz` with notices after dependency, member, and extracted functional gates |
| Portable GUI source | `packaging/portable/`, `.github/workflows/ci.yml` | `zupt-gui-5.2.3-portable.zip` after source scan, member allowlist, and extracted off-screen integration gate |
| Fedora / RPM-based systems | `packaging/rpm/zupt.spec` | downstream RPM starting point |
| AppImage helper | `packaging/build-appimage.sh` | downstream-only helper; no 5.2.2 AppImage is promoted |
| AppImage helper | `packaging/build-appimage.sh` | downstream-only helper; no 5.2.3 AppImage is promoted |
| Windows | `.github/workflows/cross-platform.yml` | native ZIP (executable plus notices) after the required native gate |
| macOS | `packaging/build-dmg.sh` | native-architecture DMG after the native gate |
| Arch Linux | `packaging/aur/PKGBUILD` | AUR package recipe |
@ -184,17 +188,17 @@ expectations, then test the installed launcher off-screen against the matching
### Portable and native release artifacts
The Linux x86_64 gate packages the tested `zupt` executable as
`zupt-5.2.2-linux-x86_64.tar.xz` beside README, changelog, security guidance,
`zupt-5.2.3-linux-x86_64.tar.xz` beside README, changelog, security guidance,
and every applicable public license and notice. Its dynamic-library allowlist,
archive member allowlist, and extracted CLI functional suite must pass.
The `zupt-gui-5.2.2-portable.zip` artifact is source-only: it contains the GUI
The `zupt-gui-5.2.3-portable.zip` artifact is source-only: it contains the GUI
Python source, shell/macOS/Windows launchers, icons, provenance, changelog, and
licenses, but no Python, Qt, CLI, or compiled runtime. The gate scans both the
assembled and extracted trees, verifies an exact safe member allowlist, and
runs the extracted launcher off-screen against the tested CLI.
AppImage creation is deliberately offline and is not a 5.2.2 release gate.
AppImage creation is deliberately offline and is not a 5.2.3 release gate.
Supply a locally verified `appimagetool`, type-2 runtime, and the complete
license/source-relink compliance notice for those exact runtime bytes; the
helper never downloads any input:
@ -210,7 +214,7 @@ APPIMAGE_RUNTIME_COMPLIANCE_FILE=/verified/path/runtime-compliance.txt \
The runtime inspected while preparing 5.2.2 omitted a linked component from
its notice and did not provide the complete LGPL source/relink handoff required
by this release policy. No AppImage produced by this helper is promoted by the
upstream 5.2.2 workflow. AppDir and Flatpak bundles and GUI platform installers
upstream 5.2.3 workflow. AppDir and Flatpak bundles and GUI platform installers
are also excluded. Bare Linux and Windows executables are not promoted; their
CLI programs appear only inside notice-bearing archives. The Windows ZIP and
macOS DMG remain CLI-only.
@ -225,8 +229,8 @@ DIST_DIR="$release_dir" RUN_CHECKS=1 packaging/build-dmg.sh
The Windows ZIP (including its executable and notices) must be built and tested
by the Windows job in `.github/workflows/cross-platform.yml`; it is not a
cross-compiled release claim from a Linux build. No Wine result is retained as
5.2.2 release evidence. Extended-length/device namespace paths, raw UNC output
roots, and mapped/network-drive output are not supported in 5.2.2. Publish the
5.2.3 release evidence. Extended-length/device namespace paths, raw UNC output
roots, and mapped/network-drive output are not supported in 5.2.3. Publish the
exact architecture recorded by the native job.
These helpers create binary distribution artifacts for the release page, not
content to be committed to Git or included in the source archive.
@ -234,7 +238,7 @@ content to be committed to Git or included in the source archive.
### AUR, Homebrew, Guix, and Nix
After calculating the final reproducible source archive, but before creating or
publishing the immutable tag, update each recipe to version 5.2.2 and to the
publishing the immutable tag, update each recipe to version 5.2.3 and to the
exact digest or content hash expected by its package manager. These recipe
directories are excluded from the source archive, so this does not create a
checksum cycle. Commit the pinned recipes in the tagged tree, then build and
@ -253,7 +257,7 @@ build.
For every published artifact:
1. start from the immutable `v5.2.2` tag;
1. start from the immutable `v5.2.3` tag;
2. keep `WITH_SDK=0 WITH_PQBOX=0` unless system dependencies are declared;
3. record the exact OS, distribution release, architecture, and toolchain;
4. run format validation plus installed `--version`, `--help`, and archive
@ -271,7 +275,7 @@ than redirecting consumers to an unverified file.
## Downstream checklist
- [ ] The source URL resolves to the immutable `v5.2.2` tag.
- [ ] The source URL resolves to the immutable `v5.2.3` tag.
- [ ] The source archive passes `scripts/check-source-only.sh --archive`.
- [ ] The recipe checksum matches the downloaded source exactly.
- [ ] `WITH_SDK=0 WITH_PQBOX=0` is explicit, or system dependencies are complete.

View file

@ -1,4 +1,4 @@
# Installing ZUPT 5.2.2
# Installing ZUPT 5.2.3
This guide covers the ZUPT command-line program and the optional Python GUI.
The canonical source repository is
@ -15,12 +15,15 @@ The canonical source repository is
Git tree or upstream source archive. Use only artifacts whose release notes
record a successful format-specific test for your target.
The promoted 5.2.2 package set, only after each target gate succeeds, is:
The immutable `v5.2.2` candidate was not promoted after CI integration
failures. Do not treat a 5.2.2 candidate artifact as a 5.2.3 package.
The 5.2.3 package set eligible for promotion after each target gate succeeds is:
| Component | Gated artifacts |
|---|---|
| CLI | `zupt-5.2.2.tar.gz`, `zupt_5.2.2_amd64.deb`, openSUSE x86_64 binary/source RPMs, `zupt-5.2.2-linux-x86_64.tar.xz`, `zupt-5.2.2-windows-x86_64.zip`, and `ZUPT-5.2.2-macOS-*.dmg` |
| GUI | `zupt-gui_5.2.2_all.deb`, `zupt-gui-5.2.2-1.noarch.rpm`, `zupt-gui-5.2.2-1.src.rpm`, and `zupt-gui-5.2.2-portable.zip` |
| CLI | `zupt-5.2.3.tar.gz`, `zupt_5.2.3_amd64.deb`, openSUSE x86_64 binary/source RPMs, `zupt-5.2.3-linux-x86_64.tar.xz`, `zupt-5.2.3-windows-x86_64.zip`, and `ZUPT-5.2.3-macOS-*.dmg` |
| GUI | `zupt-gui_5.2.3_all.deb`, `zupt-gui-5.2.3-1.noarch.rpm`, `zupt-gui-5.2.3-1.src.rpm`, and `zupt-gui-5.2.3-portable.zip` |
The GUI packages require the matching `zupt` CLI package and must pass exact
payload/dependency checks plus an installed off-screen GUI/CLI integration
@ -28,7 +31,7 @@ test. The source-only portable GUI ZIP bundles launchers, notices, and GUI
source, but not Python, Qt, or the CLI. The Linux tar.xz carries the tested CLI
beside the complete public license/notice payload. AppImage, AppDir, Flatpak
bundles, GUI platform installers, and bare Linux/Windows executables are not
promoted for 5.2.2. The Windows ZIP and macOS DMG contain the CLI only. Exact
promoted for 5.2.3. The Windows ZIP and macOS DMG contain the CLI only. Exact
target boundaries are listed in `README.md`.
The release's `SHA256SUMS` and validation notes, not the mere presence of a
download link, identify an artifact that completed its gate.
@ -65,7 +68,7 @@ sudo pacman -S base-devel gzip
```
Package names can differ by distribution release. These commands are examples,
not a statement that 5.2.2 has been accepted into each distribution repository.
not a statement that 5.2.3 has been accepted into each distribution repository.
## Build and test from source
@ -85,7 +88,7 @@ From a release archive, run the scanner as follows before extraction or from a
trusted checkout after download:
```sh
scripts/check-source-only.sh --archive /path/to/zupt-5.2.2.tar.gz
scripts/check-source-only.sh --archive /path/to/zupt-5.2.3.tar.gz
```
The default build provides the native password, ML-KEM-768 + X25519 hybrid

View file

@ -1,16 +1,31 @@
# ZUPT 5.2.2
# ZUPT 5.2.3
ZUPT is a command-line backup archiver written in C11. It combines the
bundled VaptVupt compression codec with authenticated AES-256-CTR +
HMAC-SHA256 encryption, native ML-KEM-768/X25519 hybrid encryption, archive
integrity checks, multithreaded operation, and a Python/Qt graphical frontend.
Version 5.2.2 restores the original ZUPT product name and the `zupt` command.
Version 5.2.3 is the corrective release for the source, package, workflow, and
release-integration path. The `v5.2.2` tag remains immutable, but its candidate
was not promoted after post-tag CI integration failures; no 5.2.2 binary set is
presented as the current release.
Version 5.2.2 restored the original ZUPT product name and the `zupt` command.
The `.zupt` archive extension, format v1.6, magic bytes, codec identifiers, and
SDK ABI remain unchanged. An optional `vaptvupt` command alias may be provided
for scripts written against versions 3.0.0 through 5.2.1.
## What changed in 5.2.2
## Corrective changes in 5.2.3
The corrective release carries the 5.2.2 security and format work forward
without a new archive format, codec, or SDK ABI. It realigns every current
version-bearing package and release path to 5.2.3, stabilizes the GUI version
contract used by package gates, and repairs native RPM container setup for
Tumbleweed and Fedora. A fresh exact-tag CI, package, native-platform,
source-only, and checksum record is required before any asset is promoted. See
[CHANGELOG.md](CHANGELOG.md) for the release record.
## Security and source baseline introduced in 5.2.2
This patch release makes the upstream and distribution path auditable from
source and tightens archive integrity handling:
@ -98,9 +113,9 @@ users. Those assets must be built from the tagged source, tested on their target
environment, and kept outside Git and the source archive. A format that was not
built and tested is not presented as supported.
## 5.2.2 release artifacts
## 5.2.3 release artifacts
The 5.2.2 release workflow is defined to produce the following files only after
The 5.2.3 release workflow is defined to produce the following files only after
the corresponding target gate succeeds. `SHA256SUMS` records the exact promoted
filenames and digests. The release notes identify the tested commit and the
manually dispatched CI run; that run's job definitions and logs are the runtime
@ -109,23 +124,23 @@ skips. This table is not a substitute for that evidence.
| Format | Intended target and validation boundary |
| --- | --- |
| `zupt-5.2.2.tar.gz` | Reproducible, source-only archive; scanned twice-built input plus SHA-256. |
| `zupt_5.2.2_amd64.deb` | Ubuntu 24.04 amd64 package; install, functional round trip, and uninstall gate. |
| `zupt-5.2.2-*.x86_64.rpm` and `.src.rpm` | openSUSE Tumbleweed x86_64 source/binary RPM gate; package inspection, install, round trip, and uninstall. |
| `zupt-5.2.2-linux-x86_64.tar.xz` | Linux x86_64 CLI plus the complete public license/notice payload; dependency allowlist and extracted-package functional gate. |
| `zupt-gui_5.2.2_all.deb` | Architecture-independent Python/Qt GUI package; exact dependency/payload checks plus installed off-screen GUI/CLI integration gate. |
| `zupt-gui-5.2.2-1.noarch.rpm` | Architecture-independent Python/Qt GUI RPM; package inspection plus installed off-screen GUI/CLI integration gate. |
| `zupt-gui-5.2.2-1.src.rpm` | Source RPM corresponding exactly to the gated noarch GUI RPM. |
| `zupt-gui-5.2.2-portable.zip` | Source-only GUI and launchers with licenses/provenance; source scan, exact member allowlist, and extracted off-screen GUI/CLI gate. |
| `zupt-5.2.2-windows-x86_64.zip` | Native Windows x86_64 executable with notices; extracted-ZIP round-trip gate. |
| `ZUPT-5.2.2-macOS-*.dmg` | Native macOS image; mounted packaged executable round-trip gate, with the actual architecture in the filename. |
| `zupt-5.2.3.tar.gz` | Reproducible, source-only archive; scanned twice-built input plus SHA-256. |
| `zupt_5.2.3_amd64.deb` | Ubuntu 24.04 amd64 package; install, functional round trip, and uninstall gate. |
| `zupt-5.2.3-*.x86_64.rpm` and `.src.rpm` | openSUSE Tumbleweed x86_64 source/binary RPM gate; package inspection, install, round trip, and uninstall. |
| `zupt-5.2.3-linux-x86_64.tar.xz` | Linux x86_64 CLI plus the complete public license/notice payload; dependency allowlist and extracted-package functional gate. |
| `zupt-gui_5.2.3_all.deb` | Architecture-independent Python/Qt GUI package; exact dependency/payload checks plus installed off-screen GUI/CLI integration gate. |
| `zupt-gui-5.2.3-1.noarch.rpm` | Architecture-independent Python/Qt GUI RPM; package inspection plus installed off-screen GUI/CLI integration gate. |
| `zupt-gui-5.2.3-1.src.rpm` | Source RPM corresponding exactly to the gated noarch GUI RPM. |
| `zupt-gui-5.2.3-portable.zip` | Source-only GUI and launchers with licenses/provenance; source scan, exact member allowlist, and extracted off-screen GUI/CLI gate. |
| `zupt-5.2.3-windows-x86_64.zip` | Native Windows x86_64 executable with notices; extracted-ZIP round-trip gate. |
| `ZUPT-5.2.3-macOS-*.dmg` | Native macOS image; mounted packaged executable round-trip gate, with the actual architecture in the filename. |
An asset absent from the release was not promoted through its mandatory gate.
Do not infer support for another distribution release, OS version, CPU
architecture, raw UNC/SMB destination, or package manager from a similarly
named file. Binary assets are release outputs, never source-build inputs.
No AppImage is promised for 5.2.2. The inspected upstream type-2 runtime lacked
No AppImage is promised for 5.2.3. The inspected upstream type-2 runtime lacked
a complete notice/source-relink handoff for every statically linked component,
so redistributing it would not meet this release's provenance gate. AppDir and
Flatpak bundles and GUI platform installers are likewise outside the promoted
@ -155,8 +170,8 @@ bash tests/test_source_only.sh
For a tag or an existing source archive:
~~~sh
bash scripts/check-source-only.sh --tag v5.2.2
bash scripts/check-source-only.sh --archive /path/to/zupt-5.2.2.tar.gz
bash scripts/check-source-only.sh --tag v5.2.3
bash scripts/check-source-only.sh --archive /path/to/zupt-5.2.3.tar.gz
~~~
Unknown `.bin` files fail the scan. A necessary binary data fixture may be
@ -283,7 +298,7 @@ devices are accepted only when their capacity can be determined and is large
enough. The privileged undersized-loop-device regression is reported `SKIP`,
not `PASS`, when the environment cannot create a loop device.
The committed Linux candidate `ff99770` passed the full local
The immutable, non-promoted 5.2.2 candidate at commit `ff99770` passed the local
`make release-check`. Recorded results include packaging
`PASS=49 FAIL=0 SKIP=0`, the 39/39 source-only scanner suite, strict GCC and
Clang, GCC `-fanalyzer`, a 9/9 full tool-enabled static-analysis run,
@ -291,13 +306,15 @@ ASan/UBSan/LSan, and 1,000 mutation-fuzz iterations without a
sanitizer-detected crash. An earlier off-screen GUI smoke run remains supporting
evidence rather than an exact-candidate package result.
These are upstream local self-audit results, not independent certification or a
published-release claim. Native Windows and macOS, hosted GitHub CI/release
promotion, authenticated OBS, and resolution of the openSUSE automatic
`debugsource` rpmlint `no-binary` finding remain pending. Unexecuted gates are
`SKIP`, never `PASS`.
Those results are historical upstream self-audit evidence, not independent
certification and not 5.2.3 results. Post-tag CI integration failures prevented
5.2.2 promotion. The exact 5.2.3 candidate must repeat all required gates;
native Windows and macOS, hosted GitHub CI/release promotion, authenticated OBS,
and resolution of the openSUSE automatic `debugsource` rpmlint `no-binary`
finding remain pending until recorded otherwise. Unexecuted gates are `SKIP`,
never `PASS`.
On Windows, 5.2.2 scopes output handling to normal local Win32 paths. A MinGW
On Windows, 5.2.3 scopes output handling to normal local Win32 paths. A MinGW
cross-build or Wine run is not native-Windows evidence; the `windows-latest`
package job, including its Unicode round trip, remains a mandatory publication
gate. Win32 extended-length and device-namespace paths, raw UNC output roots
@ -319,7 +336,7 @@ downgrading authentication of header and footer metadata.
`disk restore`, and exists only to recover a known, trusted archive created
before AIT was introduced. Do not use that override for an archive from
untrusted or attacker-writable storage; verify and migrate the recovered data to
a newly created 5.2.2 archive. Compression and disk backup never create a
a newly created 5.2.3 archive. Compression and disk backup never create a
no-AIT archive.
`info` is deliberately different: it reports unauthenticated framing metadata,
@ -337,7 +354,7 @@ lists, tests, extracts, and restores it byte-exact. The full local Linux gate
passed on commit `ff99770`. This is not a claim that a 5.2.1 reader understands every new
flag-gated 5.2.2 encoding or that every historical combination was tested.
The candidate commands and outcome fields for 5.2.2 are maintained in the
The candidate commands and outcome fields for 5.2.3 are maintained in the
release handoff and
[packaging/opensuse/README.md](packaging/opensuse/README.md). They must be
updated from the final release candidate before tagging. No architecture or
@ -349,9 +366,9 @@ Generate the reproducible source archive outside the repository:
~~~sh
make dist
sha256sum /tmp/zupt-5.2.2.tar.gz
sha256sum /tmp/zupt-5.2.3.tar.gz
bash scripts/check-source-only.sh \
--archive /tmp/zupt-5.2.2.tar.gz
--archive /tmp/zupt-5.2.3.tar.gz
~~~
Archive ordering, ownership and timestamps are normalized. The default epoch is
@ -367,7 +384,7 @@ final digest before the tag is published.
## openSUSE and OBS
The maintained upstream recipe is in packaging/opensuse. It is prepared for an
immutable v5.2.2 tag, disables submodules and Git LFS, builds with
immutable v5.2.3 tag, disables submodules and Git LFS, builds with
WITH_SDK=0 WITH_PQBOX=0, runs real checks, and installs without the renamed-era
`vaptvupt` alias.
@ -410,22 +427,22 @@ The optional GUI is under `gui/`. It invokes the `zupt` CLI and needs Python 3
plus PySide6 or PyQt6. GUI image assets are data files whose purpose,
provenance and license are recorded in [gui/assets/README.md](gui/assets/README.md).
The integrated source and lightweight consistency checks do not constitute a
target-native audit of every historical GUI format. The 5.2.2 artifact promise
target-native audit of every historical GUI format. The 5.2.3 artifact promise
is limited to the gated GUI DEB, noarch/source RPM, and source-only portable ZIP
listed above; AppImage, AppDir, Flatpak bundles, and platform GUI installers
remain excluded.
## Maintainers and openSUSE credit
Cristian Cezar Moisés is the creator and current upstream maintainer of
ZUPT and the author of the upstream 5.2.2 source, build, test,
documentation, and packaging changes.
Cristian Cezar Moisés is the creator and current upstream maintainer of ZUPT and
the author of the current upstream source, build, test, documentation, and
packaging changes, including the 5.2.2 baseline and corrective 5.2.3 work.
Alessandro de Oliveira Faria (Cabelo) is credited as the openSUSE collaborator
and downstream package maintainer. He reviews the handoff, commits it in the
OBS project he maintains, and may make the additional openSUSE-side adjustments
he considers necessary. That downstream role is not attribution of ZUPT
source authorship or of the upstream 5.2.2 changes.
he considers necessary. That downstream role is not attribution of ZUPT source
authorship or of the upstream 5.2.2 or 5.2.3 changes.
## License

View file

@ -1,4 +1,4 @@
# Security Policy — ZUPT 5.2.2
# Security Policy — ZUPT 5.2.3
## Reporting vulnerabilities
@ -66,7 +66,7 @@ partially accepted.
### Optional integrations
The 5.2.2 default is `WITH_SDK=0 WITH_PQBOX=0`:
The 5.2.3 default is `WITH_SDK=0 WITH_PQBOX=0`:
- `WITH_SDK=1` enables libvuptsdk-backed features, including the SDK PQ mode
and Argon2id support, using a separately installed system development package.
@ -133,7 +133,7 @@ can compromise archives encrypted to it.
## Constant-time and side-channel scope
Portable C is the 5.2.2 default. Sensitive comparisons and selections use
Portable C is the 5.2.3 default. Sensitive comparisons and selections use
branchless helpers, but generated machine-code behavior remains dependent on
the compiler and platform. This is not a formal whole-program constant-time
claim. The C AES implementation uses table lookups and is unsuitable for a
@ -197,7 +197,7 @@ media before proceeding.
The Windows handle-relative implementation is scoped to normal local Win32
paths. Win32 extended-length and device-namespace paths, raw UNC output roots,
and mapped/network-drive output are not supported in 5.2.2. Cross-build and
and mapped/network-drive output are not supported in 5.2.3. Cross-build and
Wine results are not native-Windows evidence; the `windows-latest` package gate
must pass its Unicode round trip before Windows assets are published. Restore
to a normal local directory first and move verified output to network storage
@ -220,7 +220,7 @@ gate was rerun on every platform:
`--allow-legacy-no-ait` on a supported read command. This option permits
recovery of trusted old media; it is not a general compatibility mode and
does not make unauthenticated header/footer metadata safe.
- The 5.2.2 reader accepts the fixed-width disk index and encrypted-dedup linear
- Readers since 5.2.2 accept the fixed-width disk index and encrypted-dedup linear
AAD sequence published through 5.2.1 and warns that the legacy index has no
whole-image content hash. Its regression fixture is an actual v5.2.1
password-encrypted DATA/DATA/REF/DATA disk archive stored as hexadecimal text with
@ -240,7 +240,7 @@ shared/static library, or distribution package. Audit them with:
```sh
scripts/check-source-only.sh
scripts/check-source-only.sh --archive /path/to/zupt-5.2.2.tar.gz
scripts/check-source-only.sh --archive /path/to/zupt-5.2.3.tar.gz
```
Nested archive inspection is required to enforce bounded recursion, member
@ -250,13 +250,13 @@ limit violations. On commit `ff99770`, the source-only scanner suite passed
DEB, binary RPM, SRPM, notice-bearing Linux tar.xz, source-only portable GUI
ZIP, Windows ZIP, and macOS DMG release assets are separate outputs. An
AppImage is not promoted for 5.2.2. A bare Linux or Windows executable is also
AppImage is not promoted for 5.2.3. A bare Linux or Windows executable is also
excluded; executables are distributed only inside their notice-bearing
archives. Trust an artifact only when its exact format has a recorded build,
content/metadata inspection, extracted or installed smoke test, and applicable
archive round trip. Never treat an unexecuted platform as passing.
The gated 5.2.2 set is the CLI package/archive set plus the exact GUI DEB,
The gated 5.2.3 set is the CLI package/archive set plus the exact GUI DEB,
noarch/source RPM, and source-only portable ZIP documented in the README. The
portable GUI ZIP contains no compiled runtime and is scanned as source before
and after extraction. Other GUI packages, AppImage, AppDir and Flatpak bundles,
@ -285,18 +285,22 @@ make test-asan-run
The first command builds the sanitizer configuration; the second executes its
test suite. Neither substitutes for the normal optimized build and tests.
The full local Linux `make release-check` passed on committed candidate
`ff99770`. Its recorded evidence includes packaging `PASS=49 FAIL=0 SKIP=0`,
The full local Linux `make release-check` passed on the immutable, non-promoted
5.2.2 candidate at `ff99770`. Its recorded evidence includes packaging
`PASS=49 FAIL=0 SKIP=0`,
the 39/39 source-only scanner suite, strict GCC and Clang builds, GCC
`-fanalyzer`, 9/9 static analysis in a tool-enabled run, ASan/UBSan/LSan, and
1,000 mutation-fuzz iterations without a sanitizer-detected crash. An earlier
off-screen GUI smoke run is supporting evidence, not an exact-candidate package
result.
These are upstream self-audit results, not independent certification. Native
Windows and macOS, hosted GitHub CI/release promotion, authenticated OBS, and
the openSUSE automatic `debugsource` rpmlint `no-binary` finding remain pending.
An unavailable or unexecuted environment remains `SKIP`, never `PASS`.
Post-tag CI integration failures prevented 5.2.2 promotion. Those upstream
self-audit results are not independent certification and do not transfer to
5.2.3. The exact 5.2.3 candidate must repeat the required suite. Native Windows
and macOS, hosted GitHub CI/release promotion, authenticated OBS, and the
openSUSE automatic `debugsource` rpmlint `no-binary` finding remain pending
until recorded otherwise. An unavailable or unexecuted environment remains
`SKIP`, never `PASS`.
Run target-native static analyzers and package checks as additional evidence.
Do not infer x86_64, aarch64, ppc64le, s390x, riscv64, macOS, Windows, Leap, or

View file

@ -159,8 +159,8 @@ grant attached to their unchanged Git blobs, are recorded in
## AppImage type-2 runtime
No AppImage is a promised or promoted 5.2.2 release asset. The upstream
type-2 runtime inspected for this release statically linked musl, libfuse,
No AppImage is a promised or promoted 5.2.3 release asset. The upstream
type-2 runtime inspected during the 5.2.2 review statically linked musl, libfuse,
squashfuse, zstd, zlib, and mimalloc, but its own license notice did not list
mimalloc and the available release inputs did not provide a complete
LGPL-compatible source/relink handoff. ZUPT therefore does not
@ -171,7 +171,7 @@ no network input and requires the operator to supply both a locally verified
runtime and `APPIMAGE_RUNTIME_COMPLIANCE_FILE`, containing the license notices,
source correspondence or offer, and relink information applicable to those
exact runtime bytes. An artifact produced independently with that helper is
not covered by the 5.2.2 upstream release gates.
not covered by the 5.2.3 upstream release gates.
## Reporting attribution issues

View file

@ -1,4 +1,4 @@
# ZUPT 5.2.2 threat model
# ZUPT 5.2.3 threat model
This document defines the security boundary of the ZUPT archive tool. It is
not a certification, a guarantee against every hostile input, or a substitute
@ -17,7 +17,7 @@ plausibly deniable.
## Baseline considered here
The upstream baseline is built from the 5.2.2 source with:
The upstream baseline is built from the 5.2.3 source with:
```sh
make WITH_SDK=0 WITH_PQBOX=0
@ -175,7 +175,7 @@ temporary through its descriptor or handle. These controls reduce traversal,
link, race, and partial-output risks, but do not establish that no parser or
filesystem bug can exist.
The Windows handle-relative boundary in 5.2.2 covers normal local Win32 paths.
The Windows handle-relative boundary in 5.2.3 covers normal local Win32 paths.
Win32 extended-length and device-namespace paths, raw UNC output roots, and
mapped/network-drive output are not supported. Cross-build and Wine results are
not a substitute for the required native `windows-latest` Unicode package
@ -250,23 +250,25 @@ tagged source. Each artifact extends the trust boundary to its builder,
toolchain, runner image, and packaging scripts. Treat it as validated only when
the exact target has a recorded build, content/package inspection, extracted or
installed smoke test, and applicable archive round trip. An AppImage is not
promoted for 5.2.2; bare Linux and Windows executables are also excluded.
promoted for 5.2.3; bare Linux and Windows executables are also excluded.
For 5.2.2, that gated artifact scope covers the CLI files plus the exact GUI
For 5.2.3, that gated artifact scope covers the CLI files plus the exact GUI
DEB, noarch/source RPM, and source-only portable ZIP named in the README. The
portable ZIP contains no compiled runtime and crosses the release boundary only
after source scans and an exact safe-member check. AppDir and Flatpak bundles
and GUI platform installers remain excluded; Windows ZIP and macOS DMG outputs
remain CLI-only.
The committed Linux candidate `ff99770` passed the full local
The immutable, non-promoted 5.2.2 candidate at `ff99770` passed the full local
`make release-check`: packaging reported `PASS=49 FAIL=0 SKIP=0`; strict GCC,
strict Clang, GCC `-fanalyzer`, the 9/9 tool-enabled static-analysis run,
ASan/UBSan/LSan, and 1,000 mutation-fuzz iterations passed. Earlier off-screen
GUI smoke evidence is retained separately. This upstream self-review is not an
independent certification, and native Windows/macOS, hosted GitHub CI and
release promotion, authenticated OBS, and the openSUSE automatic `debugsource`
rpmlint `no-binary` finding remain pending.
GUI smoke evidence is retained separately. Post-tag CI integration failures
prevented 5.2.2 promotion. This upstream self-review is not an independent
certification and is not 5.2.3 evidence. Native Windows/macOS, hosted GitHub CI
and release promotion, authenticated OBS, and the openSUSE automatic
`debugsource` rpmlint `no-binary` finding remain pending until recorded
otherwise.
## Historical compatibility notes
@ -293,7 +295,7 @@ These are historical facts about earlier releases, retained to support recovery:
combinations remain unclaimed.
Historical test counts in the changelog describe those releases. They do not
automatically become 5.2.2 results; current outcomes belong in the release
automatically become 5.2.3 results; current outcomes belong in the release
validation record, with unavailable environments marked `SKIP`. In particular,
runs made before the final positional-AAD and mandatory-AIT changes are not
final release gates for the resulting candidate.
@ -304,4 +306,4 @@ Email **zupt@riseup.net** with `[security]` in the subject. Include the version,
platform, impact, and a minimal non-sensitive reproducer. Do not disclose the
issue publicly until a coordinated timeline has been agreed.
Document version: 5.2.2, 2026-08-31.
Document version: 5.2.3, 2026-08-31.

View file

@ -1,6 +1,6 @@
.\" SPDX-License-Identifier: AGPL-3.0-or-later
.\" Copyright (c) 2025-2026 Cristian Cezar Moisés
.TH ZUPT-GUI 1 "2026-08-31" "ZUPT 5.2.2" "User Commands"
.TH ZUPT-GUI 1 "2026-08-31" "ZUPT 5.2.3" "User Commands"
.SH NAME
zupt-gui \- Qt interface for the ZUPT backup utility
.SH SYNOPSIS
@ -47,7 +47,7 @@ or
only when libvuptsdk or libpqvaptvupt is independently reported enabled.
These two optional integrations are detected separately.
.PP
The gated 5.2.2 GUI release set is limited to the architecture-independent DEB,
The gated 5.2.3 GUI release set is limited to the architecture-independent DEB,
noarch/source RPM, and source-only portable ZIP named in the project README.
Package gates require exact checks and installed off-screen GUI/CLI integration.
The portable ZIP receives source scans, an exact safe-member allowlist, and an
@ -142,6 +142,7 @@ option. The optional alias has no separate manual page.
.SH BUGS
Report reproducible issues at
.UR https://github.com/cristiancmoises/zupt/issues
the ZUPT issue tracker
.UE .
.SH AUTHOR
Cristian Cezar Moisés

View file

@ -1,6 +1,6 @@
.\" SPDX-License-Identifier: AGPL-3.0-or-later
.\" Copyright (c) 2025-2026 Cristian Cezar Moisés
.TH ZUPT 1 "2026-08-31" "ZUPT 5.2.2" "User Commands"
.TH ZUPT 1 "2026-08-31" "ZUPT 5.2.3" "User Commands"
.
.SH NAME
zupt \- source-built backup compression and authenticated-encryption utility
@ -72,9 +72,9 @@ for the exact boundary and historical-format limitations.
.
.PP
The bundled compression codec is VaptVupt codec 2.65.3.
Automatic codec selection uses VaptVupt where the supported AVX2 or NEON path is available and
uses the portable LZHP codec otherwise. Use a codec-selection option only when
a specific choice is required.
Automatic codec selection uses VaptVupt where the supported AVX2 or NEON path
is available and uses the portable LZHP codec otherwise. Use a codec-selection
option only when a specific choice is required.
.
.PP
The renamed-era
@ -89,7 +89,7 @@ Git and the upstream source tarball are source-only. Separately built CLI DEB,
binary RPM, SRPM, notice-bearing Linux tar.xz, Windows ZIP, and macOS DMG assets
may be published from the immutable tag only after their target-specific gates
pass; they never enter Git or the source tarball. An AppImage is not promoted
for 5.2.2; neither are AppDir/Flatpak bundles, GUI platform installers, or bare
for 5.2.3; neither are AppDir/Flatpak bundles, GUI platform installers, or bare
Linux/Windows executables. The Python/Qt frontend remains available as source;
its gated architecture-independent DEB, noarch/source RPM, and source-only
portable ZIP are included in the release claim. The portable ZIP contains no
@ -477,7 +477,7 @@ then traverse below a pinned directory descriptor with no-follow operations.
Windows builds use handle-relative traversal and
no-replace publication for normal local Win32 destinations. Extended-length and
device-namespace paths, raw UNC output roots, and mapped/network-drive output
are not supported in 5.2.2. Cross-compilation and Wine results are not native
are not supported in 5.2.3. Cross-compilation and Wine results are not native
Windows evidence; the native Windows package gate, including its Unicode round
trip, is separate and mandatory before publication.
.
@ -572,12 +572,13 @@ Inspect and verify an archive without extraction:
.SH COMPATIBILITY
The on-disk version byte remains v1.6, with flag-gated 5.2.2 encodings for
positional authenticated dedup references and disk-image integrity metadata.
The 5.2.2 reader retains compatibility parsers for the fixed-width disk index
Readers since 5.2.2 retain compatibility parsers for the fixed-width disk index
and the encrypted-dedup linear AAD sequence published through 5.2.1. The narrow
compatibility fixture is an actual v5.2.1 password-encrypted DATA/DATA/REF/DATA disk
archive stored as hexadecimal text with source and hash provenance. The
candidate lists, tests, extracts, and restores that fixture byte-exact, and the exact
final candidate must repeat the gate. It does not imply that a 5.2.1 reader
compatibility fixture is an actual v5.2.1 password-encrypted
DATA/DATA/REF/DATA disk archive stored as hexadecimal text with source and hash
provenance. The candidate lists, tests, extracts, and restores that fixture
byte-exact. The exact 5.2.3 candidate must repeat the gate. It does not imply
that a 5.2.1 reader
accepts every new 5.2.2 archive or that every historical encrypted mode was
retested.
.
@ -617,13 +618,14 @@ with those notices; the current license summary does not revoke them. See the
for repository evidence.
.
.SH AUTHORS
Cristian Cezar Moisés is the primary upstream author and maintainer. Packaging
credits belong in their applicable packaging history and do not imply authorship
of the upstream program.
Cristian Cezar Moisés is the primary upstream author and maintainer.
Packaging credits belong in their applicable packaging history and do not
imply authorship of the upstream program.
.
.SH REPORTING BUGS
Project issues:
.UR https://github.com/cristiancmoises/zupt/issues
ZUPT issue tracker
.UE
.
.PP

View file

@ -1,6 +1,6 @@
# ZUPT GUI
The ZUPT GUI is a Python/Qt front end for the ZUPT 5.2.2 command-line
The ZUPT GUI is a Python/Qt front end for the ZUPT 5.2.3 command-line
program. It starts the CLI as a subprocess; compression, archive parsing, and
cryptography remain in the C program.
@ -83,10 +83,10 @@ operating systems and must be tested on the target system.
Release pages provide only these GUI artifacts after their separate package and
installed off-screen GUI/CLI integration gates pass:
- `zupt-gui_5.2.2_all.deb`;
- `zupt-gui-5.2.2-1.noarch.rpm`;
- `zupt-gui-5.2.2-1.src.rpm`;
- `zupt-gui-5.2.2-portable.zip`.
- `zupt-gui_5.2.3_all.deb`;
- `zupt-gui-5.2.3-1.noarch.rpm`;
- `zupt-gui-5.2.3-1.src.rpm`;
- `zupt-gui-5.2.3-portable.zip`.
The DEB/RPM packages install the Python/Qt source and depend on the matching
`zupt` CLI package. The portable ZIP contains source, launchers, icons, licenses,
@ -97,7 +97,7 @@ An absent artifact did not pass its gate and must not be inferred from another
format's result.
GUI AppImage, AppDir and Flatpak bundles, and Windows/macOS GUI installers are
not promoted by the upstream 5.2.2 release gates.
not promoted by the upstream 5.2.3 release gates.
`packaging/build-gui-appimage.sh` is a downstream-only helper and fails unless
its operator supplies the exact verified runtime plus a complete
license/source-relink notice through `APPIMAGE_RUNTIME_COMPLIANCE_FILE`; that
@ -110,7 +110,7 @@ notices. It fails unless the directory also has non-empty
`PYTHON-NOTICE.txt`, `PYINSTALLER-NOTICE.txt`, `QT-NOTICE.txt`, and either
`PYSIDE6-NOTICE.txt` or `PYQT6-NOTICE.txt`. The installer includes that
directory together with every ZUPT license and notice. This requirement does
not make the untested GUI installer a 5.2.2 release asset. The promoted Windows
not make the untested GUI installer a 5.2.3 release asset. The promoted Windows
ZIP and macOS DMG are CLI-only.
Packaging recipes and scripts under `gui/packaging/` and `packaging/` are build

View file

@ -1,9 +1,9 @@
Package: zupt-gui
Version: 5.2.2
Version: 5.2.3
Section: utils
Priority: optional
Architecture: all
Depends: python3 (>= 3.9), python3-pyqt6 | python3-pyside6.qtwidgets, zupt (= 5.2.2)
Depends: python3 (>= 3.9), python3-pyqt6 | python3-pyside6.qtwidgets, zupt (= 5.2.3)
Maintainer: Cristian Cezar Moisés <sac@securityops.co>
Homepage: https://github.com/cristiancmoises/zupt
Description: Qt graphical interface for the ZUPT backup utility

View file

@ -13,7 +13,7 @@ rem runtime files embedded by this local build.
setlocal EnableExtensions
for %%I in ("%~dp0\..\..\..") do set "REPO_ROOT=%%~fI"
set "VERSION=%~1"
if not defined VERSION set "VERSION=5.2.2"
if not defined VERSION set "VERSION=5.2.3"
if not defined ZUPT_DIST_DIR set "ZUPT_DIST_DIR=%TEMP%\zupt-release"
if not defined ZUPT_CLI_EXE set "ZUPT_CLI_EXE=%REPO_ROOT%\zupt.exe"
set "WORK=%TEMP%\zupt-gui-build-%RANDOM%-%RANDOM%"

View file

@ -1097,7 +1097,7 @@ def main():
# loop once, then exits 0 — the reliable way to confirm the GUI stack launches
# on a machine where the window itself is hard to see (tiling WM, remote, CI).
if args and args[0] in ("--version", "-V", "version"):
print(f"zupt-gui {ZUPT_VER_NUMBER} ({QT_BINDING}) | CLI: {ZUPT_CLI}")
print(f"zupt-gui {ZUPT_VER_NUMBER}")
return 0
if args and args[0] in ("--help", "-h", "help"):
print("usage: zupt-gui [ARCHIVE.zupt | --extract ARCHIVE.zupt |\n"

View file

@ -117,7 +117,8 @@ static inline int zupt_win_mkdir_utf8(const char *path) {
#define ZUPT_PRODUCT_EXTENSION ".zupt" /* on-disk archive extension (kept stable) */
#define ZUPT_PRODUCT_TAGLINE "Post-quantum backup compression"
#define ZUPT_VERSION_STRING "5.2.2"
/* v5.2.3 corrects release packaging and CI; archive format remains v1.6. */
#define ZUPT_VERSION_STRING "5.2.3"
/* Vendored codec release (upstream tag) — single source for display strings.
* The codec's own VV_VERSION_* is its internal API version, not the release. */
#define ZUPT_CODEC_RELEASE "2.65.3"

View file

@ -6,7 +6,7 @@
set -Eeuo pipefail
umask 077
VERSION=${VERSION:-5.2.2}
VERSION=${VERSION:-5.2.3}
PREFIX=${PREFIX:-/usr/local}
echo "🔧 Installing ZUPT..."

View file

@ -11,7 +11,7 @@
# Test locally with `makepkg -s` after the release archive is published.
pkgname=zupt
pkgver=5.2.2
pkgver=5.2.3
pkgrel=1
pkgdesc='Pure-C11 post-quantum backup compression utility (AES-256-CTR + HMAC-SHA256 + ML-KEM-768 + X25519)'
arch=('x86_64')
@ -22,8 +22,8 @@ makedepends=('gcc' 'git' 'make')
checkdepends=('python')
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/cristiancmoises/zupt/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz")
# Updated from the byte-reproducible upstream release archive before publishing.
sha256sums=('ee28e7be2b8725189b88ea13e0951c535d3516b44b47d05d5f1fce245d64c553')
# Replace only after generating the byte-reproducible final release archive.
sha256sums=('REPLACE_AFTER_FINAL_ARCHIVE_SHA256')
build() {
cd "${pkgname}-${pkgver}"

View file

@ -1,3 +1,11 @@
zupt (5.2.3-1) UNRELEASED; urgency=medium
* Derive package checks from the upstream version header and stabilize the
GUI version output consumed by package gates.
* Replace busybox-gawk before installing the native openSUSE RPM toolchain.
-- Cristian Cezar Moisés <sac@securityops.co> Mon, 31 Aug 2026 18:15:00 +0000
zupt (5.2.2-1) UNRELEASED; urgency=medium
* Prepare a source-only upstream release and remove incomplete vendored SDK

View file

@ -62,7 +62,7 @@
xcb-util-renderutil xcb-util-wm xcb-util-cursor
libinput-minimal mtdev libevdev eudev))
(define %zupt-version "5.2.2")
(define %zupt-version "5.2.3")
(define %zupt-source
(origin
@ -72,7 +72,7 @@
"/releases/download/v" %zupt-version
"/zupt-" %zupt-version ".tar.gz"))
(sha256
(base32 "0ly5cifj9khzbxfx0isbnhb3apak3jay04zai2dih9c75fzffa7f"))))
(base32 "REPLACE_AFTER_FINAL_ARCHIVE_GUIX_BASE32"))))
(define-public zupt
(package

View file

@ -22,9 +22,9 @@
class Zupt < Formula
desc "Post-quantum backup compression utility (ML-KEM-768 + AES-256-CTR + HMAC-SHA256)"
homepage "https://github.com/cristiancmoises/zupt"
url "https://github.com/cristiancmoises/zupt/releases/download/v5.2.2/zupt-5.2.2.tar.gz"
version "5.2.2"
sha256 "ee28e7be2b8725189b88ea13e0951c535d3516b44b47d05d5f1fce245d64c553"
url "https://github.com/cristiancmoises/zupt/releases/download/v5.2.3/zupt-5.2.3.tar.gz"
version "5.2.3"
sha256 "REPLACE_AFTER_FINAL_ARCHIVE_SHA256"
license all_of: ["AGPL-3.0-or-later", "GPL-3.0-or-later", "BSD-2-Clause", "BSD-3-Clause", "CC0-1.0"]
depends_on "python@3.12" => :test # only for test-suite tamper harness

View file

@ -9,7 +9,7 @@
# nix flake check # lint the flake
#
# To consume from another flake:
# inputs.zupt.url = "github:cristiancmoises/zupt/v5.2.2";
# inputs.zupt.url = "github:cristiancmoises/zupt/v5.2.3";
# ...packages.x86_64-linux.default = inputs.zupt.packages.x86_64-linux.zupt;
#
# `make dist` has its own reproducibility gate. This development flake has no
@ -30,7 +30,7 @@
zupt = pkgs.stdenv.mkDerivation {
pname = "zupt";
version = "5.2.2";
version = "5.2.3";
# When publishing, replace this with `fetchurl` against the
# release tarball. For local development the flake assumes it

View file

@ -1,22 +1,22 @@
# ZUPT 5.2.2 for openSUSE Build Service
# ZUPT 5.2.3 for openSUSE Build Service
This directory is the upstream, source-only OBS recipe for ZUPT. It is a
handoff for the downstream maintainer; its presence does not mean that the
package has been submitted to or accepted by openSUSE Factory.
Cristian Cezar Moisés, ZUPT's creator and current upstream maintainer,
prepared the 5.2.2 source, build, test, documentation, and upstream packaging
prepared the current source, build, test, documentation, and upstream packaging
changes in this handoff. Alessandro de Oliveira Faria (Cabelo) is credited only
as the openSUSE collaborator and downstream OBS package maintainer: he reviews
the handoff, commits it through the portal/project he maintains, and may make
the openSUSE-side adjustments he considers necessary. This role does not
attribute upstream code or the 5.2.2 upstream changes to Cabelo.
attribute upstream code or the 5.2.2/5.2.3 upstream changes to Cabelo.
## Files and source policy
| File | Purpose |
|---|---|
| `_service` | Fetch the immutable `v5.2.2` tag and create `Source0` at build time. |
| `_service` | Fetch the immutable `v5.2.3` tag and create `Source0` at build time. |
| `zupt.spec` | Build and test the CLI with optional external system integrations disabled. |
| `zupt.changes` | openSUSE-format package history. |
| `source-audit.sh` | Handoff wrapper for the repository scanner; run it from the complete handoff tree. |
@ -29,11 +29,11 @@ https://github.com/cristiancmoises/zupt.git
```
`obs_scm` stores an `.obscpio` plus `.obsinfo`. The `tar` and `recompress`
services reconstruct `zupt-5.2.2.tar.gz` inside the build environment, which
services reconstruct `zupt-5.2.3.tar.gz` inside the build environment, which
matches `Source0` in the spec.
This source policy does not prohibit separately built release-page packages.
The upstream 5.2.2 gates may publish the CLI source tarball, DEB, binary RPM,
The upstream 5.2.3 gates may publish the CLI source tarball, DEB, binary RPM,
SRPM, notice-bearing Linux tar.xz, Windows ZIP, and macOS DMG, together with a
GUI DEB, noarch RPM, GUI SRPM, and source-only portable GUI ZIP after each
format-specific test succeeds. None of those files is an OBS `Source0` input
@ -138,7 +138,7 @@ reconstructed by the build-time services. Neither `%build` nor `%check` may
access the network.
For a source RPM check outside OBS, place the service-produced
`zupt-5.2.2.tar.gz` next to the spec and use a disposable RPM build tree:
`zupt-5.2.3.tar.gz` next to the spec and use a disposable RPM build tree:
```sh
rpm_top=$(mktemp -d)
@ -153,9 +153,10 @@ install it in a disposable openSUSE environment and execute
`scripts/test-installed-zupt.sh`. Do not claim a repository or architecture
as supported until its build and installed smoke test have actually passed.
## Committed-candidate local Linux validation
## Prior 5.2.2 committed-candidate local Linux validation
Commit `ff99770` passed the full local `make release-check`. Packaging policy
The immutable 5.2.2 candidate at `ff99770` passed the full local
`make release-check`. Packaging policy
and syntax reported `PASS=49 FAIL=0 SKIP=0`; source-only scanner testing passed
39/39, including GNU thin archives and safe diagnostic cases; strict GCC,
strict Clang, GCC `-fanalyzer`, the 9/9 full tool-enabled static-analysis run,
@ -164,10 +165,12 @@ environment completed six available static checks and reported `cppcheck`
unavailable rather than passing it. Earlier off-screen GUI smoke evidence is
supporting evidence, not an exact-commit package result.
These local upstream results do not establish native Windows or macOS success,
hosted GitHub CI/release promotion, authenticated OBS acceptance, or resolution
of the automatic openSUSE `debugsource` rpmlint `no-binary` finding. Those gates
remain pending.
Post-tag CI integration failures prevented 5.2.2 promotion. These historical
local results do not establish 5.2.3, native Windows or macOS success, hosted
GitHub CI/release promotion, authenticated OBS acceptance, or resolution of the
automatic openSUSE `debugsource` rpmlint `no-binary` finding. The exact 5.2.3
candidate must repeat every applicable gate; those gates remain pending until
recorded otherwise.
## Prior openSUSE packaging validation
@ -205,10 +208,12 @@ gate.
## Handoff procedure for Alessandro/Cabelo
1. Upstream creates and verifies the annotated `v5.2.2` tag only after all
mandatory gates pass.
1. Upstream completes every applicable pre-tag source and local audit gate,
then creates and verifies the annotated `v5.2.3` tag. Exact-tag hosted,
native-platform, package, and promotion gates must pass before release or
downstream handoff; the tag itself is never moved to repair a failure.
2. With Git, `file`, bsdtar, tar, zip, unzip and SHA-256 tools installed, run
`scripts/export-opensuse-package.sh v5.2.2`. Verify the reported ZIP and
`scripts/export-opensuse-package.sh v5.2.3`. Verify the reported ZIP and
SHA-256 outside the Git index. The handoff includes both
`packaging/opensuse/source-audit.sh` and its required
`scripts/check-source-only.sh`; keep that relative layout while auditing.
@ -220,7 +225,7 @@ gate.
```
4. From the extracted handoff root, run
`packaging/opensuse/source-audit.sh --archive /path/to/zupt-5.2.2.tar.gz`.
`packaging/opensuse/source-audit.sh --archive /path/to/zupt-5.2.3.tar.gz`.
Then copy `_service`, `zupt.spec`, `zupt.changes` and `README.md`
into the flat OBS package checkout. The audit wrapper is not an OBS build
source and must not be copied without its companion `scripts/` directory.

View file

@ -4,7 +4,7 @@
<service name="obs_scm" mode="manual">
<param name="url">https://github.com/cristiancmoises/zupt.git</param>
<param name="scm">git</param>
<param name="revision">refs/tags/v5.2.2</param>
<param name="revision">refs/tags/v5.2.3</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="versionrewrite-pattern">^v(.*)$</param>
<param name="versionrewrite-replacement">\1</param>

View file

@ -1,3 +1,12 @@
-------------------------------------------------------------------
Mon Aug 31 18:15:00 UTC 2026 - Cristian Cezar Moisés <sac@securityops.co>
- Update to 5.2.3:
* Derive package checks from the upstream version header and stabilize the
GUI version output consumed by package gates.
* Replace busybox-gawk before installing the native Tumbleweed RPM tooling.
* Pin the OBS source service to the immutable v5.2.3 tag.
-------------------------------------------------------------------
Mon Aug 31 00:00:00 UTC 2026 - Cristian Cezar Moisés <sac@securityops.co>

View file

@ -18,7 +18,7 @@
#
Name: zupt
Version: 5.2.2
Version: 5.2.3
Release: 0
Summary: Backup compression with authenticated and post-quantum encryption
License: AGPL-3.0-or-later AND GPL-3.0-or-later AND BSD-2-Clause AND BSD-3-Clause AND CC0-1.0

View file

@ -27,7 +27,7 @@ Requirements
------------
1. Python 3.9 or newer.
2. PySide6 6.5 or newer, or a compatible PyQt6 package.
3. ZUPT 5.2.2, installed as `zupt` on PATH or placed beside the launcher
3. ZUPT 5.2.3, installed as `zupt` on PATH or placed beside the launcher
(`zupt.exe` on Windows). A local command must have been built
and tested independently; this bundle never downloads one.
@ -46,7 +46,7 @@ Troubleshooting
---------------
* "requires PySide6 or PyQt6": install one Qt binding through your operating
system package manager or another trusted, preconfigured Python source.
* "zupt not found": install ZUPT 5.2.2 or place its command beside
* "zupt not found": install ZUPT 5.2.3 or place its command beside
the launcher.
* Set ZUPT_DEBUG=1 to print command-discovery diagnostics to stderr.

View file

@ -20,7 +20,7 @@
# installed smoke test.
Name: zupt
Version: 5.2.2
Version: 5.2.3
Release: 1%{?dist}
Summary: Backup compression with authenticated and post-quantum encryption
@ -101,6 +101,11 @@ comments. Plain archives use non-cryptographic checksums.
%endif
%changelog
* Mon Aug 31 2026 Cristian Cezar Moisés <sac@securityops.co> - 5.2.3-1
- Correct the release-package CI version checks and portable GUI version
contract, and make the openSUSE container replace busybox-gawk before
installing the native RPM toolchain.
* Mon Aug 31 2026 Cristian Cezar Moisés <sac@securityops.co> - 5.2.2-1
- Source-only release; optional SDK/PQBOX integrations use system development
packages only and are disabled for this package.

View file

@ -86,6 +86,16 @@ else
F "GUI is missing the anchored version regex (_VERSION_RE)"
fi
# Package and promotion gates consume this as a machine-readable identity.
# Keep binding and discovered-CLI diagnostics in the UI rather than appending
# them to the stable --version line.
if [ "$(grep -Fc 'print(f"zupt-gui {ZUPT_VER_NUMBER}' "$GUI")" -eq 1 ] &&
grep -Fqx ' print(f"zupt-gui {ZUPT_VER_NUMBER}")' "$GUI"; then
P "GUI --version emits the stable exact product/version line"
else
F "GUI --version output is not the stable exact product/version line"
fi
# ─── Brand-string check ───
# Release 5.2.2 restores the original ZUPT identity in every current panel.
if grep -q 'QLabel("ZUPT")' "$GUI" &&

View file

@ -58,6 +58,18 @@ check_recipe_version Guix \
"$(sed -n 's/^(define %zupt-version "\([^"]*\)")/\1/p' packaging/guix/zupt.scm)"
check_recipe_version openSUSE \
"$(awk '/^Version:/{print $2; exit}' packaging/opensuse/zupt.spec)"
check_recipe_version GUI-Deb-Control \
"$(awk '/^Version:/{print $2; exit}' gui/packaging/deb/control)"
if grep -Fqx "VERSION=\${VERSION:-$version}" install.sh && \
grep -Fqx "if not defined VERSION set \"VERSION=$version\"" \
gui/packaging/windows/build-windows.bat && \
grep -Fqx "Depends: python3 (>= 3.9), python3-pyqt6 | python3-pyside6.qtwidgets, zupt (= $version)" \
gui/packaging/deb/control; then
pass 'installer and static GUI package defaults match the upstream version'
else
fail 'installer or static GUI package defaults do not match the upstream version'
fi
if grep -En 'REPLACE_AFTER|REPLACE_WITH|sha256sums=\(.SKIP.|base32 .REPLACE' \
packaging/aur/PKGBUILD packaging/homebrew/zupt.rb packaging/guix/zupt.scm; then
@ -167,6 +179,25 @@ else
fail 'source scanner archive resource bounds or regressions are incomplete'
fi
tumbleweed_job=$(sed -n '/^ tumbleweed-rpm:/,/^ gui-rpm-package:/p' \
.github/workflows/ci.yml)
fedora_gui_job=$(sed -n '/^ gui-rpm-package:/,/^ linux-portable:/p' \
.github/workflows/ci.yml)
# These matches intentionally assert the literal Actions variable in YAML.
# shellcheck disable=SC2016
if grep -Fq 'git config --global --add safe.directory "$GITHUB_WORKSPACE"' \
<<<"$tumbleweed_job" && \
grep -Fq 'if rpm -q busybox-gawk >/dev/null 2>&1; then' \
<<<"$tumbleweed_job" && \
grep -Fq 'zypper --non-interactive remove busybox-gawk' \
<<<"$tumbleweed_job" && \
grep -Fq 'git config --global --add safe.directory "$GITHUB_WORKSPACE"' \
<<<"$fedora_gui_job"; then
pass 'RPM container jobs trust the exact workspace and replace busybox-gawk'
else
fail 'RPM container workspace trust or busybox-gawk replacement is incomplete'
fi
# These are literal shell expressions required inside the promotion workflow.
# shellcheck disable=SC2016
if grep -Fq 'zupt-gui_${VERSION}_all.deb' .github/workflows/promote-release.yml && \
@ -217,9 +248,9 @@ if grep -Eiq 'AppImage.*(not|excluded|outside)' SECURITY.md && \
grep -Eiq 'AppImage.*(not|excluded|outside)' THREAT_MODEL.md && \
grep -Eiq 'AppImage.*(not|excluded|outside)' AUDIT.md && \
grep -Eiq 'AppImage.*(not|excluded|outside)' doc/zupt.1; then
pass 'current security and user documentation records the 5.2.2 exclusions'
pass 'current security and user documentation records release exclusions'
else
fail 'current documentation still permits a 5.2.2 AppImage or bare EXE claim'
fail 'current documentation still permits an AppImage or bare EXE claim'
fi
handoff_legal_ok=1