Messaging guide: who we sell to, what we promise, how we prove it - #331
Merged
Conversation
This was referenced Sep 2, 2026
Apolloccrypt
added a commit
that referenced
this pull request
Sep 2, 2026
The messaging guide (docs/brand/messaging.md, PR #331) settles the order every commercial page runs in: what you can do here, then the split between the free tier and the business plans, then who is behind it, then the proof including the honest limits, and only then the developer material. Measured against that order, ParaSign had no page of its own and ParaSend still has none, so the only place either product is sold by name is a card on the homepage. frontend/parasign.html and frontend/parasend.html are those pages, both in the guide's order. The h1 and first paragraph on /parasign are the guide's, word for word. /parasend has no entry in the guide (section 8 books it as a later round), so it is built to the /parasign pattern and every sentence on it is lifted from copy that already ships: the tier lines and the btw convention from pricing.html, the RAM-only and burn-on-read wording from about.html and the pricing FAQ, the jurisdiction row from security.html, and the receiver line from the ParaSend card on index.html. Nothing new is promised on either page. Mick Beer appears on both, with the exact title the site already gives him and the one reason the free tier exists, in his own voice. The cryptography, the standard numbers and the RAM-only claim sit below the fold as the reason the top half is true, never in an h1. Two claims the guide flags as disputed (section 9) stay off both pages: the homepage's "no US provider in the chain" and the /pricing FAQ's "advanced (AES)". Both pages quote the /security jurisdiction row instead, and /parasign carries the /about SES wording, which is the one the guide pins. frontend/sign.html keeps its h1, its first paragraph and every sentence tests/ui-truthfulness.test.mjs locks. What changed above the tool is three mono facts (free forever, the key stays here, EU jurisdiction), a link to the new product page, and the split spelled out in the block a visitor without a session reads. The one CTA that block offers was styled with .ds-btn, a class no stylesheet ever defined, so "Create an account" rendered as plain text; it now uses the house button classes the rest of the page already uses. The tool below is untouched, and sign-flow.js selects neither class. Tests, because a promise without a gate is the thing this repo keeps catching: tests/ui-truthfulness.test.mjs now pins the three proofs the guide names as work (the /security CLOUD Act row, the three /about signing sentences, the pay-for-volume sentence on /pricing), asserts them again wherever the product pages quote them, holds the founder title to its exact wording, keeps the SES and certification limits on the page, and fails on the marketing vocabulary the guide bans. relay/test/pricing-page.test.js reads both product pages and recomputes every amount on them from billing-catalog.js, so a price cannot drift between /pricing and a product page. The sitemap and the JSON-LD come from bron-seo/, with both pages in the 0.9 crawl group and in the SoftwareApplication set. Regenerating it also corrected the /vault lastmod, which had been stale since 2026-07-25. Green locally: seo-contract, ui-truthfulness, links, frontend-loading-contract, navigation-shell (24 checks), sign-full, pricing-page (34 checks), check-csp-inline.sh, check-cache-bust.sh, eslint (exit 0). index.html untouched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XJk2nCLCLmi3F71qkCUn7N
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
force-pushed
the
docs/messaging-gids
branch
from
September 2, 2026 15:45
ebc6667 to
f16557d
Compare
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
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.
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.
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
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
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 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.
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.
Why
The frontend reads as a technology catalogue. Measured on 01-09: 59 sitemap pages, 40 nav links, 5 product names, against at most 15 visitors a day, 1 paying customer and 0 signatures in eleven days.
/docsoutdraws/pricing,/parasignreturns 404 while ParaSign is the flagship, and the only selling point Mick names is nowhere near the top of any page.That selling point, in his words on 02-09: the Community plan is his giveback to society, and there are paid business solutions for organisations that need more.
What this adds
docs/brand/messaging.md, the one place that settles the words on paramant.app:/pricingnames and prices it.tests/ui-truthfulness.test.mjs; proofs 1 and 3 are marked as assertions still to be added, and until they exist the claim does not move into a hero./aboutalready says.Rebased on main, and proof 1 rewritten to what ships
The branch is rebased onto
main, so #328 is in the base. That landed the corrected jurisdiction claim, and the guide's proof 1 was written against the older, broader one. It has been rewritten.Proof 1 is now "EU jurisdiction, no US party in the data path". The claim is about the data path, not the whole chain. Files and keys stay in the EU and are ciphertext outside the browser; transactional email is the one exception and goes through Resend, a US provider, which receives the address, the message and the personal signing link. That is what
/privacysets out and whatrelay.jsdoes when it callsapi.resend.com.The fixed wording is quoted word for word from two pages that ship on
main, and it is never paraphrased:From the rules grid on
/(frontend/index.html:382):The long form, ParaRule 5 on
/pararules(frontend/pararules.html:204):Both name the exception in the same breath as the claim. A page may shorten the long form to the short one, never the other way round, and neither may drop the Resend sentence. "No US company in the chain" and "no US provider in the chain" are now explicitly forbidden phrasings, and the to-add assertion in section 4 is written to catch them.
Two knock-on corrections in the same pass:
index.htmlbelongs to another branch is replaced, sincefeat/homepage-kopermerged as Homepage speaks to a buyer: what it does, what it costs, why you can check it #328.Sections 3 and 5 brought level with the pages
maincalls it Community everywhere andtests/ui-truthfulness.test.mjsfails any page that does not. Both bullets renamed, prices and limits unchanged./pricingin six sentences and the guide carries them verbatim. The stale "Free for everyday and community use, forever" quote is replaced by the sentence that actually ships./aboutword for word. Sentence two regained "(ML-DSA-65)". Sentence three, the split, was "the Community tier is free forever because signing and sending securely should not depend on a US subscription" and is now the sourced wording from Signed in, the free plan is called Community, and the page answers what a buyer asks #332: "The Community plan is his way of giving something back to society; the business plans pay for it." The jurisdiction claim does not belong beside his name; it belongs in proof 1, with its exception.Contradictions it records rather than hides
Three now, not two.
/aboutsays SES; the/pricingFAQ says "advanced (AES), not qualified (QES)". The/aboutwording is the pinned one, so the FAQ line moves in its own round./securitystill says "no US company". The Jurisdiction and privacy table carries "US CLOUD Act: Not applicable: no US infrastructure, no US company", which reads as no US party anywhere and is broader than/privacyallows./and/pararulesare already corrected; that row is the one that has to move, in its own PR with its own test. Until it does, proof 1 is quoted from/and/pararulesonly./aboutyet. It is on/pricingand on the signed-in pages. PR Signed in, the free plan is called Community, and the page answers what a buyer asks #332 puts it in the "Behind Paramant" block. Until that lands, section 5 quotes it from/pricingand the assertion that pins the/aboutsentences waits.Scope
Docs only. No page, test, nav, footer or stylesheet is touched. One file, one commit.
Tests
tests/static-sanity.sh: PASS, all hard checks clear, including the commit style guard.