Signed in, the free plan is called Community, and the page answers what a buyer asks - #332
Merged
Merged
Conversation
Apolloccrypt
force-pushed
the
feat/dashboard-ingelogd
branch
from
September 2, 2026 14:26
2cf702d to
da5bcc7
Compare
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Three blockers from the buyer review and three from the truthfulness review.
BUYER 1. The free plan is called Community on every page. It was the one word
Mick sells on, and /pricing called it Free while the backend has always called
it Community (admin/server.js PLANS: id 'community', name 'Community'). Renamed
the two tier cards on /pricing, and pulled the rest of the frontend in line:
terms, privacy, docs, audit-log-export, the 402 upgrade card, and the two
bridge sentences on the homepage and the dashboard that only existed to explain
the disagreement away. The pricing intro now says what the plan IS: not a
trial, not a funnel, Mick Beer's contribution back, and businesses paying for
the higher limits is what keeps it free.
BUYER 3. The ParaRules grid on the homepage printed 01, 03, 04, 06, which reads
as two rules missing rather than four chosen. The numbers are gone and the lede
says four of the nine are shown.
TRUTH 1. index.html promises 'The ParaRules come with a verify link each' and
pararules.html had nine rules and zero links. Every rule now carries one, each
pointing at something that already exists: the security page, the privacy page,
the repo, the crypto-agility page, the changelog, the CT log, security.txt.
TRUTH 2. The plan mapping was incomplete and an unmapped ID rendered raw.
dashboard.js now mirrors relay/lib/tiers.js, the declared single source of
truth: four canonical plans, with normalisePlan's aliases folded the same way
('free' and 'dev' to community, 'licensed' to enterprise).
TRUTH 3. A paying customer was told he is on the free plan. setProductPlan
writes only plan_parasign / plan_parasend and by design never touches the
unified plan, and the three endpoints a signed-in page reads returned only that
unified field. They now share one productPlanFields() helper, and dashboard.js
derives the effective plan from it: paid on either product means no Community
band and a badge showing the highest paid tier. This is a backend change to
admin/server.js because the data simply was not on the wire.
Smaller: the schema.org description said hosted in the Netherlands and Germany
while hosting is Germany only; the Enterprise line bundled ParaSend and
ParaSign terms as if they were one plan; 'accountancy' is not one of the sector
relays, which are finance, health and legal; and the dead txt('email') call is
gone now that the hero no longer repeats the address.
Gates: the plan gate reads the rows and the aliases out of tiers.js instead of
a copy, the price gate matches the whole amount instead of a substring (it
stayed green on a page that only ever said 150 when the homepage said 15), and
every ParaRule must carry a verify link. admin/test/user-plan-fields.test.js
pins the helper and the three endpoints that spread it.
Two relay tests pinned the old name verbatim and were updated with it.
The dashboard block ORDER is deliberately untouched: PR #332 owns that.
Apolloccrypt
force-pushed
the
feat/homepage-koper
branch
from
September 2, 2026 14:26
b609fb0 to
cee3093
Compare
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Three blockers from the buyer review and three from the truthfulness review.
BUYER 1. The free plan is called Community on every page. It was the one word
Mick sells on, and /pricing called it Free while the backend has always called
it Community (admin/server.js PLANS: id 'community', name 'Community'). Renamed
the two tier cards on /pricing, and pulled the rest of the frontend in line:
terms, privacy, docs, audit-log-export, the 402 upgrade card, and the two
bridge sentences on the homepage and the dashboard that only existed to explain
the disagreement away. The pricing intro now says what the plan IS: not a
trial, not a funnel, Mick Beer's contribution back, and businesses paying for
the higher limits is what keeps it free.
BUYER 3. The ParaRules grid on the homepage printed 01, 03, 04, 06, which reads
as two rules missing rather than four chosen. The numbers are gone and the lede
says four of the nine are shown.
TRUTH 1. index.html promises 'The ParaRules come with a verify link each' and
pararules.html had nine rules and zero links. Every rule now carries one, each
pointing at something that already exists: the security page, the privacy page,
the repo, the crypto-agility page, the changelog, the CT log, security.txt.
TRUTH 2. The plan mapping was incomplete and an unmapped ID rendered raw.
dashboard.js now mirrors relay/lib/tiers.js, the declared single source of
truth: four canonical plans, with normalisePlan's aliases folded the same way
('free' and 'dev' to community, 'licensed' to enterprise).
TRUTH 3. A paying customer was told he is on the free plan. setProductPlan
writes only plan_parasign / plan_parasend and by design never touches the
unified plan, and the three endpoints a signed-in page reads returned only that
unified field. They now share one productPlanFields() helper, and dashboard.js
derives the effective plan from it: paid on either product means no Community
band and a badge showing the highest paid tier. This is a backend change to
admin/server.js because the data simply was not on the wire.
Smaller: the schema.org description said hosted in the Netherlands and Germany
while hosting is Germany only; the Enterprise line bundled ParaSend and
ParaSign terms as if they were one plan; 'accountancy' is not one of the sector
relays, which are finance, health and legal; and the dead txt('email') call is
gone now that the hero no longer repeats the address.
Gates: the plan gate reads the rows and the aliases out of tiers.js instead of
a copy, the price gate matches the whole amount instead of a substring (it
stayed green on a page that only ever said 150 when the homepage said 15), and
every ParaRule must carry a verify link. admin/test/user-plan-fields.test.js
pins the helper and the three endpoints that spread it.
Two relay tests pinned the old name verbatim and were updated with it.
The dashboard block ORDER is deliberately untouched: PR #332 owns that.
Apolloccrypt
force-pushed
the
feat/homepage-koper
branch
from
September 2, 2026 14:35
cee3093 to
4af78dd
Compare
Apolloccrypt
force-pushed
the
feat/dashboard-ingelogd
branch
from
September 2, 2026 14:47
da5bcc7 to
a0fbbf2
Compare
Apolloccrypt
force-pushed
the
feat/dashboard-ingelogd
branch
from
September 2, 2026 15:24
a0fbbf2 to
8340a4c
Compare
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The site sold to an engineer while the buyer is an office. /docs is busier than /pricing, the flagship product has no page of its own, and the only selling point Mick names (the Community plan is his giveback, organisations pay for the business plans) appears nowhere above the fold. This adds docs/brand/messaging.md as the one place that settles the words: audience and their problem, the promise in one sentence, the free-versus-paid split as the structure of the site rather than a section in it, three proofs quoted from pages that ship today with the test that pins each, the founder line as /about already states it, tone and banned words, and per page the goal, H1, first paragraph and primary CTA. Two rules it enforces. Every sentence is quoted from a live page or from frontend/pricing.html, never written fresh. And no claim moves into a hero without a test that fails when it stops being true, which is why proof 1 and proof 3 are marked as pins still to be added to ui-truthfulness. Proof 1 is written to the jurisdiction claim as it now ships after #328. The claim is about the data path, not the whole chain: files and keys never leave the EU and are ciphertext outside the browser, and transactional email is the one exception and goes via Resend, a US provider, exactly as /privacy sets out. The guide quotes the rules grid on / and ParaRule 5 on /pararules word for word, forbids the older "no US company in the chain" phrasing, and drops the homepage H1 that carried it, because an H1 has no room for the Resend exception the claim needs beside it. Cloudflare is gone from the guide: DNS moved to Bunny and the site is served straight from Hetzner. Section 3 and section 5 are brought level with the pages: the free plan is Community on both products, the give-back paragraph is quoted from /pricing where it ships, and the founder paragraph matches /about word for word. It records three places where the site runs ahead of itself: /about says SES where the pricing FAQ says advanced (AES), the /security jurisdiction table still carries the unqualified "no US infrastructure, no US company" row, and the give-back sentence is not on /about until #332 lands. Each needs its own PR, not a silent copy edit. Docs only. No page, test, nav or style is touched.
The dashboard and the account page are what a customer sees after signing up, so they carry the same message the homepage sells on: the Community plan is given, the business plans pay for it. This makes that message true, checkable and, on a phone, actually reachable. Order on a 390px screen. Measured with getBoundingClientRect, viewport 844: before plan band 323, upgrade link 624, first action 718, second 1004 after plan chip 247, first action 323, second action 612, plan band 1132 The band came first and pushed both products past the fold, so the two things a customer opens the page to do were half visible and invisible. The actions are now directly under the greeting and the plan message follows them. scripts/shot-dashboard.mjs prints these offsets on every run. /about is the source for the founder line, so the give-back sentence belongs there first. It now says, in Behind Paramant, that the Community plan is his way of giving something back to society and the business plans pay for it. The dashboard and account bands use that wording and no other. The founder gate is two-way and no longer optional. It used to be shaped "if the page says X, check /about says X", which a rewrite walks past: swapping the title for an invented one deletes the string the check looked for. Now index, dashboard and account MUST name him, the title must be the one /about gives, and every word in the clause beside his name must be a word /about uses. Paying is decided by behaviour, not by a string. The old check read account.inline1.js looking for the literal 'current_plan !== community', which says nothing about what the page does. tests/user-dashboard-documents.test.mjs now drives /account in Chromium across six plan shapes: Community, the ParaSign floor 'free', the ParaSend floor 'community', an unrecognised tier, a live self-serve ParaSign Pro, and one whose paid period has lapsed. It checks the plan chip, the Current plan row, the Active badge, the Cancel button and which of the two bands is on screen. paidProductTier() now reads the paid rungs instead of listing the floors. The two products do not share a floor in relay/lib/entitlements.js (PARASEND_TIERS starts at community, PARASIGN_TIERS at free), and a list of floor words is a list that goes stale. Reading it the other way round fails closed: a floor word, a renamed tier and a typo all come out unpaid. Copy, each against its source: - ParaSend has one story and it is the true one. relay.js decrements views_remaining and burns at zero, so the card says the file is gone the moment it has been read, matching the hero and the homepage rules grid. "It expires by itself" was a second, softer story. - The EUR 15 card is called Pro, not Business. Business is EUR 299. The price answer names the tier it belongs to. - Verification is not unconditional. verify.html says a legacy v1/v2 envelope can only be checked by the relay with an API key, so the answer reads: signed documents verify without an account, older envelope formats need the relay. - Webhooks, exportable audit log, API access, no IP rate limit and CT tree head are gone from both bands. A lawyer reads what he gets; the feature names stay on /pricing where they are sold. scripts/shot-dashboard.mjs writes .jpg directly at 1x. The body linked .jpg files a PNG-only script had never written.
Apolloccrypt
force-pushed
the
feat/dashboard-ingelogd
branch
from
September 2, 2026 17:30
8340a4c to
f23e989
Compare
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=609. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place, the sentence section 5 fixes
word for word: the Community plan is his way of giving something back to
society; the business plans pay for it. PR #332 puts it on the page from
the other side; this branch does not wait for it.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=629 and "Verify a document" at y=689.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. All
four agree now, and the description no longer describes a lede the page
stopped carrying. Its plan sentence named two of the four paid ParaSign
tiers; it names all of them.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the four paid tiers. Eighteen
sabotages, eighteen red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 162 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0. At 390px all three pages have
scrollWidth === clientWidth === 390.
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
…araSign Three pages, one shape, taken from docs/brand/messaging.md: what you can do here, who it is for, the split with its real number, who is behind it, then the proof and the honest limits. The algorithm names moved to the bottom of every page, where they are the reason a plain sentence above is true. /parasend is new. ParaSign has had a page since #325; ParaSend had nothing, so the send half of the product could not be found by name. It follows the /parasign pattern the guide asks for. What changed against the review, per page. /parasign - H1 is the one the guide specifies: "Sign documents in your browser, prove it years later." The old H1 was the product name, which does not say what the page is for. - The opening paragraph says what a buyer gets, in two sentences and 160 characters, and no longer opens on ML-DSA-65 and a transparency log. The guide's own tone rule keeps cryptography below the fold; the sentence it specifies for this page contradicted that rule, so the sentence now sits verbatim in the proof block at 04 instead of in the hero. - The buyer is named in the first screen: legal, finance and healthcare practices in the EU, the same audience index.html states. - The eIDAS status moved from 6,386px to 737px. A lawyer asks it first; the page now answers it before the tiers instead of on screen 8 of 9. - The free promise carries its number. "Free forever" became "Free on the Community plan: 2 signatures a month, no card, forever." - "Zero-knowledge" is gone from the scope note. It described nothing this page can point at, and it sat next to the most honest paragraph on the page. - The proof block quotes /about word for word and carries the EU claim in the form #328 settled: no US provider in the data path, with Resend named in the same breath. /parasend - Section 02, the section that has to convince, said AES-256-GCM, ciphertext, RAM, ML-KEM-768, tenant and RAM budget. It now says what the buyer gets. The algorithm names are in 06, each next to the page that checks it. - The free promise carries its limits: links that last an hour, gone after one read, 10 uploads an hour. - The bridge sentence explaining that Community is listed as Free is gone, and the tier card is named Community. #328 renamed the tier on /pricing, so there is nothing left to explain away. - The founder block quotes /about instead of composing a sentence about US subscriptions. #332 put that sentence on /about, so it is now sourced. /sign - "Private key" was the last jargon in the first screenful. Same fact, words a practice manager already uses. One layout fix, page-local. At 390px the house .sec-head keeps the section number in its own grid column, which left the H1 about 160px to wrap in: six lines of headline on /parasign, and the buttons and the eIDAS note off the first screen. On a narrow screen the number now stacks above the headline. design-system.css is untouched, because it is shared with pages this PR does not open. Measured at 390px with Playwright, per page: no horizontal overflow anywhere (scrollWidth 390), and on /parasign the H1, the audience, both buttons, the free promise and the eIDAS note all land inside the first 844px.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Two gates that looked like gates and were not, both found by sabotage rather
than by reading.
1. The monthly price on both product pages was pinned by nothing.
relay/test/pricing-page.test.js asserted with a bare substring, so
includes('€49') was satisfied by the annual "€499 excl." standing on
the same card, and includes('€15') by "€150". Verified: €49 to
€59 on /parasign and €15 to €19 on /parasend both stayed green.
Those are the two numbers a buyer clicks. An amount now has to end where it
says it ends and sit on the card of the plan it belongs to; the opening line
"business plans from €49 a month" can no longer stand in for the tier.
Both sabotages go red after this, and so do the annual amounts.
2. A claim that has to be read in the first screen was asserted against the
whole file, which is satisfied by screen 8 of 9. The eIDAS scope note, the
audience line and the free promise with its number are now asserted against the
hero section of the page, not against the file.
Also pinned, each one a sentence that had drifted or had no source:
- The SLA figure is read off /sla by name (the Enterprise cell, not the first
.uptime on the page) and every page repeating it has to match. This is how
"SLA 99.9%" reached a product page while /pricing and /sla both published
99.95%: the quota lines were pinned, the service lines were not.
- The EU claim in the form #328 settled: "No US provider in the data path"
with the Resend exception in the same breath, on /, /parasign and /parasend.
The broader "no US company" wording is refused on the product pages;
section 9 of the guide holds it open, and it stays on /security where the
table qualifies it.
- The give-back sentence, now that #332 has put it on /about, quoted rather
than composed.
- The free plan is called Community on /sign too, and "Free accounts" is
refused there.
The stale string is gone as well: the suite pinned "The community tier stays
free", a sentence #328 removed from /pricing. It now pins what /pricing
actually ships.
This was referenced Sep 2, 2026
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=629 and "Verify a document" at y=689.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. All
four agree now, and the description no longer describes a lede the page
stopped carrying. Its plan sentence named two of the four paid ParaSign
tiers; it names all of them.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the four paid tiers. Eighteen
sabotages, eighteen red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 162 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0. At 390px all three pages have
scrollWidth === clientWidth === 390.
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Third pass on the review of PR #333. Blocker. The data-location answer said "Your documents and keys live on servers at Hetzner Nuremberg, Germany". The keys do not. Five places on the site promise the opposite: "Generated on your device, never sent" (index.html), "relay holds only ciphertext, never keys" and "No plaintext, no keys" (security.html), "we never hold decryption keys, anywhere" (trust.html), "The relay never sees plaintext and never holds a private key" (docs.html). Flattening a table into prose is how the word "keys" got in there, and it is the sentence a security reviewer would quote back at us. The answer now says the documents are there and that they are ciphertext, and it quotes docs.html for where the keys are not: Your documents live on servers at Hetzner Nuremberg, Germany, and they sit there as ciphertext. The relay never sees plaintext and never holds a private key. Your files stay under EU law and the GDPR, and no US provider is in the data path. Email goes out via Resend, as /privacy sets out. Pinned in both directions. The positive half is a pair, the quote and docs.html. The negative half is a loop over every sentence in the /help body: a sentence that mentions a key and a piece of infrastructure in the same breath must be denying it, and may never use a locative verb between the two. Sabotage: putting "and keys" back is red, "your keys are stored on the relay" is red, and "Your keys are kept on servers at Hetzner Nuremberg, and there is no US provider" is red as well, so a stray "no" elsewhere in the sentence does not buy a pass. Also in this commit, from the same review: - The gate against the pricing slogan and the one against sales vocabulary ran on the three answers only. Both now run on the whole /help body below </head>, so the line cannot come back through the lede, an article card or the footer. Sabotage on both: red. - Rebased on main for #332, which added two console.log lines at the end of tests/ui-truthfulness.test.mjs. No name collision; both sides kept. Tests: links, seo-contract, ui-truthfulness, site-claims, frontend-loading-contract, navigation-shell, csp-inline, cache-bust, eslint, static-sanity. All pass. 37 sabotage mutations, one at a time, all red.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Third pass on the review of PR #333. Blocker. The data-location answer said "Your documents and keys live on servers at Hetzner Nuremberg, Germany". The keys do not. Five places on the site promise the opposite: "Generated on your device, never sent" (index.html), "relay holds only ciphertext, never keys" and "No plaintext, no keys" (security.html), "we never hold decryption keys, anywhere" (trust.html), "The relay never sees plaintext and never holds a private key" (docs.html). Flattening a table into prose is how the word "keys" got in there, and it is the sentence a security reviewer would quote back at us. The answer now says the documents are there and that they are ciphertext, and it quotes docs.html for where the keys are not: Your documents live on servers at Hetzner Nuremberg, Germany, and they sit there as ciphertext. The relay never sees plaintext and never holds a private key. Your files stay under EU law and the GDPR, and no US provider is in the data path. Email goes out via Resend, as /privacy sets out. Pinned in both directions. The positive half is a pair, the quote and docs.html. The negative half is a loop over every sentence in the /help body: a sentence that mentions a key and a piece of infrastructure in the same breath must be denying it, and may never use a locative verb between the two. Sabotage: putting "and keys" back is red, "your keys are stored on the relay" is red, and "Your keys are kept on servers at Hetzner Nuremberg, and there is no US provider" is red as well, so a stray "no" elsewhere in the sentence does not buy a pass. Also in this commit, from the same review: - The gate against the pricing slogan and the one against sales vocabulary ran on the three answers only. Both now run on the whole /help body below </head>, so the line cannot come back through the lede, an article card or the footer. Sabotage on both: red. - Rebased on main for #332, which added two console.log lines at the end of tests/ui-truthfulness.test.mjs. No name collision; both sides kept. Tests: links, seo-contract, ui-truthfulness, site-claims, frontend-loading-contract, navigation-shell, csp-inline, cache-bust, eslint, static-sanity. All pass. 37 sabotage mutations, one at a time, all red.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
It also says what that exception costs the reader, in words rather than in
ours: the extensions encrypt on our server, which means we can read what
you upload through them until that is changed. "Treat those uploads as
relay-side" was the internal phrasing, and relay is exactly the word this
branch removed from the /trust hero. Neither hero uses it now, and a test
says so.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=656 and "Verify a document" at y=716.
The free plan is Community here too. A first version of this branch left
"ParaSign Free and ParaSend Free cost EUR 0" standing at r.448, because the
only check that forbade the old name was scoped to /about. That check now
covers all three pages, and the sitewide sweep in ui-truthfulness gained the
shape it was missing, so any page using it fails. The page description no
longer sells "relay architecture" either.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. All
four agree now, and the description no longer describes a lede the page
stopped carrying. Its plan sentence named two of the three paid
ParaSign tiers; it names all three, and both free tiers as Community.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the paid tiers. Twenty-four
sabotages, twenty-four red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 162 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0. At 390px all three pages have
scrollWidth === clientWidth === 390.
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
It also says what that exception costs the reader, in words rather than in
ours: the extensions encrypt on our server, which means we can read what
you upload through them until that is changed. "Treat those uploads as
relay-side" was the internal phrasing, and relay is exactly the word this
branch removed from the /trust hero. Neither hero uses it now, and a test
says so.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=656 and "Verify a document" at y=716.
The free plan is Community here too. A first version of this branch left
"ParaSign Free and ParaSend Free cost EUR 0" standing at r.448, because the
only check that forbade the old name was scoped to /about. That check now
covers all three pages, and the sitewide sweep in ui-truthfulness gained the
shape it was missing, so any page using it fails. The page description no
longer sells "relay architecture" either.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. All
four agree now, and the description no longer describes a lede the page
stopped carrying. Its plan sentence named two of the three paid
ParaSign tiers; it names all three, and both free tiers as Community.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the paid tiers. Twenty-four
sabotages, twenty-four red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 162 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0. At 390px all three pages have
scrollWidth === clientWidth === 390.
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
It also says what that exception costs the reader, in words rather than in
ours: the extensions encrypt on our server, which means we can read what
you upload through them until that is changed. "Treat those uploads as
relay-side" was the internal phrasing, and relay is exactly the word this
branch removed from the /trust hero. Neither hero uses it now, and a test
says so.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=656 and "Verify a document" at y=716.
The free plan is Community here too. A first version of this branch left
"ParaSign Free and ParaSend Free cost EUR 0" standing at r.448, because the
only check that forbade the old name was scoped to /about. That check now
covers all three pages, and the sitewide sweep in ui-truthfulness gained the
shape it was missing, so any page using it fails. The page description no
longer sells "relay architecture" either.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. All
four agree now, and the description no longer describes a lede the page
stopped carrying. Its plan sentence named two of the three paid
ParaSign tiers; it names all three, and both free tiers as Community.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the paid tiers. Twenty-four
sabotages, twenty-four red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 162 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0. At 390px all three pages have
scrollWidth === clientWidth === 390.
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
…araSign Three pages, one shape, taken from docs/brand/messaging.md: what you can do here, who it is for, the split with its real number, who is behind it, then the proof and the honest limits. The algorithm names moved to the bottom of every page, where they are the reason a plain sentence above is true. /parasend is new. ParaSign has had a page since #325; ParaSend had nothing, so the send half of the product could not be found by name. It follows the /parasign pattern the guide asks for. What changed against the review, per page. /parasign - H1 is the one the guide specifies: "Sign documents in your browser, prove it years later." The old H1 was the product name, which does not say what the page is for. - The opening paragraph says what a buyer gets, in two sentences and 160 characters, and no longer opens on ML-DSA-65 and a transparency log. The guide's own tone rule keeps cryptography below the fold; the sentence it specifies for this page contradicted that rule, so the sentence now sits verbatim in the proof block at 04 instead of in the hero. - The buyer is named in the first screen: legal, finance and healthcare practices in the EU, the same audience index.html states. - The eIDAS status moved from 6,386px to 737px. A lawyer asks it first; the page now answers it before the tiers instead of on screen 8 of 9. - The free promise carries its number. "Free forever" became "Free on the Community plan: 2 signatures a month, no card, forever." - "Zero-knowledge" is gone from the scope note. It described nothing this page can point at, and it sat next to the most honest paragraph on the page. - The proof block quotes /about word for word and carries the EU claim in the form #328 settled: no US provider in the data path, with Resend named in the same breath. /parasend - Section 02, the section that has to convince, said AES-256-GCM, ciphertext, RAM, ML-KEM-768, tenant and RAM budget. It now says what the buyer gets. The algorithm names are in 06, each next to the page that checks it. - The free promise carries its limits: links that last an hour, gone after one read, 10 uploads an hour. - The bridge sentence explaining that Community is listed as Free is gone, and the tier card is named Community. #328 renamed the tier on /pricing, so there is nothing left to explain away. - The founder block quotes /about instead of composing a sentence about US subscriptions. #332 put that sentence on /about, so it is now sourced. /sign - "Private key" was the last jargon in the first screenful. Same fact, words a practice manager already uses. One layout fix, page-local. At 390px the house .sec-head keeps the section number in its own grid column, which left the H1 about 160px to wrap in: six lines of headline on /parasign, and the buttons and the eIDAS note off the first screen. On a narrow screen the number now stacks above the headline. design-system.css is untouched, because it is shared with pages this PR does not open. Measured at 390px with Playwright, per page: no horizontal overflow anywhere (scrollWidth 390), and on /parasign the H1, the audience, both buttons, the free promise and the eIDAS note all land inside the first 844px.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Two gates that looked like gates and were not, both found by sabotage rather
than by reading.
1. The monthly price on both product pages was pinned by nothing.
relay/test/pricing-page.test.js asserted with a bare substring, so
includes('€49') was satisfied by the annual "€499 excl." standing on
the same card, and includes('€15') by "€150". Verified: €49 to
€59 on /parasign and €15 to €19 on /parasend both stayed green.
Those are the two numbers a buyer clicks. An amount now has to end where it
says it ends and sit on the card of the plan it belongs to; the opening line
"business plans from €49 a month" can no longer stand in for the tier.
Both sabotages go red after this, and so do the annual amounts.
2. A claim that has to be read in the first screen was asserted against the
whole file, which is satisfied by screen 8 of 9. The eIDAS scope note, the
audience line and the free promise with its number are now asserted against the
hero section of the page, not against the file.
Also pinned, each one a sentence that had drifted or had no source:
- The SLA figure is read off /sla by name (the Enterprise cell, not the first
.uptime on the page) and every page repeating it has to match. This is how
"SLA 99.9%" reached a product page while /pricing and /sla both published
99.95%: the quota lines were pinned, the service lines were not.
- The EU claim in the form #328 settled: "No US provider in the data path"
with the Resend exception in the same breath, on /, /parasign and /parasend.
The broader "no US company" wording is refused on the product pages;
section 9 of the guide holds it open, and it stays on /security where the
table qualifies it.
- The give-back sentence, now that #332 has put it on /about, quoted rather
than composed.
- The free plan is called Community on /sign too, and "Free accounts" is
refused there.
The stale string is gone as well: the suite pinned "The community tier stays
free", a sentence #328 removed from /pricing. It now pins what /pricing
actually ships.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
…araSign Three pages, one shape, taken from docs/brand/messaging.md: what you can do here, who it is for, the split with its real number, who is behind it, then the proof and the honest limits. The algorithm names moved to the bottom of every page, where they are the reason a plain sentence above is true. /parasend is new. ParaSign has had a page since #325; ParaSend had nothing, so the send half of the product could not be found by name. It follows the /parasign pattern the guide asks for. What changed against the review, per page. /parasign - H1 is the one the guide specifies: "Sign documents in your browser, prove it years later." The old H1 was the product name, which does not say what the page is for. - The opening paragraph says what a buyer gets, in two sentences and 160 characters, and no longer opens on ML-DSA-65 and a transparency log. The guide's own tone rule keeps cryptography below the fold; the sentence it specifies for this page contradicted that rule, so the sentence now sits verbatim in the proof block at 04 instead of in the hero. - The buyer is named in the first screen: legal, finance and healthcare practices in the EU, the same audience index.html states. - The eIDAS status moved from 6,386px to 737px. A lawyer asks it first; the page now answers it before the tiers instead of on screen 8 of 9. - The free promise carries its number. "Free forever" became "Free on the Community plan: 2 signatures a month, no card, forever." - "Zero-knowledge" is gone from the scope note. It described nothing this page can point at, and it sat next to the most honest paragraph on the page. - The proof block quotes /about word for word and carries the EU claim in the form #328 settled: no US provider in the data path, with Resend named in the same breath. /parasend - Section 02, the section that has to convince, said AES-256-GCM, ciphertext, RAM, ML-KEM-768, tenant and RAM budget. It now says what the buyer gets. The algorithm names are in 06, each next to the page that checks it. - The free promise carries its limits: links that last an hour, gone after one read, 10 uploads an hour. - The bridge sentence explaining that Community is listed as Free is gone, and the tier card is named Community. #328 renamed the tier on /pricing, so there is nothing left to explain away. - The founder block quotes /about instead of composing a sentence about US subscriptions. #332 put that sentence on /about, so it is now sourced. /sign - "Private key" was the last jargon in the first screenful. Same fact, words a practice manager already uses. One layout fix, page-local. At 390px the house .sec-head keeps the section number in its own grid column, which left the H1 about 160px to wrap in: six lines of headline on /parasign, and the buttons and the eIDAS note off the first screen. On a narrow screen the number now stacks above the headline. design-system.css is untouched, because it is shared with pages this PR does not open. Measured at 390px with Playwright, per page: no horizontal overflow anywhere (scrollWidth 390), and on /parasign the H1, the audience, both buttons, the free promise and the eIDAS note all land inside the first 844px.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Two gates that looked like gates and were not, both found by sabotage rather
than by reading.
1. The monthly price on both product pages was pinned by nothing.
relay/test/pricing-page.test.js asserted with a bare substring, so
includes('€49') was satisfied by the annual "€499 excl." standing on
the same card, and includes('€15') by "€150". Verified: €49 to
€59 on /parasign and €15 to €19 on /parasend both stayed green.
Those are the two numbers a buyer clicks. An amount now has to end where it
says it ends and sit on the card of the plan it belongs to; the opening line
"business plans from €49 a month" can no longer stand in for the tier.
Both sabotages go red after this, and so do the annual amounts.
2. A claim that has to be read in the first screen was asserted against the
whole file, which is satisfied by screen 8 of 9. The eIDAS scope note, the
audience line and the free promise with its number are now asserted against the
hero section of the page, not against the file.
Also pinned, each one a sentence that had drifted or had no source:
- The SLA figure is read off /sla by name (the Enterprise cell, not the first
.uptime on the page) and every page repeating it has to match. This is how
"SLA 99.9%" reached a product page while /pricing and /sla both published
99.95%: the quota lines were pinned, the service lines were not.
- The EU claim in the form #328 settled: "No US provider in the data path"
with the Resend exception in the same breath, on /, /parasign and /parasend.
The broader "no US company" wording is refused on the product pages;
section 9 of the guide holds it open, and it stays on /security where the
table qualifies it.
- The give-back sentence, now that #332 has put it on /about, quoted rather
than composed.
- The free plan is called Community on /sign too, and "Free accounts" is
refused there.
The stale string is gone as well: the suite pinned "The community tier stays
free", a sentence #328 removed from /pricing. It now pins what /pricing
actually ships.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
It also says what that exception costs the reader, in words rather than in
ours: the extensions encrypt on our server, which means we can read what
you upload through them until that is changed. "Treat those uploads as
relay-side" was the internal phrasing, and relay is exactly the word this
branch removed from the /trust hero. Neither hero uses it now, and a test
says so.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=656 and "Verify a document" at y=716.
The free plan is Community here too. A first version of this branch left
"ParaSign Free and ParaSend Free cost EUR 0" standing at r.448, because the
only check that forbade the old name was scoped to /about. That check now
covers all three pages, and the sitewide sweep in ui-truthfulness gained the
shape it was missing, so any page using it fails. The page description no
longer sells "relay architecture" either.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. #334
then rewrote every head on the site, so the literal strings belong there and
tests/seo-contract.test.mjs pins them. What this branch pins is the
relation: the title, og:title, twitter:title and the JSON-LD name must name
the page the same, and that name must contain the words the H1 uses.
Punctuation and case are not the point; Transparency versus Verification
was. Its plan sentence named two of the three paid
ParaSign tiers; it names all three, and both free tiers as Community.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the paid tiers. Twenty-five
sabotages, twenty-five red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 162 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0. At 390px all three pages have
scrollWidth === clientWidth === 390.
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
It also says what that exception costs the reader, in words rather than in
ours: the extensions encrypt on our server, which means we can read what
you upload through them until that is changed. "Treat those uploads as
relay-side" was the internal phrasing, and relay is exactly the word this
branch removed from the /trust hero. Neither hero uses it now, and a test
says so.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=656 and "Verify a document" at y=716.
The free plan is Community here too. A first version of this branch left
"ParaSign Free and ParaSend Free cost EUR 0" standing at r.448, because the
only check that forbade the old name was scoped to /about. That check now
covers all three pages, and the sitewide sweep in ui-truthfulness gained the
shape it was missing, so any page using it fails. The page description no
longer sells "relay architecture" either.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. #334
then rewrote every head on the site, so the literal strings belong there and
tests/seo-contract.test.mjs pins them. What this branch pins is the
relation: the title, og:title, twitter:title and the JSON-LD name must name
the page the same, and that name must contain the words the H1 uses.
Punctuation and case are not the point; Transparency versus Verification
was. Its plan sentence named two of the three paid
ParaSign tiers; it names all three, and both free tiers as Community.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the paid tiers. Twenty-six
sabotages, twenty-six red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 162 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0. At 390px all three pages have
scrollWidth === clientWidth === 390.
Two things this branch had to touch on main's side
tests/ui-truthfulness.test.mjs did not parse on main: #336 and #339 each
landed a const named pricingVisible in the same module, for two different
values. The one #339 added is renamed to pricingText, with a comment saying
why. Without it nothing in this file runs, this branch included.
tests/site-claims.test.mjs block 12 read the /pricing tier cards by their
section heading. #336 renamed both headings and put ParaSign first, so the
split now finds them by product prefix and orders them by position.
Not touched, and still broken on main: relay/test/pricing-page.test.js r.498
declares tiers twice, so eslint cannot parse it. It is outside these three
pages and outside this PR.
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
It also says what that exception costs the reader, in words rather than in
ours: the extensions encrypt on our server, which means we can read what
you upload through them until that is changed. "Treat those uploads as
relay-side" was the internal phrasing, and relay is exactly the word this
branch removed from the /trust hero. Neither hero uses it now, and a test
says so.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=656 and "Verify a document" at y=716.
The free plan is Community here too. A first version of this branch left
"ParaSign Free and ParaSend Free cost EUR 0" standing at r.448, because the
only check that forbade the old name was scoped to /about. That check now
covers all three pages, and the sitewide sweep in ui-truthfulness gained the
shape it was missing, so any page using it fails. The page description no
longer sells "relay architecture" either.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. #334
then rewrote every head on the site, so the literal strings belong there and
tests/seo-contract.test.mjs pins them. What this branch pins is the
relation: the title, og:title, twitter:title and the JSON-LD name must name
the page the same, and that name must contain the words the H1 uses.
Punctuation and case are not the point; Transparency versus Verification
was. Its plan sentence named two of the three paid
ParaSign tiers; it names all three, and both free tiers as Community.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the paid tiers. Twenty-six
sabotages, twenty-six red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 162 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0. At 390px all three pages have
scrollWidth === clientWidth === 390.
Three things this branch had to touch on main's side
tests/ui-truthfulness.test.mjs did not parse on main: #336 and #339 each
landed a const named pricingVisible in the same module, for two different
values. The one #339 added is renamed to pricingText, with a comment saying
why. Without it nothing in this file runs, this branch included.
tests/site-claims.test.mjs block 12 read the /pricing tier cards by their
section heading. #336 renamed both headings and put ParaSign first, so the
split now finds them by product prefix and orders them by position.
relay/test/pricing-page.test.js r.498 required ../lib/tiers a second time,
under a name the file already binds at r.18. That is a SyntaxError, and it
took down two CI checks on every PR: "static, every name must exist" (eslint
cannot parse the file) and "relay - unit suite". The duplicate line is
removed; the binding at the top of the file is the same module. This was
outside the three pages, but no PR can go green while it stands.
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
It also says what that exception costs the reader, in words rather than in
ours: the extensions encrypt on our server, which means we can read what
you upload through them until that is changed. "Treat those uploads as
relay-side" was the internal phrasing, and relay is exactly the word this
branch removed from the /trust hero. Neither hero uses it now, and a test
says so.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=656 and "Verify a document" at y=716.
The free plan is Community here too. A first version of this branch left
"ParaSign Free and ParaSend Free cost EUR 0" standing at r.448, because the
only check that forbade the old name was scoped to /about. That check now
covers all three pages, and the sitewide sweep in ui-truthfulness gained the
shape it was missing, so any page using it fails. The page description no
longer sells "relay architecture" either.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. #334
then rewrote every head on the site, so the literal strings belong there and
tests/seo-contract.test.mjs pins them. What this branch pins is the
relation: the title, og:title, twitter:title and the JSON-LD name must name
the page the same, and that name must contain the words the H1 uses.
Punctuation and case are not the point; Transparency versus Verification
was. Its plan sentence named two of the three paid
ParaSign tiers; it names all three, and both free tiers as Community.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the paid tiers. Twenty-seven
sabotages, twenty-seven red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 173 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0, bron-seo/apply_seo_head.py --check
reports 0 pages, and tests/static-sanity.sh is PASS on all eleven checks,
including #362's new test-scope guard. At 390px all three pages have
scrollWidth === clientWidth === 390.
Following main through four parallel merges
#359 landed the deduplication this branch was carrying (the second const
tiers in relay/test/pricing-page.test.js, and pricingVisible renamed to
pricingText), so both local fixes are dropped in favour of main's.
This branch's own block in tests/ui-truthfulness.test.mjs now sits inside a
bare block scope and declares nothing at module level. Four PRs merged into
that file in parallel on 2 September and two of them collided on a top-level
const, which is a SyntaxError: not one assertion in the file runs, on any
branch. A block that declares nothing at module level cannot do that to the
next branch.
tests/site-claims.test.mjs block 12 stopped spelling the units itself. #336
renamed both /pricing section headings and put ParaSign first, and #359
reworded "2 signatures per month" to "2 signatures a month". The block now
finds the headings by product prefix, orders them by position, and lifts each
fact out of the card as a whole phrase, so /about repeats what /pricing says
rather than what this file guesses /pricing says. /about follows the new
wording: "2 signatures a month", "24 hour link expiry", "up to 10 reads per
link".
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The three pages a buyer reaches after the homepage were written for someone
who already believes the product. /about opened on the mission and put the
founder in section 03, below the cryptography. /security opened on defence in
depth and kept the one row a buyer came for, the jurisdiction table, seven
screens down. /trust never said who it was for.
They now run the order docs/brand/messaging.md fixes: what this is, who it is
for, who is behind it, a next step, then the proof including the honest
limits. Copy, hierarchy and order only. No restyle. index.html, apply-nav.py
and js/nav-auth.js are untouched.
/about is the founder page.
The lede is plain language: sign and send documents so only you and the
recipient can read them, so anyone can check later that the document is
genuine, on servers in Germany under EU law. Under it, in the first phone
screen, who it is for, then Mick Beer with the title the guide fixes, then
two buttons. Measured at 390x844: the founder sits at y=463 and the second
button at y=608. The section number "00" is hidden in the mobile override
instead of landing under the H1 as a stray number.
Two sentences are gone. "The cryptography is post-quantum, which is the
proof that it still holds up in ten years" was not a proof and not
checkable, on the page whose argument is that everything on it is
checkable. The founder paragraph explained the free plan with a
jurisdiction claim ("should not depend on a US subscription"), which the
guide forbids beside his name. In its place stands the paragraph #332
landed on main while this branch was in review: the Community plan is his
way of giving something back to society, the business plans pay for it,
that is the whole arrangement, and it is why the Community plan is not a
trial and has no end date. Taken from main verbatim, moved with the section
into the top half, and pinned so the two copies cannot drift.
The tier block names the free plan Community, which is what /pricing prints
on the card since #328.
/security answers "why would I trust you" before it answers "how it works".
The promise carries its own scope. It read "even if our own server is
broken into, nobody can read your documents" flat out, while ten screens
lower the page says the Chromium and Outlook extensions take a server-side
encryption path. For an extension user the flat version is untrue today, so
the exception now travels with the promise, in the hero.
It also says what that exception costs the reader, in words rather than in
ours: the extensions encrypt on our server, which means we can read what
you upload through them until that is changed. "Treat those uploads as
relay-side" was the internal phrasing, and relay is exactly the word this
branch removed from the /trust hero. Neither hero uses it now, and a test
says so.
The first screen also carries who is behind the page (Paramantis Solutions
B.V., Harderwijk, KvK 42115132, and the founder line) and the next step.
The buttons used to sit at roughly y=11400 on a phone; "See pricing" is now
at y=656 and "Verify a document" at y=716.
The free plan is Community here too. A first version of this branch left
"ParaSign Free and ParaSend Free cost EUR 0" standing at r.448, because the
only check that forbade the old name was scoped to /about. That check now
covers all three pages, and the sitewide sweep in ui-truthfulness gained the
shape it was missing, so any page using it fails. The page description no
longer sells "relay architecture" either.
The audit block says what /docs#audits actually adds up to: three external
audits in April 2026, two by R. Zwarts and one by Ryan Williams of Smart
Cyber Solutions, forty findings, four of them critical, with the resolving
commits in the table. The previous round claimed "the audit reports
themselves are not published" and pinned it. That was false:
docs/security-audit-2026-04.md is the full Smart Cyber Solutions writeup
and it ships in the site tree. Only the raw pentest output is missing,
which is what that document itself calls the raw report. Both pages now say
that, and link the report.
The CLOUD Act row and the EU-law card move to the data-path wording, as
section 9.2 of the guide requires: no US provider in the data path, with
Resend named as the one exception in the same breath. The old row read "not
applicable: no US infrastructure, no US company", which is broader than
/privacy allows.
/trust names its reader, then gives that reader somewhere to go.
The hero addresses organisations running their own relay and anyone
checking a supplier, and now offers them two buttons instead of one text
link mid-paragraph (y=416 and y=476). The first sentence under the hero no
longer says "the operator who runs the relay": relay is not a word a
supplier reviewer knows.
The page called itself Trust & Verification in its title and H1 while the
social card and the structured data still said Trust & Transparency. #334
then rewrote every head on the site, so the literal strings belong there and
tests/seo-contract.test.mjs pins them. What this branch pins is the
relation: the title, og:title, twitter:title and the JSON-LD name must name
the page the same, and that name must contain the words the H1 uses.
Punctuation and case are not the point; Transparency versus Verification
was. Its plan sentence named two of the three paid
ParaSign tiers; it names all three, and both free tiers as Community.
Tests
tests/ui-truthfulness.test.mjs pins each of the above, and each one was
sabotaged in place to confirm it goes red: the ten-year promise, the
give-back sentence, the US-subscription framing, the Community rename, the
CLOUD Act row, the Resend exception dropped from the card, the finding
counts, the "reports not published" sentence, the auditor names on
/security as well as /trust, the two hero buttons on each page, the
who-is-behind line, the bounded promise, the /trust og:title and JSON-LD
name, the jargon in the first screen, and the paid tiers. Twenty-seven
sabotages, twenty-seven red, no gaps.
tests/site-claims.test.mjs block 11 reads the numbers out of the /pricing
tier card that owns them and requires /about to repeat them; it follows the
Community rename and now also forbids "ParaSign Free" on /about.
node --test over the CI glob: 173 pass, 0 fail. check-csp-inline,
check-cache-bust and eslint exit 0, bron-seo/apply_seo_head.py --check
reports 0 pages, and tests/static-sanity.sh is PASS on all eleven checks,
including #362's new test-scope guard. At 390px all three pages have
scrollWidth === clientWidth === 390.
Following main through four parallel merges
#359 landed the deduplication this branch was carrying (the second const
tiers in relay/test/pricing-page.test.js, and pricingVisible renamed to
pricingText), so both local fixes are dropped in favour of main's.
This branch's own block in tests/ui-truthfulness.test.mjs now sits inside a
bare block scope and declares nothing at module level. Four PRs merged into
that file in parallel on 2 September and two of them collided on a top-level
const, which is a SyntaxError: not one assertion in the file runs, on any
branch. A block that declares nothing at module level cannot do that to the
next branch.
tests/site-claims.test.mjs block 12 stopped spelling the units itself. #336
renamed both /pricing section headings and put ParaSign first, and #359
reworded "2 signatures per month" to "2 signatures a month". The block now
finds the headings by product prefix, orders them by position, and lifts each
fact out of the card as a whole phrase, so /about repeats what /pricing says
rather than what this file guesses /pricing says. /about follows the new
wording: "2 signatures a month", "24 hour link expiry", "up to 10 reads per
link".
Still open, deliberately
The eIDAS level (SES on /about, advanced (AES) in the /pricing FAQ) is a
real contradiction and needs a decision, not a copy edit. This branch stops
it spreading and pins that it stays on the one page that has always carried
it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebased onto
mainat4ccee0c. One commit, eight files.The earlier run failed
relay - crypto suiteonrelay/test/billing-stance-boot, which this branch does not touch: the diffcontains no
relay/file at all. The branch was sitting on2329aa4and missed#342,
fix(relay): the bugs the critical-path tests found, which is the fix.Rebasing picked it up. For completeness the same test fails 4/4 on unmodified
origin/mainin my checkout as well, because the relay cannot boot there withoutthe native
@paramant/coredependency that CI installs separately, so a localgreen was never available to confirm it either way.
That push also cleared a stale merge base: while the PR was retargeted from
feat/homepage-kopertomain, GitHub kept reporting 53 changed files andattributed 224/300 lines of
index.htmlto this PR. Its own compare API saidahead 1, behind 0, 8 filesthroughout. The new head SHA forced therecomputation and the PR now reports 8.
Review points, each with its evidence
1. Base and CI.
git rebase --onto origin/main origin/feat/homepage-koper.Zero conflicts: #328 was squash-merged, so my branch is
origin/mainplus onecommit and
git merge-base origin/main HEADis the current main tip.index.htmlandpararules.htmlare not in the diff, so the Resend disclosureand the corrected EU claim are untouched. Base is now
mainand the full suiteruns on this PR.
2. The give-back sentence now has a source. It was on the dashboard but not
on /about, so it was unsourced.
frontend/about.html, section"Behind Paramant", now carries one sentence in Mick's words: the Community plan
is his way of giving something back to society; the business plans pay for it.
The dashboard and account bands reuse that wording.
The founder gate is genuinely two-way now:
FOUNDER_REQUIRED = ['index', 'dashboard', 'account'], noif (includes)gate. Delete the sentence and the suite goes red.
what forced the band's wording to match /about rather than paraphrase it: the
first draft said "gives back to society, paid for by" and the gate rejected
givesandpaid.Sabotage: title swapped to "award winning cryptographer" → red. Sentence deleted
from dashboard → red. Sentence deleted from account → red.
3. Neither gate was broken. Checked rather than assumed:
git diff origin/main...HEAD -- tests/ui-truthfulness.test.mjs | grep '^-'removes exactly five lines, all of them one stale comment about /pricing selling
Free. Nothing was removed from
TIER_NAME_SHAPES,tierNameHits,SANCTIONED_TITLEor theABOUT_WORDSfilter. Both are live on this branch:putting "Everything in Free" on the dashboard → red; adding "cryptographer,"
beside his name on /account → red.
4. Behaviour instead of strings. The
assert.doesNotMatchoncurrent_plan !== 'community'is gone.tests/user-dashboard-documents.test.mjsnow drives /account in Chromium across six plan shapes and reads the plan
chip, the Current plan row, the Active badge, the Cancel button and which band
is visible:
communityplan_parasign: 'free'(ParaSign floor)plan_parasend: 'community'(ParaSend floor)plan_parasign: 'platinum'(unknown)plan_parasign: 'pro', period runningplan_parasign: 'pro', period lapsedSabotage, all red: expiry
>=flipped to<in account.inline1.js; the sameflip in dashboard.js;
const free = false;const free = true; the oldone-string gate restored; the paid ladder widened so an unknown tier unlocks a
subscription.
One finding while doing this. My first attempt added
PRODUCT_FLOORS = { free, community }and the sabotage did not go red: with a combined ladder,indexOf(t) < 1already caught both floor words, so the map was dead code.paidProductTier()now reads the three paid rungs instead of listing thefloors, which fails closed. A floor word, a renamed tier and a typo all come out
unpaid, and the last two rows of the table pin it.
5. The EUR 15 card is Pro. Business is EUR 299. The answer now reads
"Paid plans start at EUR 15 a month excl. btw, which is ParaSend Pro."
6. One story about ParaSend.
relay.jsdecrementsviews_remainingandburns at zero, so the card says the file is gone the moment it has been read,
matching the dashboard hero and the homepage rules grid. "It expires by itself"
was a second, softer story for the same mechanism.
7. Verification is not unconditional.
verify.htmlsays a legacy v1/v2envelope can only be checked by the relay with an API key. The answer now reads
"Signed documents verify without an account. Older envelope formats need the
relay."
8. Comment corrected.
entitlements.jsgives ParaSend the floorcommunityand ParaSign the floorfree; they do not share one. Both files sayso now, and the code was restructured so the claim is load-bearing rather than
decorative (see point 4).
9. Order on a phone, measured.
getBoundingClientRect, 390x844, px fromthe top of the page.
scripts/shot-dashboard.mjsprints this on every run:main)The band came first and pushed both products past the 844px fold. Both actions
are now fully above it and the plan message follows them.
10. Jargon out of both bands. Gone: webhooks, exportable audit log, API
access, no IP rate limit, CT tree head as CSV or JSON, link expiry. What a
lawyer reads instead: "keep links open longer", "keep a record of what you sent",
"support with a name on it", "an audit trail you can export and hand over",
"a connection you can plug into your own systems". The exact feature names stay
on /pricing, where they are sold.
11. One step, one extension. The script writes
.jpgdirectly at 1x withtype: 'jpeg'. It used to write PNG while the body linked JPEG.Verification
CI on
f23e989: 11/11 green, includingrelay - crypto suite, which is theone that failed on the stale base, and
sign-e2e, which runs the browser suitesthis PR extends.
Green locally:
links,seo-contract,ui-truthfulness,frontend-loading-contract,navigation-shell,user-dashboard-documents(25 checks),
site-claims,cosign-appearance-contract,developer-parasign-dashboard,usage-purpose,check-csp-inline.sh,check-cache-bust.sh,static-sanity.sh,eslint .,check-commit-style.sh.tests/heartbeat-lib.test.mjsfails in my checkout for want of@noble/post-quantum, whichtest.ymlinstalls separately. It fails the sameway on unmodified
main, so it is environmental and not from this branch.Thirteen sabotages run in total across points 2, 3 and 4. All red, all restored.
Screenshots, 390px, full page
main)main)Unified plan
pro, granted rather than bought:The self-serve case: unified plan still
community, ParaSign tierprowith arunning period. Badge reads Pro, give-back band gone, paid band names only the
product bought, and /account finally shows the Active badge and Cancel button to
the person paying for them.
Images live on
review/dashboard-ingelogd-screenshots, which is not for merging.Nothing open
I flagged "Everything in Free" on the ParaSend Pro card in my previous report.
It is already fixed:
frontend/pricing.htmlline 261 reads "Everything inCommunity", corrected inside #328 itself (
0161740) after I read it. Thesite-wide sweep was right and there was nothing for it to catch.