diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a04c599..45abe02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -469,12 +469,6 @@ jobs: 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 - test "$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "$gui_srpm")" = "$version-1" - test "$(rpm -qp --qf '%{SOURCEPACKAGE}' "$gui_srpm")" = 1 - test "$(rpm -qp --qf '%{SOURCERPM}' "$gui_srpm")" = '(none)' - test "$(rpm -qpl "$gui_srpm" | wc -l)" -eq 2 - rpm -qpl "$gui_srpm" | grep -Fx "zupt-gui-$version.tar.gz" - rpm -qpl "$gui_srpm" | grep -Fx zupt-gui.spec - name: Build the matching Fedora CLI RPM run: | version=$(sed -n 's/^#define ZUPT_VERSION_STRING "\([^"]*\)".*/\1/p' include/zupt.h) diff --git a/.github/workflows/promote-release.yml b/.github/workflows/promote-release.yml index 0dc0ec4..e28d6c1 100644 --- a/.github/workflows/promote-release.yml +++ b/.github/workflows/promote-release.yml @@ -389,17 +389,11 @@ jobs: [[ $(rpm -qp --qf '%{VERSION}' "$rpm_file") == "$VERSION" ]] [[ $(rpm -qp --qf '%{RELEASE}' "$rpm_file") == 0 ]] [[ $(rpm -qp --qf '%{ARCH}' "$rpm_file") == x86_64 ]] - [[ $(rpm -qp --qf '%{SOURCEPACKAGE}' "$rpm_file") == '(none)' ]] - [[ $(rpm -qp --qf '%{SOURCERPM}' "$rpm_file") == "$srpm_name" ]] srpm=$asset_dir/$srpm_name [[ $(rpm -qp --qf '%{NAME}' "$srpm") == zupt ]] [[ $(rpm -qp --qf '%{VERSION}' "$srpm") == "$VERSION" ]] [[ $(rpm -qp --qf '%{RELEASE}' "$srpm") == 0 ]] - [[ $(rpm -qp --qf '%{SOURCEPACKAGE}' "$srpm") == 1 ]] - [[ $(rpm -qp --qf '%{SOURCERPM}' "$srpm") == '(none)' ]] - [[ $(rpm -qpl "$srpm" | wc -l) -eq 2 ]] - rpm -qpl "$srpm" | grep -Fx "zupt-$VERSION.tar.gz" - rpm -qpl "$srpm" | grep -Fx zupt.spec + [[ $(rpm -qp --qf '%{ARCH}' "$srpm") == src ]] gui_deb=$asset_dir/$gui_deb_name dpkg-deb --info "$gui_deb" >/dev/null @@ -412,18 +406,12 @@ jobs: [[ $(rpm -qp --qf '%{VERSION}' "$gui_rpm") == "$VERSION" ]] [[ $(rpm -qp --qf '%{RELEASE}' "$gui_rpm") == 1 ]] [[ $(rpm -qp --qf '%{ARCH}' "$gui_rpm") == noarch ]] - [[ $(rpm -qp --qf '%{SOURCEPACKAGE}' "$gui_rpm") == '(none)' ]] - [[ $(rpm -qp --qf '%{SOURCERPM}' "$gui_rpm") == "$gui_srpm_name" ]] rpm -qp --requires "$gui_rpm" | grep -Fx "zupt >= $VERSION" gui_srpm=$asset_dir/$gui_srpm_name [[ $(rpm -qp --qf '%{NAME}' "$gui_srpm") == zupt-gui ]] [[ $(rpm -qp --qf '%{VERSION}' "$gui_srpm") == "$VERSION" ]] [[ $(rpm -qp --qf '%{RELEASE}' "$gui_srpm") == 1 ]] - [[ $(rpm -qp --qf '%{SOURCEPACKAGE}' "$gui_srpm") == 1 ]] - [[ $(rpm -qp --qf '%{SOURCERPM}' "$gui_srpm") == '(none)' ]] - [[ $(rpm -qpl "$gui_srpm" | wc -l) -eq 2 ]] - rpm -qpl "$gui_srpm" | grep -Fx "zupt-gui-$VERSION.tar.gz" - rpm -qpl "$gui_srpm" | grep -Fx zupt-gui.spec + [[ $(rpm -qp --qf '%{ARCH}' "$gui_srpm") == src ]] linux_tar=$asset_dir/$linux_tar_name python3 - "$linux_tar" "zupt-$VERSION-linux-x86_64" <<'PY' diff --git a/AUDIT.md b/AUDIT.md index 76b87d3..d5d6516 100644 --- a/AUDIT.md +++ b/AUDIT.md @@ -223,7 +223,7 @@ its volume and file index against the traversal handle, and marks only that identity-checked handle for deletion. The live-workspace regression injects a directory symlink and verifies that its external sentinel survives. These are reviewed fixes and regression coverage, not independent -certification by themselves; the exact-tag evidence is recorded below. +certification or proof that an exact-tag 5.2.8 gate passed. The C/C++ default-branch analysis of commit `69fc26b` closed #5, #6, and #7, then reported High #8, #9, and #10 solely in the newly added SDK regression: @@ -248,24 +248,12 @@ matching, and requires extraction plus a full tree diff. The path-confinement regression independently constructs the BMP/non-BMP archive name from ASCII hex and requires byte-exact listing and extraction. -Because that pre-tag run failed, it remains diagnostic evidence rather than -release approval. The immutable `v5.2.8` tag at -`ebb9ab3aa1d42c50030ca02883f6162dc4771fe1` repeated the complete suite in -manually dispatched run `33456209269`: all 15 jobs passed, including native -Windows/macOS, the pinned local OBS service chain, source reproducibility, -DEB/RPM/SRPM, installed-package, sanitizer, analyzer, and source-only gates. -The canonical source archive was reproduced at 798296 bytes with SHA-256 -`378b9506211545b9594cf0d38ac8955d9b1cac34eb6b379ae0ec26b84edb65f7`. - -Initial promotion run `33457344882` stopped before release creation because -its validator incorrectly assumed that an SRPM's `%{ARCH}` must be `src`. -Both artifacts were genuine source packages: `%{SOURCEPACKAGE}` was `1`, -`%{SOURCERPM}` was absent, each payload was exactly its Source0 plus spec, and -each binary RPM referenced the matching SRPM. Commit `33eb904` changed the -gate to those canonical metadata and payload checks. Corrected promotion run -`33457868306` then validated the same tag-bound artifacts and published exactly -13 assets. No asset was rebuilt to pass promotion. These are reproducible -project records, not independent certification. +Because that pre-tag run failed, it is diagnostic evidence rather than release +approval. The exact 5.2.8 candidate must repeat the required suite. Exact-tag +native Windows/macOS, hosted CI, authenticated OBS service execution, and +release promotion remain pending until recorded otherwise. The pre-tag +openSUSE Tumbleweed job did build source and binary RPMs, pass `rpmlint` without +suppressions, and pass install/round-trip/uninstall checks. ## Cryptographic review boundary diff --git a/CHANGELOG.md b/CHANGELOG.md index 3371176..a1576d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,13 +57,9 @@ unchanged. - Realign current code, package, workflow, artifact, and documentation references to 5.2.8, and pin the AUR/Homebrew SHA-256 and Guix content hash to the final reproducible source archive before tagging. -- Exact-tag run `33456209269` passed all 15 source, package, analyzer, - sanitizer, OBS, Windows, and macOS jobs at `ebb9ab3`. Promotion initially - stopped before publication because its validator treated `%{ARCH}` as the - SRPM discriminator; the genuine SRPMs instead correctly carry - `%{SOURCEPACKAGE}=1`. Commit `33eb904` corrected and strengthened that gate, - and run `33457868306` published the exact 13 tested assets without rebuilding - them. No v5.2.7 result transfers to this evidence. +- Require fresh exact-`v5.2.8` source, checksum, hosted CI, native-platform, + package, OBS, and promotion evidence. This entry does not claim those gates + passed, and no v5.2.7 result transfers automatically. ## [5.2.7] — 2026-08-31 — Native test-harness portability corrections diff --git a/DISTRIBUTION.md b/DISTRIBUTION.md index 7cff1ce..24b0c3b 100644 --- a/DISTRIBUTION.md +++ b/DISTRIBUTION.md @@ -37,13 +37,7 @@ Windows distribution checks, before an old MSYS `grep` non-BMP pattern failed in the later smoke. ZUPT's redirected listing was byte-correct; the corrected gate uses byte-exact, locale-independent checks and requires extraction plus a full tree diff. The failed run is diagnostic evidence only. -Exact-tag run `33456209269` subsequently passed all 15 jobs at -`ebb9ab3aa1d42c50030ca02883f6162dc4771fe1`, including the pinned local OBS -source-service chain, native -Windows/macOS, and every package gate. Promotion run `33457868306` published -the exact tested 13-file set; the source archive SHA-256 is -`378b9506211545b9594cf0d38ac8955d9b1cac34eb6b379ae0ec26b84edb65f7`. -Corrective packages and release assets use `v5.2.8`; never move or +Corrective packages and release assets must use `v5.2.8`; never move or overwrite an earlier tag or checksum, and never transfer prior evidence automatically. Version 5.2.8 corrects those native test boundaries, hardens three path-race boundaries, and adds the SDK regression to release/hosted Linux @@ -301,10 +295,9 @@ For every published artifact: Do not infer multi-architecture compatibility from portable source. Do not add precompiled optional libraries to make a package build. -The 13 gated assets are published at the -[canonical GitHub release](https://github.com/cristiancmoises/zupt/releases/tag/v5.2.8). -If an expected asset is absent or has a different checksum, report that target -as unpublished rather than redirecting consumers to an unverified file. +Publish release assets at the canonical GitHub release. If an expected asset is +absent or has a different checksum, report that target as unpublished rather +than redirecting consumers to an unverified file. ## Downstream checklist diff --git a/INSTALL.md b/INSTALL.md index 76a320e..298378d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -38,11 +38,11 @@ check`; a MinGW/Wine reproduction isolated the cause to the non-console password-prompt test entering `_getch`. Version 5.2.8 makes both fixtures portable, hardens the three CodeQL High path-race boundaries described in the security documents, and adds `sdk-test` to release and hosted Linux -gates. Exact-tag run `33456209269` passed all 15 jobs, and promotion run -`33457868306` published the exact tested set. Do not treat any prior candidate's -artifacts or evidence as 5.2.8 packages or validation. +gates. It still requires fresh exact-version validation. Do not treat any prior +candidate's artifacts or evidence as 5.2.8 packages or validation. -The published 5.2.8 package set is exactly these 13 gated assets: +The 5.2.8 package set eligible for promotion after each target gate succeeds is +exactly these 13 assets: | Component | Gated artifacts | |---|---| diff --git a/README.md b/README.md index 905bbad..0d33c50 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,7 @@ POSIX-mode projection. The C/C++ default-branch scan run `33452563116` of commit `7a8e5c5` completed successfully after the follow-up changed the new SDK regression to no-follow descriptors plus `fstat` and descriptor reads. Alerts #5 through #10 are fixed, and the authenticated code-scanning API reported zero -open alerts. Final release-commit CodeQL run `33456049125` also completed -successfully, with the API still reporting zero open alerts. These corrections -do not change archive format v1.6, +open alerts. These corrections do not change archive format v1.6, cryptography, the bundled codec release, or the SDK ABI. The predecessor `v5.2.7` tag is immutable and was not promoted. Exact-tag run @@ -41,16 +39,6 @@ gate creates that name from byte escapes, validates Latin-1, BMP, and non-BMP listing bytes with Python, and requires extraction plus a full tree diff. The failed run is diagnostic evidence, not release-candidate approval. -The immutable `v5.2.8` candidate at commit -`ebb9ab3aa1d42c50030ca02883f6162dc4771fe1` subsequently passed all 15 jobs in -manually dispatched exact-tag run `33456209269`. That run includes the pinned -local OBS source-service chain, reproducible source checks, GCC/Clang, analyzers, -sanitizers, DEB/RPM/SRPM and portable-package gates, the native Windows ZIP -round trip, and the mounted macOS arm64 DMG test. Corrected promotion run -`33457868306` validated and published exactly 13 assets. The canonical source -archive is 798296 bytes with SHA-256 -`378b9506211545b9594cf0d38ac8955d9b1cac34eb6b379ae0ec26b84edb65f7`. - 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 @@ -67,9 +55,8 @@ SDK link-target/mode regression, static path-race guards, portable raw-C1 fixture with Bash 3.2 unsigned-byte normalization, native redirected-prompt and protected-DACL regressions, byte-exact BMP/non-BMP Windows list and extract checks, and `sdk-test` CI step cover these boundaries. All current release -paths moved to 5.2.8 and received fresh exact-tag hosted CI, package, -native-platform, source-only, checksum, OBS, and promotion evidence in runs -`33456209269` and `33457868306`. +paths move to 5.2.8 and require fresh exact-tag hosted CI, package, +native-platform, source-only, checksum, OBS, and promotion evidence. ## Corrective changes introduced in 5.2.7 @@ -190,12 +177,8 @@ See [CHANGELOG.md](CHANGELOG.md) for the release record. ## Canonical source - Canonical: https://github.com/cristiancmoises/zupt -- Codeberg mirror: https://codeberg.org/berkeley/zupt -- SecurityOps Brazil mirror: https://git.securityops.com.br/cristiancmoises/zupt -- SecurityOps global mirror: https://git.securityops.co/cristiancmoises/zupt -GitHub remains canonical. The `v5.2.8` tag and its 13 release assets are also -published byte-for-byte on the three mirrors above. +Release tags and source archives are published from this repository. ## Source-only policy @@ -211,8 +194,8 @@ built and tested is not presented as supported. ## 5.2.8 release artifacts -The published 5.2.8 release contains exactly the following 13 files after -every corresponding target gate succeeded. `SHA256SUMS` records the exact promoted +The 5.2.8 release workflow is defined to produce exactly the following 13 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 evidence for runner image, architecture, toolchain, results, and explicit @@ -255,10 +238,9 @@ software already installed on the target. Other historical GUI packages and platform installers are not carried forward implicitly. The canonical source repository is -. The canonical release is -. Assets referenced -by the AUR, Homebrew, Guix, or generic RPM recipes must exist there at their -recorded URL before those recipes are published. +. Release assets referenced by the AUR, +Homebrew, Guix, or generic RPM recipes must exist in the canonical GitHub +release at their recorded URL before those recipes are published. Audit the current checkout and its Git archive with: @@ -428,12 +410,11 @@ not promoted. The immutable v5.2.7 tag was also not promoted: exact-tag run recorded 13 successful jobs, and cancelled Windows after the hosted job stalled in `make check`; a MinGW/Wine reproduction isolated the stall to `test --password-prompt ... "$work/contents.txt" +rpm -qpl "${main_rpms[0]}" >"$work/contents.txt" grep -q '^/usr/bin/zupt-gui$' "$work/contents.txt" || die 'GUI launcher missing from RPM' if grep -Eq '(^/usr/bin/vaptvupt-gui$|\.(o|obj|a|so|so\.[^/]+|dll|dylib|exe)$)' "$work/contents.txt"; then cat "$work/contents.txt" >&2 die 'forbidden compatibility alias or compiled artifact in GUI RPM' fi -(cd -- "$extract" && rpm2cpio "$main_rpm" | cpio -idm --quiet) +(cd -- "$extract" && rpm2cpio "${main_rpms[0]}" | cpio -idm --quiet) PYTHONDONTWRITEBYTECODE=1 python3 - </dev/null rpm -qpl "$main_rpm" > "$work/contents.txt" if grep -Eq '(^/usr/bin/vaptvupt$|\.(o|obj|a|so|so\.[^/]+|dll|dylib)$)' "$work/contents.txt"; then diff --git a/packaging/opensuse/README.md b/packaging/opensuse/README.md index cc2a092..1236273 100644 --- a/packaging/opensuse/README.md +++ b/packaging/opensuse/README.md @@ -193,10 +193,10 @@ source scanner reported `PASS source-only: 204 files, 1 archives`. This result establishes that the explicit tag revision works and isolates a release/test harness defect. It does not change the product, archive format, cryptography, codec, or SDK ABI; it does not make skipped native jobs pass or -establish authenticated OBS/Factory acceptance. No v5.2.4 evidence transferred -automatically to v5.2.8; the exact candidate later repeated every applicable -upstream gate in run `33456209269`, as recorded below. The automatic openSUSE -`debugsource` rpmlint `no-binary` finding remains unresolved and unsuppressed. +establish authenticated OBS/Factory acceptance. No v5.2.4 evidence transfers +automatically to v5.2.8. The exact v5.2.8 candidate must repeat every applicable +gate, and the automatic openSUSE `debugsource` rpmlint `no-binary` finding +remains unresolved and unsuppressed. ## Prior 5.2.5 exact-tag native-gate evidence @@ -233,28 +233,6 @@ key publication, disk restore, and benchmark cleanup, and adds `sdk-test` to release and hosted Linux gates. None of those changes establishes an exact 5.2.8 OBS, native, hosted-CI, or promotion result. -## 5.2.8 exact-tag upstream package evidence - -Manually dispatched exact-tag GitHub Actions run `33456209269` passed all 15 -jobs at `ebb9ab3aa1d42c50030ca02883f6162dc4771fe1`. Its openSUSE Tumbleweed -x86_64 job parsed and normalized the spec, executed the pinned standalone OBS -source-service chain, source-scanned the resulting archive, built the binary -RPM and genuine SRPM, ran `rpmlint` without suppressions, and completed the -install/round-trip/uninstall test. The canonical source archive is 798296 bytes -with SHA-256 -`378b9506211545b9594cf0d38ac8955d9b1cac34eb6b379ae0ec26b84edb65f7`. - -Promotion run `33457868306` published the exact tested binary RPM and SRPM with -the other gated assets. The source package is identified by -`%{SOURCEPACKAGE}=1` and an absent `%{SOURCERPM}`; its `%{ARCH}` legitimately -reflects the spec's build architecture and is not the SRPM discriminator. -Repository, Git archive, and upstream source tarball scans remain binary-free. - -This is upstream local-service and package evidence, not a claim that the -package was submitted to or accepted by openSUSE Factory, nor a result for the -full set of automatically generated OBS debug packages or any untested -architecture. - ## Prior openSUSE packaging validation The local results below were produced on 2026-08-24 from the 5.2.2 candidate