Homepage speaks to a buyer: what it does, what it costs, why you can check it - #328
Merged
Conversation
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Mick's two content requirements for /parasign, plus the rebase onto main. The free plan is called Community, because that is what it is: a give-back, not a trial and not a funnel. The card says so in the founder's own terms (Mick Beer, privacy and security researcher at Paramantis Solutions B.V., the wording about.html already carries) and bridges to /pricing, where the same plan is listed as the tier named Free. PR #328 introduces the same Community wording on the homepage; whichever lands first, the bridge keeps both pages honest. The paid tiers are presented as what they are: business plans that pay for the free one. Names and amounts are lifted from /pricing (Pro 49, Business 299, Enterprise on request, with the incl-btw checkout amounts), and relay/test/pricing-page.test.js already ties every one of them to relay/lib/billing-catalog.js. The technique moved to section 04, under the heading that says it is evidence and not a pitch. ML-DSA-65, FIPS 204 and SHA3-256 no longer appear in the title, the description, the H1 area or the opening paragraph; first occurrence in the rendered page is now at character 4633 of 1280px body text, well past the plans. The hero says what the reader gets, the proof section says how to check it. Three new gates in relay/test/pricing-page.test.js, deliberately in that file rather than in ui-truthfulness.test.mjs, which #328 is rewriting: - saying Community obliges the page to name the /pricing tier it maps to, and obliges /pricing to still carry a tier named Free - every tier name printed on /parasign must be a tier /pricing sells - the founder line may claim only what /about claims, and naming him obliges the page to name the company registration Rebased onto main (#324 navigation, #326 billing stance, #330 signals), no conflicts. frontend/apply-nav.py stamped the seven-item nav shell, the Company/Legal footer and the design-system versions onto the page; a second run produces no diff. bron-seo/apply_seo_head.py re-stamped the JSON-LD for the new title and description. bron-seo/build_sitemap.py said the sitemap was out of date and regenerated it: one line, the lastmod of /vault, which #324 touched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Mick's two content requirements for /parasign, plus the rebase onto main. The free plan is called Community, because that is what it is: a give-back, not a trial and not a funnel. The card says so in the founder's own terms (Mick Beer, privacy and security researcher at Paramantis Solutions B.V., the wording about.html already carries) and bridges to /pricing, where the same plan is listed as the tier named Free. PR #328 introduces the same Community wording on the homepage; whichever lands first, the bridge keeps both pages honest. The paid tiers are presented as what they are: business plans that pay for the free one. Names and amounts are lifted from /pricing (Pro 49, Business 299, Enterprise on request, with the incl-btw checkout amounts), and relay/test/pricing-page.test.js already ties every one of them to relay/lib/billing-catalog.js. The technique moved to section 04, under the heading that says it is evidence and not a pitch. ML-DSA-65, FIPS 204 and SHA3-256 no longer appear in the title, the description, the H1 area or the opening paragraph; first occurrence in the rendered page is now at character 4633 of 1280px body text, well past the plans. The hero says what the reader gets, the proof section says how to check it. Three new gates in relay/test/pricing-page.test.js, deliberately in that file rather than in ui-truthfulness.test.mjs, which #328 is rewriting: - saying Community obliges the page to name the /pricing tier it maps to, and obliges /pricing to still carry a tier named Free - every tier name printed on /parasign must be a tier /pricing sells - the founder line may claim only what /about claims, and naming him obliges the page to name the company registration Rebased onto main (#324 navigation, #326 billing stance, #330 signals), no conflicts. frontend/apply-nav.py stamped the seven-item nav shell, the Company/Legal footer and the design-system versions onto the page; a second run produces no diff. bron-seo/apply_seo_head.py re-stamped the JSON-LD for the new title and description. bron-seo/build_sitemap.py said the sitemap was out of date and regenerated it: one line, the lastmod of /vault, which #324 touched.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
…at a buyer asks Builds on the dashboard work in #328. That branch renamed the badge to Free because /pricing has no tier called Community. The name is right, the direction was not: Community is the word relay/lib/tiers.js uses for the free row, the word /sla uses ("Community plan: no credit entitlement"), the word the account mail uses ("reverts to the Community plan"), and it is the one thing Paramant sells on. /pricing is the page that is out of step, and renaming it is a change of its own. So both signed-in pages say Community and, in the same band, name the /pricing tier it maps to, and a test holds that bridge in place until the pricing page catches up. Dashboard, top to bottom on a 390px screen: - The plan band names the plan, says whose gift it is in the words /about already uses for him, says what the business plans add, and carries one link to /pricing. Nothing else in the band is clickable. - A paying customer gets a different band: what his plan covers, quoted from /pricing, and a link to his own invoices. No link to a higher tier. Someone who already pays is a customer, not a lead. - The two products carry the screen. Request signatures and Send a file keep full size on a phone; signing alone is the same action in a smaller card below them. The desktop row is unchanged at three columns. - The ParaSend card says what happens when you click it in the buyer's words: encrypted in your browser, one link, expires by itself. Not held in RAM. - The three questions someone asks before he puts a real contract through this, each answered in one line that links to the page carrying the proof: price to /pricing, who can read it to /security, checking a signature to /verify. One line to the help centre under them. Account page, the same message where a customer goes looking for it: - Plan chip, the advanced-key row and Current plan all show the plan name, not the raw ID. It used to print "community", and "standard" for a record with no plan at all, which is a word no tier ladder contains. - The same two bands in Plan and billing, so the answer is the same on both pages. - The Active badge and the Cancel button no longer test for the single string 'community'. ParaSend's floor tier is 'community' and ParaSign's is 'free' (relay/lib/entitlements.js), so a free ParaSign account was offered a cancel button for a subscription it does not have. Tests, in tests/ui-truthfulness.test.mjs: - The two plan maps must agree with each other, so they cannot drift apart. - The free plan must be called Community, and relay/lib/tiers.js must really carry that row. - Every other name shown must be a tier /pricing sells. - Both pages must bridge Community to the Free tier by name. Drop this check when /pricing is renamed. - A founder claim on either page must already stand on /about. - The paid band may not link to /pricing. scripts/shot-dashboard.mjs serves frontend/ and stubs the account endpoints so the signed-in view can be photographed at 390px without a live relay.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Apolloccrypt
force-pushed
the
feat/homepage-koper
branch
from
September 2, 2026 14:26
b609fb0 to
cee3093
Compare
…check it The homepage read as a page for developers and cryptographers. The meta description opened with ML-KEM-768 + ML-DSA-65, the H1 was three verbs with no object, and the headings after it were 'Your documents', 'Sign and send, right in your browser', 'Drop post-quantum crypto into your stack' and 'Three ways in. One crypto core.' Ten calls to action, six ParaRules and a 'What's next' roadmap. Nothing on the page said what it is, who it is for, or what it costs. Rebuilt in the order a buyer reads it: what it is and for whom, the two products we actually sell, three steps, the real prices from /pricing, then the proof, then one line for developers. The crypto names moved out of the hero and into the trust section, where they answer a question instead of raising one. The trust section repeats four ParaRules verbatim, each with the verify link it already had. No new promise was added anywhere on the page. Two gates follow the change: - tests/ui-truthfulness.test.mjs pins the new homepage: no verified-signer or legally-binding claim, every 'no account' sentence scoped to the invited signer, and every price on the homepage must also stand on /pricing. - tests/navigation-shell.test.mjs expected three hero buttons and now expects one primary plus one secondary, with ParaSend checked in its own section. Nav and footer are untouched and restamped with frontend/apply-nav.py after the rebase onto the seven-item navigation. design-system.css is untouched, so no cache-bust version moves.
…email The homepage a customer sees after signing up is /dashboard, and on a phone it opened with the H1, a mission line, the email address a second time (the nav already shows it), and a badge reading COMMUNITY PLAN. Only after all of that came the first thing you can actually do. Three things were wrong rather than merely long: 1. COMMUNITY is a relay plan ID, not a tier. /pricing sells Free, Pro, Business and Enterprise and never says Community, so the one thing a customer wants to look up could not be found on the page that sells it. dashboard.js now maps the ID to the name /pricing uses, and a free plan gets one visible way up: an Upgrade link next to the badge. A paid plan does not see it. 2. The email was in the nav and again in the hero, above both product actions. The hero copy is gone. 3. The three start cards did not say which product they belong to, and the two flagship actions were split by a third. They now carry a ParaSign or ParaSend label matching the new homepage, and the two products lead: request signatures, then send a file that disappears, then sign alone. The mission line names the two products in the same words the homepage uses. tests/ui-truthfulness.test.mjs gains two assertions: every plan name the dashboard can show must be a tier /pricing actually sells, and the dashboard hero may not repeat the email address the nav already carries. The signed-in homepage state was aligned with the same vocabulary. Its three quick actions are unchanged, so navigation-shell keeps passing on that half.
Mick's own framing, and the one thing that separates Paramant from every other signing service: the Community plan is a contribution back to society, and the paid business plans are what makes that possible. Nothing else may stand in front of it, so it is the first section after the hero on the homepage and the first band a free account sees on the dashboard. Homepage, directly under the hero, two halves side by side: - Community, EUR 0. Free with no card and no time limit, and named as what it is on /pricing so the visitor can find it there: the tier called Free. Built by Mick Beer, privacy and security researcher and founder of Paramantis Solutions B.V., with the company details /about already carries. - Business plans, from EUR 15 a month. The tiers named exactly as /pricing names them, with what each adds: volume, control, accountability, own relay. Dashboard: a free account now gets the same message in the same words, with one upgrade link. A paying account never sees the band. The upgrade chip next to the plan badge was folded into it, so there is one route up and not two. The founder line says only what /about already says. No biography was invented. Tests: - tests/ui-truthfulness.test.mjs: a homepage that says Community must also name the /pricing tier it maps to, /pricing must actually carry that tier, every founder claim on the homepage must appear on /about, and naming the founder requires naming the company registration alongside him. - tests/user-dashboard-documents.test.mjs pinned two strings that changed on purpose. The mission line now names the two products in the homepage's words instead of 'Send, sign and prove important documents', and the start cards now lead with the two PRODUCTS, so ParaSend is second and signing alone is third. On a 390px screen the old order pushed ParaSend off the fold, which made the dashboard disagree with a homepage that sells two things.
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.
Rebased onto a main that gained the site-claims suite. Two of its ten gates disagreed with this branch, both because they pinned something this PR changes on purpose. Gate 5 pinned the tier name Free in two sentences on /privacy. The numbers it guards are unchanged and still read out of tiers.js; only the name moved, and the remaining Free on the retention line moved with it so /privacy does not carry two names for one plan. Gate 10 required the homepage to say 'N encrypted CLI tools'. A gate that forces a page to MAKE a claim is the wrong invariant, and this is the claim the July audit found unobtainable: paramant-solutions is private, so a visitor cannot get the tools, and the sentence came off the buyer homepage. Retargeted to what must actually stay true: any page stating a tool count must state the catalogue's real one, checked across every page under frontend/ rather than the homepage alone. Sabotage-checked in both directions: a page claiming 7 fails, a page claiming 10 passes. The pricing conflict from the rebase kept both sides: main's correction of the Enterprise SLA to 99.95 percent, and this branch's tier rename. The homepage quoted 99.9 percent in two places and now matches.
…xists Rebased onto a main that gained the /parasign page (#325). Two things followed. That page calls the free plan Community and then carried a bridge sentence, 'on the pricing page this plan is the tier named Free', with a gate in relay/test/pricing-page.test.js requiring it. The bridge existed only because /pricing disagreed with every other page. This branch renames the tier instead, so the sentence is gone and the gate now checks what actually has to hold: /pricing carries a tier named Community, carries no tier named Free, and /parasign does not explain the name away. A visitor who reads Community and goes looking for it on the pricing page finds it. The ui-truthfulness gate covers /parasign as well now, so all four pages that mention the plan are held to one name. /pricing linked to /docs#parasign, which is not an anchor on that page. The id is parasign-api. Swept every /docs# link on the site afterwards; that was the only broken one. Relay suite compared name by name against a stashed origin/main baseline: no new failures.
Apolloccrypt
force-pushed
the
feat/homepage-koper
branch
from
September 2, 2026 14:35
cee3093 to
4af78dd
Compare
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
…at a buyer asks Builds on the dashboard work in #328, which resolves plan names out of relay/lib/tiers.js and reads the per-product tiers. This adds the other half of the same rule and carries it to the account page. Dashboard, top to bottom on a 390px screen: - The plan band names the plan, says whose gift it is in the words /about already uses for him, says what the business plans add, and carries one link to /pricing. Nothing else in the band is clickable. The sentence explaining that /pricing called this tier Free is gone, because /pricing says Community. - A paying customer gets a different band: what his plan covers, per product, quoted from /pricing, and a link to his own invoices. No link to a higher tier. Someone who already pays is a customer, not a lead. It is per product because a self-serve purchase moves one ladder only, so a ParaSend customer is not told about a signature allowance he does not have. An account whose unified plan was granted by hand gets a plain sentence instead. - The two products carry the screen. Request signatures and Send a file keep full size on a phone; signing alone is the same action in a smaller card below them. The desktop row is unchanged at three columns. - The ParaSend card says what happens when you click it in the buyer's words: encrypted in your browser, one link, expires by itself. Not held in RAM. - The three questions someone asks before he puts a real contract through this, each answered in one line that links to the page carrying the proof: price to /pricing, who can read it to /security, checking a signature to /verify. One line to the help centre under them. Account page, the same message where a customer goes looking for it: - Plan resolution now has the shape dashboard.js uses: the canonical rows and aliases from tiers.js, plus the per-product ladders from entitlements.js. It used to print "community", and "standard" for a record with no plan at all, which is a word no tier ladder contains. - The Active badge and the Cancel button no longer test one string, current_plan !== 'community'. That both offered a free ParaSign account (floor tier 'free') a cancel button for a subscription it does not have, and hid the badge from a self-serve customer whose unified plan stayed community while his product tier moved. - The same two bands in Plan and billing, so the answer matches the dashboard. Tests, in tests/ui-truthfulness.test.mjs, on top of the gate from #328: - account.inline1.js must name every canonical row in tiers.js and fold every alias the same way, so the two resolvers cannot drift apart. - It may not decide "paying" by comparing against a single plan ID again. - Both pages must carry the paid band, and it may not link to /pricing. - The free band gets exactly one upgrade link, and may not explain a Free/Community mismatch that no longer exists. - A founder line is pinned in both directions: every piece must stand on /about, and the sentence naming him must read exactly the sanctioned one. The subset check alone did not bite, because swapping the real title for an invented one removes the phrase it was looking for. Each of these was checked by sabotage: break the thing, watch the suite go red, put it back. scripts/shot-dashboard.mjs serves frontend/ and stubs the account endpoints so the signed-in view can be photographed at 390px without a live relay, including the self-serve case where the unified plan is community and a product tier is not.
The two the reviewer named, plus five the first sweep missed because it grepped the source and these read as prose: a feature list, an FAQ answer, two rows of the API reference, the signing page and the terms twice. pricing.html Everything in Free -> Everything in Community pricing.html Free covers 2 signatures -> Community covers 2 signatures docs.html Free (pgp_) in the TTL table -> Community (pgp_) docs.html Free/community -> 403 -> Community -> 403 sign.html Free accounts sign 2 a month -> Community accounts sign 2 terms.html one hour on Free -> one hour on Community terms.html falls back to Free -> falls back to Community Found by rendering every page under frontend/ to visible text (comments, scripts, styles and tags stripped) and reading each remaining hit, rather than by grepping markup. Nine hits stay and all nine are correct English: 'Free to start', 'Free on the Community plan', BUSL's 'Free to use', the ot-brief's own Evaluation tier priced at Free, and two lines on /vs describing what WeTransfer and SFTP cost. No frontend script carries the word at all. A gate in tests/ui-truthfulness.test.mjs now walks every page and rejects the shapes that can only be a plan name, with /vs and the ot-brief exempt because they price someone else's product and their own Evaluation tier. Checked by reverting each of the seven fixes one at a time: all seven go red, and the competitor lines stay green. No new relay failures against a stashed origin/main baseline.
1. 'No US provider in the chain' was false. relay.js posts to api.resend.com in
three places (1577, 3421, 5438), and privacy.html already says Resend receives
the recipient address, the message and the complete personal link. The claim is
true of the data path and only of that, so the homepage now reads 'No US
provider in the data path' and names the email route with a link to /privacy.
The stronger version of the same sentence on /pararules ('No US CLOUD Act reach
over your data') is scoped the same way: files and keys never leave the EU and
are ciphertext everywhere but the browser, transactional email is the one
exception, and Resend never sees the document.
security.html listed Cloudflare as a third party. It is not one. Checked from
outside the network: paramant.app resolves via kiki.bunny.net and
coco.bunny.net, the A record points straight at Hetzner 116.203.86.81, and no
response carries a Cloudflare header. Naming a provider we do not use makes the
scope list wrong in both directions, so the list is now Resend, Hetzner, Bunny
and Mollie, and docs/migration-bunny.md moves off 'Planned for Q2 2026' to done
with what was measured and the date it was measured. The migration date itself
is not recorded, so it is not invented.
2. A coverage gap, not a bug. The expiry rule and the band toggle in
dashboard.js could both be deleted with every suite green, because the only
test on them inspects source. Five browser checks now drive the real page with
/api/user/me stubbed: Community shows the band, a valid paid ParaSign or
ParaSend tier hides it and reads Pro, an expired period falls back to Community,
and licensed reads Enterprise. Six sabotages, six reds.
3. Gate 10 in site-claims matched only the exact phrase of a claim this PR
removed, so it guarded nothing. Broadened to any count of CLI or command-line
tools, in digits or words. Zero matches stays allowed on purpose and the comment
says why: the '10 encrypted CLI tools' line came off the homepage because
paramant-solutions is private and a visitor cannot obtain the tools, and a gate
that forces the sentence back would force back an unobtainable claim.
4. The founder check had the shape 'if the page says X, /about must say X',
which a rewrite walks straight past: swapping the title deletes the string the
check looks for. It is pinned in both directions now. Every page that sells on
the founder must carry the exact title /about gives him, and the words in the
clause beside his name must all be words /about uses, so no extra credential
fits next to it. Three sabotages, three reds.
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.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
main moved while this branch was open. Rebased onto 99909a1 and folded what arrived into the CHANGELOG section, because a release section that is a snapshot of the moment it was written is the exact failure this PR is fixing. New in the section: the ParaSign product page at /parasign (#325), the messaging guide (#331), the homepage rewrite for a buyer (#328), the site claims pinned to the code that makes them true (#327), the heartbeat that cannot be green without evidence (#338), and the route suites that boot a real relay.js (#341). Count in the intro goes from 268 commits and 52 PRs to 277 and 58, and the intro now says it was rebased rather than pretending it was written in one pass. #341 is worth naming for what it is: point 3 of the toekomstbestendigheid report was that relay.js, 6488 lines and 68 routes, was loaded by no unit test at all. It is now loaded by the route suites. That point is not closed, but it is no longer zero. Two conflicts, both resolved toward main's newer structure: - product-heartbeat.yml: #338 moved the live job out into heartbeat.yml. Took main's file whole and applied the Node 24 bump to both files instead, so the bump follows the job rather than the filename. All seven node-version entries across the five workflows now read '24'. - test.yml: #341 added a second silent-suites gate for the route job and set both expected sets to empty. Kept main's exclusion lists and applied --test-reporter=tap to both steps. That second one matters more after the rebase than before. With a non-empty expected list, the spec reporter made the gate fail, which is how it was found. With an empty expected list, the spec reporter makes it PASS: the grep finds nothing, silent is empty, and a gate that can no longer see anything reports green. A dead gate that reports green is precisely what these two gates exist to prevent, so both now pin the reporter rather than inherit a Node default. Tests after the rebase, on Node 22 and again under node:24-alpine: relay 175, admin 40, root 145 (143 pass, 2 pre-existing skips), both silent-suite gates empty as expected. static-sanity PASS including the style guard, bash -n and eslint clean. The root job now runs npm ci first, per #338; tests/README.md and the local commands in docs/RELEASE.md match what CI does.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Second pass on the review of PR #333, rebased on main (#324, #327, #328, #331, #342). /docs - The buyer line is pinned to the visible paragraph. The old assertion matched the same words in four meta tags, so deleting the paragraph left the test green. Proven by sabotage, both ways. - The buyer gets a real button to /pricing beside Quick start, same size, same row. Quick start stays the primary CTA the messaging guide asks for; the pricing button is the outlined one. - Two sentences that ran on double colons now read as sentences, and the ADR range no longer uses an en-dash. /help - "What does it cost?" names the numbers /pricing prints: ParaSign Community free forever, no card, 2 signatures per month, and ParaSign Pro at 49 euro a month excl. btw (59.29 incl.) with 100 signatures. Each half is pinned to the card it was quoted from. - "Pay for volume, never for security" is off the support page. The fact behind it stays, quoted from /pricing: every plan gets the same encryption, the same post-quantum signatures and the same public proof log. A test now fails if the sales line comes back. - "Where does my data live?" is three readable sentences instead of a flattened compliance table: Hetzner Nuremberg, EU law and the GDPR, no US provider in the data path, and email via Resend as /privacy sets out. Scoped to the data path per proof 1 of the messaging guide, so the unqualified "no US company" row from /security is not repeated here while that contradiction is open (guide section 9). - The em-dash sweep on api-key-vs-totp and lost-authenticator now covers the H1, the tab title, the meta description and the body, not only the lede. A test pins all three help pages. /developer - The page is noindex and only reachable once signed in, so the lede addresses the developer reading it, not the buyer who sent them. The plan boundary for API access stays, and a test forbids the buyer phrasing coming back. Tests: links, seo-contract, ui-truthfulness, site-claims, frontend-loading-contract, navigation-shell, csp-inline, cache-bust, eslint and static-sanity all pass. Every new pin was sabotaged one at a time and went 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=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
…t screen A phone showed "Pricing", a decorative "00" and a paragraph about a post-quantum core. No amount, no product, and nothing about who holds the files. Rebased onto main, so #328's rename (Community, not Free), its founder paragraph and its /docs#parasign-api fix all stand; this builds the first screen on top of them. /pricing - The lead says what you buy before what it costs: sign documents, send files that vanish after one read. - The promise carries its own number. "Free forever" alone reads as generous until the table says two signatures a month; it now says "Community is €0 a month, forever: 2 signatures per month and 10 uploads per hour, no card" in the same breath. - Jargon out of the lead. "A dedicated relay" and "a connection to their own software" became "a server of their own" and "signing built into their own software". The cryptography sentence keeps doing its work under the tables. - Who is behind it moved from 1128px into the first screen: Mick Beer, with the exact title /about gives him, and KvK 42115132 beside it. - The decorative "00" over the h1 is gone. It meant nothing and cost the first 60px of the fold. - Every tier card says who it is for, in one line. ParaSign moved above ParaSend; it is the flagship and it was second. - The Community cards send a visitor to /signup instead of /dashboard, which is a page they cannot open yet. - The FAQ said "Signatures are advanced (AES), not qualified (QES)" while /about says Simple Electronic Signature. /about is right: a ParaSign signature is an SES under eIDAS, not AES and not QES. - "All tiers meet NIS2 and GDPR requirements by design" was a guarantee the same page withdraws four paragraphs later. It now says the architecture is built to support that work and that Paramant holds no third-party certification. - Layout: grid items default to min-width:auto and .btn is nowrap, so the longest CTA set the min-content width of the track. At 390px every card was 471px inside a 342px container. /signup names the free limit in the same words /pricing uses. billing/checkout says where checkout actually happens and that nothing is charged there. Tests. tests/pricing-fold.test.mjs measures the laid-out page: the bottom edge of the amount, the audience line, the founder line and the first action must fall inside 390x844, in that order. It reads text nodes rather than a list of block tags, so the kicker span under the h1 is covered too. Prices, limits and checkout links are untouched; relay/test/pricing-page.test.js still recomputes all 34 of them from the catalog.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Head elements only, on all 53 frontend pages: title, meta description, Open Graph, Twitter cards and JSON-LD. No body text, no styling. apply-nav.py and js/nav-auth.js are untouched. Rebased on main. Main's wording wins in every head it already writes to the messaging guide (#331): the homepage keeps the title, the description and the SoftwareApplication node #328 gave it, and the Organization description keeps "Dutch company, servers in Germany". This branch adds what main does not have: the founder, the legal entity and the address in the Organization node of every public page, and Open Graph and Twitter cards that match the title. The founder and the company are now in the description itself on /, /about and /pricing, not only in the JSON-LD no preview renders. Jargon is out of the sentence a buyer reads first. /verify says what it gets you instead of naming FIPS 204, /sign says the key stays on the device, and "relay" is gone from every title and every opening sentence except the four pages whose subject is the architecture. The free plan is called Community in the head as well, on /pricing and /signup. Three gates in tests/seo-contract.test.mjs: - title, og:title, twitter:title and the JSON-LD WebPage name are one sentence. /trust shipped three different names at once and nothing failed. - eight pages have their title and description pinned word for word, with the source of every claim named in the file. - no title or description carries a certification we do not hold, and none carries our own vocabulary. bron-seo/apply_seo_head.py reproduces every generated block exactly: "would change: 0 pages". Main drifted by one page before this commit, because #328 hand-edited the homepage JSON-LD the generator owns; the generator now carries that shape instead.
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
Second pass on the review of PR #333, rebased on main (#324, #327, #328, #331, #342). /docs - The buyer line is pinned to the visible paragraph. The old assertion matched the same words in four meta tags, so deleting the paragraph left the test green. Proven by sabotage, both ways. - The buyer gets a real button to /pricing beside Quick start, same size, same row. Quick start stays the primary CTA the messaging guide asks for; the pricing button is the outlined one. - Two sentences that ran on double colons now read as sentences, and the ADR range no longer uses an en-dash. /help - "What does it cost?" names the numbers /pricing prints: ParaSign Community free forever, no card, 2 signatures per month, and ParaSign Pro at 49 euro a month excl. btw (59.29 incl.) with 100 signatures. Each half is pinned to the card it was quoted from. - "Pay for volume, never for security" is off the support page. The fact behind it stays, quoted from /pricing: every plan gets the same encryption, the same post-quantum signatures and the same public proof log. A test now fails if the sales line comes back. - "Where does my data live?" is three readable sentences instead of a flattened compliance table: Hetzner Nuremberg, EU law and the GDPR, no US provider in the data path, and email via Resend as /privacy sets out. Scoped to the data path per proof 1 of the messaging guide, so the unqualified "no US company" row from /security is not repeated here while that contradiction is open (guide section 9). - The em-dash sweep on api-key-vs-totp and lost-authenticator now covers the H1, the tab title, the meta description and the body, not only the lede. A test pins all three help pages. /developer - The page is noindex and only reachable once signed in, so the lede addresses the developer reading it, not the buyer who sent them. The plan boundary for API access stays, and a test forbids the buyer phrasing coming back. Tests: links, seo-contract, ui-truthfulness, site-claims, frontend-loading-contract, navigation-shell, csp-inline, cache-bust, eslint and static-sanity all pass. Every new pin was sabotaged one at a time and went red.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Second pass on the review of PR #333, rebased on main (#324, #327, #328, #331, #342). /docs - The buyer line is pinned to the visible paragraph. The old assertion matched the same words in four meta tags, so deleting the paragraph left the test green. Proven by sabotage, both ways. - The buyer gets a real button to /pricing beside Quick start, same size, same row. Quick start stays the primary CTA the messaging guide asks for; the pricing button is the outlined one. - Two sentences that ran on double colons now read as sentences, and the ADR range no longer uses an en-dash. /help - "What does it cost?" names the numbers /pricing prints: ParaSign Community free forever, no card, 2 signatures per month, and ParaSign Pro at 49 euro a month excl. btw (59.29 incl.) with 100 signatures. Each half is pinned to the card it was quoted from. - "Pay for volume, never for security" is off the support page. The fact behind it stays, quoted from /pricing: every plan gets the same encryption, the same post-quantum signatures and the same public proof log. A test now fails if the sales line comes back. - "Where does my data live?" is three readable sentences instead of a flattened compliance table: Hetzner Nuremberg, EU law and the GDPR, no US provider in the data path, and email via Resend as /privacy sets out. Scoped to the data path per proof 1 of the messaging guide, so the unqualified "no US company" row from /security is not repeated here while that contradiction is open (guide section 9). - The em-dash sweep on api-key-vs-totp and lost-authenticator now covers the H1, the tab title, the meta description and the body, not only the lede. A test pins all three help pages. /developer - The page is noindex and only reachable once signed in, so the lede addresses the developer reading it, not the buyer who sent them. The plan boundary for API access stays, and a test forbids the buyer phrasing coming back. Tests: links, seo-contract, ui-truthfulness, site-claims, frontend-loading-contract, navigation-shell, csp-inline, cache-bust, eslint and static-sanity all pass. Every new pin was sabotaged one at a time and went red.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
…t screen A phone showed "Pricing", a decorative "00" and a paragraph about a post-quantum core. No amount, no product, and nothing about who holds the files. Rebased onto main, so #328's rename (Community, not Free), its founder paragraph and its /docs#parasign-api fix all stand; this builds the first screen on top of them. /pricing - The lead says what you buy before what it costs: sign documents, send files that vanish after one read. - The promise carries its own number. "Free forever" alone reads as generous until the table says two signatures a month; it now says "Community is €0 a month, forever: 2 signatures per month and 10 uploads per hour, no card" in the same breath. - The lead prices the two products separately: from €15 a month for sending (ParaSend Pro), from €49 for signing (ParaSign Pro). One figure for both anchored an office that came to sign on the cheaper product's price. Both amounts are read off their own Pro card by the test, and those cards are already bound to the catalog. - Jargon out of the lead. "A dedicated relay" and "a connection to their own software" became "a server of their own" and "signing built into their own software". The cryptography sentence keeps doing its work under the tables. - Who is behind it moved from 1128px into the first screen: Mick Beer, with the exact title /about gives him, and KvK 42115132 beside it. - The decorative "00" over the h1 is gone. It meant nothing and cost the first 60px of the fold. - Every tier card says who it is for, in one line. ParaSign moved above ParaSend; it is the flagship and it was second. - The Community cards send a visitor to /signup instead of /dashboard, which is a page they cannot open yet. - The FAQ said "Signatures are advanced (AES), not qualified (QES)" while /about says Simple Electronic Signature. /about is right: a ParaSign signature is an SES under eIDAS, not AES and not QES. - "All tiers meet NIS2 and GDPR requirements by design" was a guarantee the same page withdraws four paragraphs later. It now says the architecture is built to support that work and that Paramant holds no third-party certification. - Layout: grid items default to min-width:auto and .btn is nowrap, so the longest CTA set the min-content width of the track. At 390px every card was 471px inside a 342px container. /signup names the free limit in the same words /pricing uses. billing/checkout says where checkout actually happens and that nothing is charged there. Tests. tests/pricing-fold.test.mjs measures the laid-out page: the bottom edge of the amount, the audience line, the founder line and the first action must fall inside 390x844, in that order. It reads text nodes rather than a list of block tags, so the kicker span under the h1 is covered too. Prices, limits and checkout links are untouched; relay/test/pricing-page.test.js still recomputes all 34 of them from the catalog.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Head elements only: title, meta description, Open Graph, Twitter cards and JSON-LD on 54 of the 60 frontend pages. No body text, no styling. apply-nav.py and js/nav-auth.js are untouched, and no diff hunk in any of the 54 files falls after </head>. Rebased on main. Main's wording wins in every head it already writes to the messaging guide (#331): the homepage keeps the title, the description sentence and the SoftwareApplication node #328 gave it, and the Organization description keeps "Dutch company, servers in Germany". This branch adds what main does not have: the founder, the legal entity, the address and the KvK number in the Organization node of every public page, and Open Graph and Twitter cards that match the title. The legal entity is now in the description itself on /, /about and /pricing, not only in the JSON-LD no preview renders. The founder's name is in one description, /about, because that is the only one of the three where /about's own sentence backs it; on / and /pricing the description names Paramantis Solutions B.V. and the founder stays in the Organization node. Jargon is out of the sentence a buyer reads first. /verify says what it gets you instead of naming FIPS 204, and "relay" is gone from every title and every opening sentence except the four pages whose subject is the architecture. /sign says "the document text and your signing key never leave it", not "the file". In Request signatures the encrypted document does go to Paramant, which is how a recipient receives it. The plaintext and the key stay in the browser in all three modes; the file does not. /pricing names a floor per product, sending from 15 euro a month and signing from 49. An unsplit "from 15 euro" reads as if signing starts there. The free plan is called Community in the head as well, on /pricing and /signup. Three gates in tests/seo-contract.test.mjs: - title, og:title, twitter:title and the JSON-LD WebPage name are one sentence. /trust shipped three different names at once and nothing failed. - eight pages have their title and description pinned word for word, with the source of every claim named in the file. - no title or description carries a certification we do not hold, and none carries our own vocabulary. bron-seo/apply_seo_head.py reproduces every generated block exactly: "would change: 0 pages". Main drifted by one page before this commit, because #328 hand-edited the homepage JSON-LD the generator owns; the generator now carries that shape instead.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Head elements only: title, meta description, Open Graph, Twitter cards and JSON-LD on 54 of the 60 frontend pages. No body text, no styling. apply-nav.py and js/nav-auth.js are untouched, and no diff hunk in any of the 54 files falls after </head>. Rebased on main. Main's wording wins in every head it already writes to the messaging guide (#331): the homepage keeps the title, the description sentence and the SoftwareApplication node #328 gave it, and the Organization description keeps "Dutch company, servers in Germany". This branch adds what main does not have: the founder, the legal entity, the address and the KvK number in the Organization node of every public page, and Open Graph and Twitter cards that match the title. The legal entity is now in the description itself on /, /about and /pricing, not only in the JSON-LD no preview renders. The founder's name is in one description, /about, because that is the only one of the three where /about's own sentence backs it; on / and /pricing the description names Paramantis Solutions B.V. and the founder stays in the Organization node. Jargon is out of the sentence a buyer reads first. /verify says what it gets you instead of naming FIPS 204, and "relay" is gone from every title and every opening sentence except the four pages whose subject is the architecture. /sign says "the document text and your signing key never leave it", not "the file". In Request signatures the encrypted document does go to Paramant, which is how a recipient receives it. The plaintext and the key stay in the browser in all three modes; the file does not. /pricing names a floor per product, sending from 15 euro a month and signing from 49. An unsplit "from 15 euro" reads as if signing starts there. The free plan is called Community in the head as well, on /pricing and /signup. Three gates in tests/seo-contract.test.mjs: - title, og:title, twitter:title and the JSON-LD WebPage name are one sentence. /trust shipped three different names at once and nothing failed. - eight pages have their title and description pinned word for word, with the source of every claim named in the file. - no title or description carries a certification we do not hold, and none carries our own vocabulary. bron-seo/apply_seo_head.py reproduces every generated block exactly: "would change: 0 pages". Main drifted by one page before this commit, because #328 hand-edited the homepage JSON-LD the generator owns; the generator now carries that shape instead.
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
Head elements only: title, meta description, Open Graph, Twitter cards and JSON-LD on 54 of the 60 frontend pages. No body text, no styling. apply-nav.py and js/nav-auth.js are untouched, and no diff hunk in any of the 54 files falls after </head>. Rebased on main. Main's wording wins in every head it already writes to the messaging guide (#331): the homepage keeps the title, the description sentence and the SoftwareApplication node #328 gave it, and the Organization description keeps "Dutch company, servers in Germany". This branch adds what main does not have: the founder, the legal entity, the address and the KvK number in the Organization node of every public page, and Open Graph and Twitter cards that match the title. The legal entity is now in the description itself on /, /about and /pricing, not only in the JSON-LD no preview renders. The founder's name is in one description, /about, because that is the only one of the three where /about's own sentence backs it; on / and /pricing the description names Paramantis Solutions B.V. and the founder stays in the Organization node. Jargon is out of the sentence a buyer reads first. /verify says what it gets you instead of naming FIPS 204, and "relay" is gone from every title and every opening sentence except the four pages whose subject is the architecture. /sign says "the document text and your signing key never leave it", not "the file". In Request signatures the encrypted document does go to Paramant, which is how a recipient receives it. The plaintext and the key stay in the browser in all three modes; the file does not. /pricing names a floor per product, sending from 15 euro a month and signing from 49. An unsplit "from 15 euro" reads as if signing starts there. The free plan is called Community in the head as well, on /pricing and /signup. Three gates in tests/seo-contract.test.mjs: - title, og:title, twitter:title and the JSON-LD WebPage name are one sentence. /trust shipped three different names at once and nothing failed. - eight pages have their title and description pinned word for word, with the source of every claim named in the file. - no title or description carries a certification we do not hold, and none carries our own vocabulary. bron-seo/apply_seo_head.py reproduces every generated block exactly: "would change: 0 pages". Main drifted by one page before this commit, because #328 hand-edited the homepage JSON-LD the generator owns; the generator now carries that shape instead.
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
…t screen A phone showed "Pricing", a decorative "00" and a paragraph about a post-quantum core. No amount, no product, and nothing about who holds the files. Rebased onto main, so #328's rename (Community, not Free), its founder paragraph and its /docs#parasign-api fix all stand; this builds the first screen on top of them. /pricing - The lead says what you buy before what it costs: sign documents, send files that vanish after one read. - The promise carries its own number. "Free forever" alone reads as generous until the table says two signatures a month; it now says "Community is €0 a month, forever: 2 signatures per month and 10 uploads per hour, no card" in the same breath. - The lead prices the two products separately: from €15 a month for sending (ParaSend Pro), from €49 for signing (ParaSign Pro). One figure for both anchored an office that came to sign on the cheaper product's price. Both amounts are read off their own Pro card by the test, and those cards are already bound to the catalog. - The Community limits are the ones the relay enforces. The page sold "10 uploads per hour per IP", which is ANON_RATE_PER_HOUR on /v2/anon-inbound, deprecated 2026-05-28 with Sunset 2026-12-31. What actually stops an account is transfers_month 10 and file_mb 5 from relay/lib/tiers.js, refused with 402 and 413. The lead and the ParaSend cards now say "10 transfers per month, 5 MB per file", and ParaSend Pro says 500 transfers per month instead of "no IP rate limit", which was the same misdescription from the other side. - ParaSign's ParaShare claim matched no register entry. frontend/crypto-agility lists ParaShare with Default SIG "n/a" on a pre-v1 hybrid wire format, so "ML-DSA-65 signed receipts" is dropped for what the register says. - Jargon out of the lead. "A dedicated relay" and "a connection to their own software" became "a server of their own" and "signing built into their own software". The cryptography sentence keeps doing its work under the tables. - Who is behind it moved from 1128px into the first screen: Mick Beer, with the exact title /about gives him, and KvK 42115132 beside it. - The decorative "00" over the h1 is gone. It meant nothing and cost the first 60px of the fold. - Every tier card says who it is for, in one line. ParaSign moved above ParaSend; it is the flagship and it was second. - The Community cards send a visitor to /signup instead of /dashboard, which is a page they cannot open yet. - The FAQ said "Signatures are advanced (AES), not qualified (QES)" while /about says Simple Electronic Signature. /about is right: a ParaSign signature is an SES under eIDAS, not AES and not QES. - "All tiers meet NIS2 and GDPR requirements by design" was a guarantee the same page withdraws four paragraphs later. It now says the architecture is built to support that work and that Paramant holds no third-party certification. - Layout: grid items default to min-width:auto and .btn is nowrap, so the longest CTA set the min-content width of the track. At 390px every card was 471px inside a 342px container. /signup names the free limit in the same words /pricing uses. billing/checkout says where checkout actually happens and that nothing is charged there. Tests. tests/pricing-fold.test.mjs measures the laid-out page: the bottom edge of the amount, the audience line, the founder line and the first action must fall inside 390x844, in that order. It reads text nodes rather than a list of block tags, so the kicker span under the h1 is covered too. Prices, limits and checkout links are untouched; relay/test/pricing-page.test.js still recomputes all 34 of them from the catalog.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Head elements only: title, meta description, Open Graph, Twitter cards and JSON-LD on 54 of the 60 frontend pages. No body text, no styling. apply-nav.py and js/nav-auth.js are untouched, and no diff hunk in any of the 54 files falls after </head>. Rebased on main. Main's wording wins in every head it already writes to the messaging guide (#331): the homepage keeps the title, the description sentence and the SoftwareApplication node #328 gave it, and the Organization description keeps "Dutch company, servers in Germany". This branch adds what main does not have: the founder, the legal entity, the address and the KvK number in the Organization node of every public page, and Open Graph and Twitter cards that match the title. The legal entity is now in the description itself on /, /about and /pricing, not only in the JSON-LD no preview renders. The founder's name is in one description, /about, because that is the only one of the three where /about's own sentence backs it; on / and /pricing the description names Paramantis Solutions B.V. and the founder stays in the Organization node. Jargon is out of the sentence a buyer reads first. /verify says what it gets you instead of naming FIPS 204, and "relay" is gone from every title and every opening sentence except the four pages whose subject is the architecture. /sign says "the document text and your signing key never leave it", not "the file". In Request signatures the encrypted document does go to Paramant, which is how a recipient receives it. The plaintext and the key stay in the browser in all three modes; the file does not. /pricing names a floor per product, sending from 15 euro a month and signing from 49. An unsplit "from 15 euro" reads as if signing starts there. The free plan is called Community in the head as well, on /pricing and /signup. Three gates in tests/seo-contract.test.mjs: - title, og:title, twitter:title and the JSON-LD WebPage name are one sentence. /trust shipped three different names at once and nothing failed. - eight pages have their title and description pinned word for word, with the source of every claim named in the file. - no title or description carries a certification we do not hold, and none carries our own vocabulary. bron-seo/apply_seo_head.py reproduces every generated block exactly: "would change: 0 pages". Main drifted by one page before this commit, because carries that shape instead.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Head elements only: title, meta description, Open Graph, Twitter cards and JSON-LD on 50 of the 60 frontend pages. No body text, no styling. apply-nav.py and js/nav-auth.js are untouched, and no diff hunk in any of the 50 files falls after </head>. Rebased on main. Main's wording wins in every head it already writes to the messaging guide (#331): the homepage keeps the title, the description sentence and the SoftwareApplication node #328 gave it, and the Organization description keeps "Dutch company, servers in Germany". This branch adds what main does not have: the founder, the legal entity, the address and the KvK number in the Organization node of every public page, and Open Graph and Twitter cards that match the title. The legal entity is now in the description itself on /, /about and /pricing, not only in the JSON-LD no preview renders. The founder's name is in one description, /about, because that is the only one of the three where /about's own sentence backs it; on / and /pricing the description names Paramantis Solutions B.V. and the founder stays in the Organization node. Jargon is out of the sentence a buyer reads first. /verify says what it gets you instead of naming FIPS 204, and "relay" is gone from every title and every opening sentence except the four pages whose subject is the architecture. /sign says "the document text and your signing key never leave it", not "the file". In Request signatures the encrypted document does go to Paramant, which is how a recipient receives it. The plaintext and the key stay in the browser in all three modes; the file does not. /pricing names a floor per product, sending from 15 euro a month and signing from 49. An unsplit "from 15 euro" reads as if signing starts there. The free plan is called Community in the head as well, on /pricing and /signup. Three gates in tests/seo-contract.test.mjs: - title, og:title, twitter:title and the JSON-LD WebPage name are one sentence. /trust shipped three different names at once and nothing failed. - eight pages have their title and description pinned word for word, with the source of every claim named in the file. - no title or description carries a certification we do not hold, and none carries our own vocabulary. bron-seo/apply_seo_head.py reproduces every generated block exactly: "would change: 0 pages". Main drifted by one page before this commit, because carries that shape instead.
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
Head elements only: title, meta description, Open Graph, Twitter cards and JSON-LD on 50 of the 60 frontend pages. No body text, no styling. apply-nav.py and js/nav-auth.js are untouched, and no diff hunk in any of the 50 files falls after </head>. Rebased on main. Main's wording wins in every head it already writes to the messaging guide (#331): the homepage keeps the title, the description sentence and the SoftwareApplication node #328 gave it, and the Organization description keeps "Dutch company, servers in Germany". This branch adds what main does not have: the founder, the legal entity, the address and the KvK number in the Organization node of every public page, and Open Graph and Twitter cards that match the title. The legal entity is now in the description itself on /, /about and /pricing, not only in the JSON-LD no preview renders. The founder's name is in one description, /about, because that is the only one of the three where /about's own sentence backs it; on / and /pricing the description names Paramantis Solutions B.V. and the founder stays in the Organization node. Jargon is out of the sentence a buyer reads first. /verify says what it gets you instead of naming FIPS 204, and "relay" is gone from every title and every opening sentence except the four pages whose subject is the architecture. /sign says "the document text and your signing key never leave it", not "the file". In Request signatures the encrypted document does go to Paramant, which is how a recipient receives it. The plaintext and the key stay in the browser in all three modes; the file does not. /pricing names a floor per product, sending from 15 euro a month and signing from 49. An unsplit "from 15 euro" reads as if signing starts there. The free plan is called Community in the head as well, on /pricing and /signup. Three gates in tests/seo-contract.test.mjs: - title, og:title, twitter:title and the JSON-LD WebPage name are one sentence. /trust shipped three different names at once and nothing failed. - eight pages have their title and description pinned word for word, with the source of every claim named in the file. - no title or description carries a certification we do not hold, and none carries our own vocabulary. bron-seo/apply_seo_head.py reproduces every generated block exactly: "would change: 0 pages". Main drifted by one page before this commit, because carries that shape instead.
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
…t screen A phone showed "Pricing", a decorative "00" and a paragraph about a post-quantum core. No amount, no product, and nothing about who holds the files. Rebased onto main, so #328's rename (Community, not Free), its founder paragraph and its /docs#parasign-api fix all stand; this builds the first screen on top of them. /pricing - The lead says what you buy before what it costs: sign documents, send files that vanish after one read. - The promise carries its own number. "Free forever" alone reads as generous until the table says two signatures a month; it now says "Community is €0 a month, forever: 2 signatures per month and 10 uploads per hour, no card" in the same breath. - The lead prices the two products separately: from €15 a month for sending (ParaSend Pro), from €49 for signing (ParaSign Pro). One figure for both anchored an office that came to sign on the cheaper product's price. Both amounts are read off their own Pro card by the test, and those cards are already bound to the catalog. - The Community limits are the ones the relay enforces. The page sold "10 uploads per hour per IP", which is ANON_RATE_PER_HOUR on /v2/anon-inbound, deprecated 2026-05-28 with Sunset 2026-12-31. What actually stops an account is transfers_month 10 and file_mb 5 from relay/lib/tiers.js, refused with 402 and 413. The lead and the ParaSend cards now say "10 transfers per month, 5 MB per file", and ParaSend Pro says 500 transfers per month instead of "no IP rate limit", which was the same misdescription from the other side. - ParaSign's ParaShare claim matched no register entry. frontend/crypto-agility lists ParaShare with Default SIG "n/a" on a pre-v1 hybrid wire format, so "ML-DSA-65 signed receipts" is dropped for what the register says. - Jargon out of the lead. "A dedicated relay" and "a connection to their own software" became "a server of their own" and "signing built into their own software". The cryptography sentence keeps doing its work under the tables. - Who is behind it moved from 1128px into the first screen: Mick Beer, with the exact title /about gives him, and KvK 42115132 beside it. - The decorative "00" over the h1 is gone. It meant nothing and cost the first 60px of the fold. - Every tier card says who it is for, in one line. ParaSign moved above ParaSend; it is the flagship and it was second. - The Community cards send a visitor to /signup instead of /dashboard, which is a page they cannot open yet. - The FAQ said "Signatures are advanced (AES), not qualified (QES)" while /about says Simple Electronic Signature. /about is right: a ParaSign signature is an SES under eIDAS, not AES and not QES. - "All tiers meet NIS2 and GDPR requirements by design" was a guarantee the same page withdraws four paragraphs later. It now says the architecture is built to support that work and that Paramant holds no third-party certification. - Layout: grid items default to min-width:auto and .btn is nowrap, so the longest CTA set the min-content width of the track. At 390px every card was 471px inside a 342px container. /signup names the free limit in the same words /pricing uses. billing/checkout says where checkout actually happens and that nothing is charged there. Tests. tests/pricing-fold.test.mjs measures the laid-out page: the bottom edge of the amount, the audience line, the founder line and the first action must fall inside 390x844, in that order. It reads text nodes rather than a list of block tags, so the kicker span under the h1 is covered too. Prices, limits and checkout links are untouched; relay/test/pricing-page.test.js still recomputes all 34 of them from the catalog.
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 was referenced Sep 2, 2026
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.
The homepage was written for the people who build Paramant, not for the people
who buy it. Measured on 2 September: the meta description opened with
ML-KEM-768 + ML-DSA-65, the H1 was three verbs with no object(Send it. Sign it. Prove it.), the headings under it were Your documents,
Drop post-quantum crypto into your stack and Three ways in. One crypto core.,
there were ten calls to action and a What's next roadmap, and nowhere did the
page say what it costs.
What the page does now
The order of the sections is the argument:
/sign) and onesecondary (
/pricing). No crypto names in the H1 or the first paragraph.Community is given away, business plans pay for it.
/pricing.ParaRules, verbatim, each with the verify link it already had.
/docs. No roadmap.New H1:
New first paragraph:
The audience is not invented. Legal, health and finance are the three sector
relays the site already names (
/pricing,dpa.html,docs.html).Meta title and description rewritten in the same spirit. The title names both
the product and the company, which no page did before:
ParaSign by Paramant · sign and send documents in the EU(56 chars).Claims dropped
paramant-solutionsis private, so a visitor cannot get them; flagged as untrue in the July claims
audit and never removed.
SPHINCS+ · Falconlist.Nothing new was promised anywhere on the page.
Community, everywhere
The free plan is called Community on every page now. It is the word Mick
sells on and the site was the only place disagreeing with itself:
/pricingsaid Free while
admin/server.jsPLANS has always heldid: 'community', name: 'Community'. Both tier cards renamed (price, limits andorder untouched) and the rest pulled in line: terms, privacy, docs,
audit-log-export, the 402 upgrade card, and the bridge sentences on the
homepage, the dashboard and
/parasignthat existed only to explain thedisagreement away.
A later sweep, rendering every page to visible text rather than grepping markup,
found seven more:
Nine hits remain and all nine are correct English, not a plan name: "Free to
start", "Free on the Community plan", BUSL's "Free to use", the OT brief's own
Evaluation tier priced at Free, and two lines on
/vsabout what WeTransfer andSFTP cost. No frontend script carries the word at all.
Truthfulness fixes
The ParaRules had no proofs.
index.htmlpromises "The ParaRules come witha verify link each" and
pararules.htmlhad nine rules and zero links. All ninecarry one now, each to something that already exists:
/security,/privacy,the repo,
/crypto-agility,/changelog,/ct-log,/.well-known/security.txt."No US provider in the chain" was false.
relay.jsposts toapi.resend.comin three places, andprivacy.htmlalready says Resend receivesthe recipient address, the message and the complete personal link. True of the
data path and only that, so the homepage reads "No US provider in the data
path" and names the email route with a link to
/privacy. The stronger form on/pararulesis scoped the same way.Cloudflare was listed as a third party on
/security. It is not one.Checked from outside the network:
paramant.appresolves viakiki.bunny.netand
coco.bunny.net, the A record points straight at Hetzner 116.203.86.81, andno response carries a Cloudflare header. The list is now Resend, Hetzner, Bunny
and Mollie, and
docs/migration-bunny.mdmoves off "Planned for Q2 2026" todone, with what was measured and the date it was measured. The migration date
itself is not recorded there, so it is not invented.
A paying customer was told he is on the free plan.
setProductPlandelegates to
applyProductTier, which writes onlyplan_parasign/plan_parasendand by design never touches the unifiedplan. The endpointsreturned only that unified field, so a self-serve ParaSign Pro purchase kept
plan "community" and the dashboard called that customer free. Backend change
to
admin/server.js: one helper,productPlanFields(), feeds three endpointsso the dashboard and the account page cannot read two different truths.
GET /api/user/meplanplan_parasign,plan_parasend,paid_until_parasign,paid_until_parasendGET /api/user/accountplanGET /api/user/billing/statuscurrent_plandashboard.jsderives the effective plan from those and applies the same expiryrule as
effectiveProductTier. Plan names mirrorrelay/lib/tiers.js, solicensedreads Enterprise instead of a raw machine string.Smaller: the schema.org description said hosted in the Netherlands and
Germany (hosting is Germany only); the Enterprise line bundled ParaSend and
ParaSign terms as one plan; "accountancy" appears nowhere on main, so the hero
says legal, finance and healthcare; the ParaRules grid printed 01, 03, 04, 06,
which reads as two missing rather than four chosen; and a dead
txt('email')call is gone.
Gates added, and what each one catches
Sabotage-checked one change at a time. Every line below was run.
Plan naming and prices (
tests/ui-truthfulness.test.mjs)The plan gate reads the canonical rows AND the aliases out of
relay/lib/tiers.js, not a copy. The price gate matches the whole amount: itused to pass
€15against a page that only said€150.The founder line (
tests/ui-truthfulness.test.mjs)The old check had the shape "if the page says X, /about must say X", which a
rewrite walks straight past: swapping the title deletes the string it looks for.
Pinned both ways now.
The plan badge and the band, in a browser (
tests/user-dashboard-documents.test.mjs)admin/test/user-plan-fields.test.jsproves the fields are on the wire, but itinspects source, so the expiry rule and the band toggle could both be deleted
with every suite green. Five checks now drive the real page with
/api/user/mestubbed:ParaRules and CLI counts (
tests/ui-truthfulness.test.mjs,tests/site-claims.test.mjs)Site-claims gate 10 matched only the exact phrase of a claim this PR removed, so
it guarded nothing. Broadened to any count of CLI or command-line tools, digits
or words. Zero matches stays allowed and the comment says why: forcing the
sentence back would force back an unobtainable claim.
Tests
Green: links, seo-contract, ui-truthfulness, frontend-loading-contract,
product-heartbeat, site-claims, user-dashboard-documents (19 checks),
static-sanity (PASS, all hard checks), csp-inline, cache-bust, eslint,
admin/test/*(0 fail),relay/test/pricing-page.test.js(34 checks).relay/test/*carries pre-existing failures needing@paramant/coreand a liverelay. Compared name by name against a stashed
origin/mainbaseline afterevery round: no new failures.
Tests changed, all because they pinned a string this PR changes on purpose, each
with the reason in a comment above it:
navigation-shell(hero buttons),user-dashboard-documents(mission line, card order),relay/test/quota-upgrade-render.jsandrelay/test/pricing-page.js(bothquoted "Free" as the plan name),
site-claimsgates 5 and 10.Rebases
Rebased through #324, #325, #326, #327, #329 and #330. The
/pricingconflictkept both sides: main's SLA correction to 99.95 percent and this branch's
rename; the homepage quoted 99.9 twice and now matches.
/pricinglinked to/docs#parasign, which is not an anchor (it isparasign-api); fixed, and every/docs#link swept, that was the only broken one.The dashboard block order is deliberately untouched: PR #332 owns it and
stacks on this branch, where it finds the backend fields ready.
Per
AGENTS.mdandscripts/check-commit-style.sh, the AI attribution trailersare stripped from every commit on this branch and from this body;
scripts/check-commit-style.sh origin/main..HEADexits 0.Screenshots, 390 CSS pixels
Full page, Playwright. Images-only branch
review/homepage-koper-screenshots, not for merging.The dashboard shot stubs
/api/user/me. Its nav still shows Sign in / Createaccount because the stub does not drive
nav-auth.js; that is the harness, notthe page.
Note: this body was overwritten on 2 September by the description belonging to
PR #341 (relay.js critical-path tests), which already carries that text. This is
the restored description for #328.