Say the desktop app is not maintained, instead of selling a March build - #358
Conversation
09fede0 to
919aadc
Compare
|
Rebased on main (7c07b99). Two things worth flagging for review. 1. The two "already been declared" errors on this branch are not from this PR. They arrived on main through parallel merges and a hotfix is on the way:
Line 821 sits in the messaging-guide block that came from main, not in the 2. This PR’s new test block is wrapped in a bare block scope on purpose, so it can never contribute to that class of collision. Rest of the suite on the rebased branch: links, seo-contract 14, site-claims 11, frontend-loading-contract 7, navigation-shell 25 checks, csp-inline, cache-bust, static-sanity 10/10 with no warnings, and |
919aadc to
3b38478
Compare
|
Update: rebased on main (faf599e) now that #359 landed the deduplication. Both "already been declared" errors are gone, so the note above is resolved and nothing in it is outstanding. The new test block is now a named IIFE, All ten checks pass on head The five sabotage cases were re-run after the rebase and all still fail as intended: reverting the H1, putting |
3b38478 to
cf7f10f
Compare
|
The reviewer is right and I had it backwards. Corrected in I reproduced the evidence before changing anything: That fingerprint is exactly the GOODSIG in the v0.2.0 release notes, so the notes were accurate. The signature vanished between v0.2.0 and v0.2.1, and v0.2.1 is what My error was the yardstick: I checked only for Changed
Re-measured the other three with the same care, since one wrong yardstick is reason to distrust the rest. All unchanged:
Rebased on main ( |
Two reviewers rejected /download on 2026-09-02. The page opened with "THE
DESKTOP APP IS OUT OF DATE. USE THE WEB APP." and then ran a full product
page with four download buttons underneath, so it argued with itself. It
also led on jargon, and it made a signing claim that did not hold.
The facts settle which of the two messages the page keeps. The last
release of the app is v0.2.1, published 28 March 2026; none has followed
it, and the repository has no workflow that would build one. The .deb on
the page is v0.2.1 and the other three installers are still v0.2.0, so
there is no single version number for the list. The app is also a
messenger, not ParaSign or ParaSend, so it is not part of what the site
sells today. It is an archive, and the page now says so once, at the top.
Signing, measured on the published artifacts:
.deb 0.2.0 dpkg-sig signature present: a _gpgbuilder member holding a
clearsigned manifest, signer
6EF8E5ACC444949E5A2EAA65CCE2378929A49B97.
.deb 0.2.1 no _gpgbuilder and no _gpgorigin. Not signed.
.rpm rpm -qpi reports "Signature : (none)"; rpm -Kv shows only
header and payload digests.
.AppImage .sha256_sig and .sig_key exist but are all zeroes.
.exe Authenticode, certificate table 1704 bytes, but subject and
issuer are both CN=Mick Beer, O=PARAMANT, C=NL.
So the Debian package lost its signature between v0.2.0 and v0.2.1, and
v0.2.1 is the one this page serves. That is a regression in the build,
not a release note that overclaimed: the fingerprint in the v0.2.0 notes
is exactly the one in the artifact. A first version of this commit had it
the other way round, because it checked only for _gpgorigin, the member
debsigs writes, and dpkg-sig writes _gpgbuilder instead. A reviewer caught
it with the evidence. The yardstick on the page and in the test names both
members now, so the next reader cannot repeat it.
What the page does now, following docs/brand/messaging.md: the first
screenful says what this is, who it is for and what to do next, and it
carries only an H1, a two sentence sub and two buttons at 390px. The
split, the founder line and the proof follow in that order. The
installers are still reachable, collapsed into an archive with the
measurement and the checksums beside them, so anyone who needs the old
build can still verify what they downloaded.
Three defects fixed along the way. The file was truncated mid-word with
no closing main, body or html tag, which is why apply-nav.py could never
stamp nav.js or nav-auth.js on it and the hamburger on /download did
nothing. A second sticky nav, unique to this page, sat under the real
one. And .hero, .lede, .cta-row and .warn all collide with
design-system.css, which silently overrode the mobile spacing and
flattened inline links to body colour; the page local classes are
prefixed now.
Pinned in tests/ui-truthfulness.test.mjs: the status sentence with the
release and its date, the four installers as filename plus version plus
measured sha256 with no fifth link allowed, a yardstick that must name
both _gpgbuilder and _gpgorigin, a rule that every signing claim names
the release it holds for, the served .deb described as unsigned, a first
screenful jargon gate that did not exist before, and a check that the
document is complete and loads its nav scripts. Eight sabotage cases were
verified to fail.
cf7f10f to
3a0a4bd
Compare
Two reviewers rejected
/downloadon 2026-09-02, outside the auth PR. The pagewas internally contradictory: it opened with "THE DESKTOP APP IS OUT OF DATE.
USE THE WEB APP." and then ran a full product page with four download buttons
underneath it. It also opened on jargon, listed detail without meaning, and made
a signing claim about the installers that could not be checked.
The facts first, because they decide the message
I measured before writing, against the artifacts rather than the release notes.
.deband an Android.apk. None has followed it.Apolloccrypt/paramant-apphas no.github/workflowsat all, so nothing builds or signs automatically..debis v0.2.1. The.rpm, AppImage and.exeare still v0.2.0 (26 March 2026). No single version number covers the list./download. It is insitemap.xml:45, so it is reached from search or a bookmark.Signing, measured on the published files (all four are byte-identical to the
release artifacts, verified by sha256):
paramant_0.2.1_amd64.debar tlists onlydebian-binary,control.tar.gz,data.tar.gz. A signed Debian package carries a fourth member:_gpgbuilderfrom dpkg-sig, or_gpgoriginfrom debsigs. Neither is there. The v0.2.0 package does carry_gpgbuilder.PARAMANT-0.2.0-1.x86_64.rpmrpm -qpireportsSignature : (none); digests only.PARAMANT_0.2.0_amd64.AppImage.sha256_sig(1024 B) and.sig_key(8192 B) exist but are all zeroes, the placeholdersappimagetoolleaves when nothing signs.PARAMANT-0.2.0-windows-signed.exeCN=Mick Beer, O=PARAMANT, C=NL.So one of four carries a signature and it vouches for itself, which proves
nothing to someone who does not already hold the certificate.
A regression, not a false claim, and I had this backwards at first. The
v0.2.0 release notes say
[DEB] GPG signed - GOODSIG 6EF8E5AC.... That isaccurate: the v0.2.0 package carries a
_gpgbuildermember holding a clearsignedmanifest whose
Signer:is exactly6EF8E5ACC444949E5A2EAA65CCE2378929A49B97.The signature disappeared in v0.2.1, which is the package this page serves.
My first pass checked only for
_gpgoriginand concluded the notes hadoverclaimed. That was wrong, and a reviewer caught it with the evidence. There
are two tools and they write different members: dpkg-sig writes
_gpgbuilder,debsigs writes
_gpgorigin. Checking one and declaring a package unsigned isthe mistake, so the page and the test now name both.
The wider lesson, which is why the test is shaped the way it is: for a negative
finding you first have to know how many shapes the positive case has. One
command that returns nothing is not proof of absence.
The message I chose, and why
"The desktop app is not maintained, use the web app." Not a product page.
Five months without a release, no pipeline that could produce one, four
installers across two versions, one self-signed signature, and a product that is
not in the current line. A product page would have to imply a maintained thing.
The honest version is also the shorter one, and it is the only one that survives
docs/brand/messaging.md: a sentence may go on the site only if it is alreadytrue and a test fails when it stops being true.
The installers stay, but demoted: a collapsed archive with a warning, the
measurement, and the checksum beside each file. Someone who has a reason for the
old build can still get it and still verify it. Nobody is sold it.
Dropped: "missing 21 protections the web app has." The count was internally
consistent with its own list, but nothing in either repo can check it, and
docs/site-claims.md:78already recorded it as unpinnable. It is replaced byfacts that can be checked: the release date, the version split, and the
signature measurements above. Also gone, as the reviewers asked: the kicker
// NATIVE_APP_DOWNLOAD, "ML-KEM-768 and AES-256-GCM" above the fold, thenickname entropy line, and
x-forwarded-for read from the last hop.The page now
Following
messaging.mdsections 6 and 7. First screenful, confirmed byscreenshot at 390x844: kicker, H1, a two sentence sub, two buttons, nothing
else.
Then, in the guide's fixed order: what happened, the free/paid split quoted from
/pricing, the founder line, and the proof. All technical material sits in twocollapsed blocks at the foot, with the commands a reader can run themselves.
Since the source repo is private there is no public commit log to link, so the
control links are the artifacts and
/dl/SHA256SUMS, which anyone can check.Three defects fixed along the way
geen installatie vereiwith no
</main>,</body>or</html>.apply-nav.pybails on a missing</body>, so/downloadshipped withoutnav.jsandnav-auth.js: thehamburger did nothing and the signed-in state never resolved. No test caught
this, so one was added.
nav.p-navwith stale Dutch-era links(
/#sectoren,/#integratie) and its own inline CSS, unique to this page,stacked under the real nav. Removed.
.hero,.lede,.cta-rowand.warnall exist indesign-system.css, which loads after the page block and silently won:.heroforced 128px of top padding on mobile, and inline links rendered inbody colour so they were invisible as links. Page local classes are prefixed
dl-now.The page was also half Dutch under
<html lang="en">. It is English throughout.Tests
New section at the foot of
tests/ui-truthfulness.test.mjspinning:v0.2.1and28 March 2026deepEqualthat rejects a fifth/dl/link or a missing one, and a ban onlinking the
.apk_gpgbuilderand_gpgorigin; every sentence claiming a signature must name the release itholds for; the served v0.2.1
.debmust be described as unsigned; theself-signed disclosure is required; no "verified publisher" implication
assumed one;
grep -ril jargonreturns nothing repo-wide. The nearest thingwas
seo-contract.test.mjs:483, which only reads the title and the firstsentence of the meta description. The new gate slices
<main>to the end of<header class="dl-lead">and rejects crypto names, standard numbers, buildvocabulary, internal header names and the words
messaging.mdbans outright.Eight sabotage cases were verified to fail: reverting the H1, putting
ML-KEM-768back in the hero, inventing a0.3.0rpm, truncating the file,narrowing the yardstick to one member name, detaching a signing claim from its
release, erasing the regression sentence, and marking the served
.debsigned.tests/seo-contract.test.mjspins the title and description word for word, sothe
downloadentry inPINNEDmoves with the page.All green: links, seo-contract (14), ui-truthfulness, site-claims (11),
frontend-loading-contract (7), navigation-shell (25 checks), csp-inline,
cache-bust, eslint, static-sanity (10/10, no warnings).
python3 bron-seo/apply_seo_head.py --checkreportswould change: 0 pages.