Follow-ups of the review of PR #418.
- check-latest-json.jq wants exactly one document and release.yml calls it
with -s: under jq 1.6, the release container's, an empty file passed the
check (no output, status 0) and two documents were judged on the last one,
so the job would have deleted the published manifest and uploaded the bad
one. Two tests cover both cases.
- build-latest-json.test.mjs runs the text of release.yml's "Publish
latest.json to package registry" step against a fake curl: DELETE then PUT
on a valid manifest, exit 1 and no request on a refused one.
- check-frontend no longer ignores .claude/** and release.yml (decision of
Max): the test reads verify-release.sh and runs the Publish step, so "on
every pull request" holds. REVIEW.md, CLAUDE.md and architecture.md follow.
- release.yml: stale ".deb fallback" comment fixed.
- qa-update-cycle.md: a tauri dev build on Linux shows TargetsNotFound,
expected since #418.
Refs #461Resolves#419
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
REVIEW.md, from the suggestions of the first review of #460:
- stacked-PR pitfall: fs_commands.rs compiles two CSV files of
src/__fixtures__/samples/ through include_str!, outside the paths of
check-rust;
- high level: .claude/settings.json and .mcp.json, a pull_request_target
trigger, an install step that changes the toolchain or the PATH (the
check-workflow list is now given as examples of the principle), a lock
origin whose host or scheme changes even with a new version, and a diff
that removes or bypasses a consent (price consent lives on the front);
- db.ts and dataExportService.ts stay normal (Max's decision of
2026-10-18), and the data zone now names the lock, the profile switch
and the restore;
- release zone: cargo-xwin and the Rust toolchain, installed unpinned at
each tag, also run with the signing key;
- windows-sys guard: EXPECTED joins CRATES and PIN;
- identifier: changing it orphans the databases and the app_data_dir
files (license key, activation token, token fallback); the keychain
service is a constant and does not follow.
scripts/review-levels.py is the calibration script of the PR body, now in
the repo: pages of 50 files read until an empty page (the instance caps
pages at 50), the new rules above, comment lines ignored by the workflow
checks, and --check, which compares its patterns with the Haut table
without network access. Fresh run: 3/28/8 on the 39 reference PRs and
6/33/12 on the 51, unchanged.
Refs #456
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Max's decision on PR #416, after its review measured who still read the
key. tauri-plugin-updater looks up "{os}-{arch}-{installer}" first, and
every version that ships the updater (v0.2.1 and later, plugin 2.10.0,
tauri-utils 2.8.2 in each tag's Cargo.lock) carries its bundle-type
marker, so .deb and .rpm installs never reach the generic key. Its last
readers were the AppImage installs v0.4.3 to v0.4.5 (v0.4.2 targets a
route that answers 404, earlier versions read GitHub) and binaries run
outside a package; none of them can install the .deb it served, and the
updater wrote that .deb over the running file. They now get
TargetsNotFound when checking: an error on the Updates card, nothing
installed.
The key leaves the script, scripts/check-latest-json.jq and
verify-release.sh together; the test compares the three lists. Docs fix
the readers named by #416 (v0.4.2 is not one) and the CHANGELOG entry
says what changes for those AppImage installs.
Refs #320
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-ups of PR #416. The check that release.yml runs before
deleting the published manifest moves from an inline jq program to
scripts/check-latest-json.jq, which release.yml applies with
`jq -e --arg version ... -f`. scripts/build-latest-json.test.mjs now runs
that same filter on every pull request: on the script's output, on a
wrong version, on nine broken manifests and on the shape published up to
v0.17.1. It also compares the key lists of the script, of the filter and
of verify-release.sh, so a list left behind shows before the tag.
Two new cases pin the version argument: 0.18.0 must come out as 0.18.0
(the other fixtures pass 0.17.1, the version the bundle names carry, so a
script that ignored its argument passed them all), and an empty version
must fail. Both mutations survived the review's pass.
No change to what the manifest holds: still four keys.
Refs #320
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fallback key is also read by the AppImage installs of v0.4.2 to
v0.4.5 (bundled until v0.7.3, published on Forgejo for v0.4.2-v0.4.3
and on the GitHub mirror for v0.4.3-v0.4.5, all reading the registry),
which look up linux-x86_64-appimage, absent, then linux-x86_64. Like a
marker-less binary, they cannot install the .deb it serves: the updater
writes its bytes over the running AppImage. State since v0.4.2, not
changed by this PR; the key stays as decided.
Also quote the error the update card really shows for a refused
package (invalid updater binary format).
Refs #320
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
latest.json only had linux-x86_64, built from the .deb. An .rpm install
looks up linux-x86_64-rpm first, then fell back on linux-x86_64,
downloaded the .deb and refused it (InvalidUpdaterFormat).
- scripts/build-latest-json.sh writes linux-x86_64-deb,
linux-x86_64-rpm, linux-x86_64 (the .deb, as a fallback) and
windows-x86_64 from the release assets. It fails unless it finds
exactly one .deb, one .rpm and one -setup.exe, each with a non-empty
.sig. The JSON comes from jq alone, notes read with --rawfile, file
names encoded with @uri like the upload step.
- scripts/build-latest-json.test.mjs (vitest) runs it under
bash -e -o pipefail on a temporary assets dir; check-frontend
installs jq.
- release.yml calls the script, writes the notes output under a random
delimiter, checks the manifest with jq before the registry DELETE,
and names the .rpm instead of an AppImage in the release notes.
- verify-release.sh requires the four keys, the extension of each URL
and the minisign file: of each signature, and exits 1 on any failure.
- Docs: release skill, qa-update-cycle section 3 (rpm procedure, keys,
reason and removal condition of the fallback), architecture, README,
CHANGELOG, STATE.
Resolves#320
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>