Repository navigation
fix(content): say what the sync relay actually carries - #5
Merged
Merged
Conversation
The site made two claims about the sync relay that the product does not support, in English and in Dutch, across the home page, the feature cards, the privacy page, the sync page, the security page, the Dutch FAQ and the served llms.txt. "A relay that only ever holds ciphertext it cannot read" is false. PairingPeerOutbox::queueFor() json_encodes the pairing frame and hands the raw blob to RelayMailbox::deliverIfUnderQuota() with no encryption step, so a PAIR_RESPONDER_ACCEPT sits in the mailbox as readable JSON carrying both device ids, the responder's Ed25519 and X25519 public keys and the display name of the device. The relay has two production users: GdkRotationService, whose epoch wraps are sealed with crypto_box_seal to the recipient's X25519 key, and the pairing courier, whose frames are not sealed at all. Only one half of that was ciphertext. "If one device is asleep, the changes wait in a relay" is false too. Transactions never cross the relay; op-log frames only ever travel the direct Noise session. The product already tells its own users so — Modules/Sync/Resources/lang/en/devices.php reads "A relay lets two devices complete pairing and exchange encryption keys when they cannot reach each other directly. Transactions themselves still sync only when both devices are on the same network", and Sync's TheRelayHelpPromisesNoPullThePhoneCannotMakeTest pins that sentence. The website was contradicting the application's own screen. The claims are corrected rather than deleted. A privacy page that goes quiet about the relay is worse than one that describes it, so the sync and security pages now state what a relay holds in both directions: key handovers sealed to the receiving device, pairing messages that are not sealed, the metadata it sees, and the fact that it cannot interpose itself because the safety number covers the keys. The security page's "what it does not defend against" list gains the pairing metadata, which is where a reader looking for the cost of a relay will go. The Dutch is written from the shipped Dutch help string in Modules/Sync/Resources/lang/nl/devices.php rather than translated from the new English, so the site and the application say the same thing in the same words. Left alone deliberately: the "zero-knowledge relay fallback" roadmap label in the milestone seed reproduces 00-overview/roadmap.md verbatim and is fetched live from the spec at build time, and the English FAQ answer is rendered straight from 90-appendix/faq.md. Both carry the same false claim and both need a spec PR; correcting the seed here would only drift from the canonical text it mirrors. Spec: REPO-R41, REPO-R43 Signed-off-by: Wessel Verheij <info@nightworks.io>
…t true
The privacy page's English bullet says a removed device "cannot read
anything sent afterwards". Its Dutch counterpart lost the qualifier and
reads "zodat het verwijderde niets meer kan lezen" — so the Dutch page
claims full revocation while the English page claims forward-only
revocation, which is the one the product provides.
Revocation rotates the group key and re-wraps it to the devices kept; it
cannot reach back into what the removed device already holds. The Dutch
sentence as written was outright false about what removing a device
protects, which is why it is corrected here alongside the relay claims
rather than left on the list of copy to review.
Every other revocation sentence on the site already carries the qualifier
("van wat er daarna verstuurd is", "van alles daarna"), so this is the one
site that was out of step, not a policy change.
Spec: REPO-R43
Signed-off-by: Wessel Verheij <info@nightworks.io>
… ranges
`security / osv-scanner` refused this branch. Clearing the first two advisories
uncovered six more behind them, one critical:
astro 7.1.4 -> 7.3.2 GHSA-26w7-cxv4-gfx2 9.8
GHSA-376h-93r7-7g6f 6.3
sharp 0.35.3 -> 0.35.4 GHSA-rgj7-g3m4-5g8c 8.9
js-yaml 4.3.1 -> 4.3.2 GHSA-2883-xcg3-v3hh 7.5
fast-uri 3.1.5 -> 3.1.7 four advisories 7.5 (dev)
svgo 4.0.2 -> 4.1.0 GHSA-4vpr-x523-8j87 6.1
GHSA-w27v-7q3p-w38r 8.2
Every one is satisfied inside the range package.json already declares, so this
is the lockfile alone. `npm update`, never `npm install <pkg>@latest`: the
latter promotes a transitive package to a direct dependency, which it did for
svgo on the first attempt and which would make this repo own a version astro
is responsible for.
`npm audit` now reports 0 vulnerabilities, and the site still builds 33 pages.
Unrelated to the relay copy this branch carries. The advisories predate it and
were blocking the merge; the scanner reports them all at once, so fixing only
the two first named would have left a critical standing behind a green check.
Signed-off-by: Wessel Verheij <info@nightworks.io>
lessevv
force-pushed
the
fix/relay-copy-accuracy
branch
from
September 13, 2026 17:51
b2ba2b3 to
75aee9e
Compare
|
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 site made two claims about the sync relay that the product does not support. Both were live in English and in Dutch, on the home page, the feature cards, the privacy page, the sync page, the security page, the Dutch FAQ and the served
llms.txt.Do not merge this yet. Auto-merge is deliberately not armed — this is public-facing privacy copy and the timing is the owner's call.
The two false claims, and what the code says
1. "a relay that only ever holds ciphertext it cannot read"
Modules/Sync/Internal/Pairing/PairingPeerOutbox::queueFor()json_encodes the pairing frame and hands the raw blob straight toRelayMailbox::deliverIfUnderQuota(). There is no encryption step. APAIR_RESPONDER_ACCEPTsits in the relay mailbox as readable JSON carryingtoken_hash, both device ids, the responder's Ed25519 and X25519 public keys, andresponder_name— the display name of the device.The relay has exactly two production users.
GdkRotationService::deliverWrap()seals its epoch key withsodium_crypto_box_seal()to the recipient's X25519 key, so those really are opaque. The pairing courier seals nothing.PAIR_CONFIRMis Ed25519-signed overPairingFrame::confirmSigningMessage(), which makes it unforgeable — not unreadable.2. "if one device is asleep, the changes wait in a relay"
Transactions never cross the relay at all; op-log frames only ever travel the direct Noise session. The application already tells its own users this, in
Modules/Sync/Resources/lang/en/devices.php:Modules/Sync/tests/Feature/TheRelayHelpPromisesNoPullThePhoneCannotMakeTest.phppins that sentence and asserts the screen never offers the relay "as a road a transaction can take". The website was contradicting the application's own settings screen.What changed
The claims are corrected, not deleted. A privacy page that goes quiet about the relay is worse than one that describes it, so the sync and security pages now say what a relay holds in both directions: key handovers sealed to the receiving device, pairing messages that are not sealed, the metadata it sees, and the fact that it cannot interpose itself because the safety number covers the keys.
Nineteen strings across seven files, nine English and ten Dutch:
src/i18n/en.ts×3src/i18n/cards.tssrc/i18n/pages-en.ts×4public/llms.txtsrc/i18n/nl.ts×3src/i18n/cards.tssrc/i18n/faq.ts×2src/i18n/pages-nl.ts×4The Dutch is written from the shipped Dutch help string in
Modules/Sync/Resources/lang/nl/devices.phprather than translated from the new English, so the site and the application say the same thing in the same words.A second commit fixes one more claim that is outright false about security: the Dutch privacy bullet on device removal had lost the qualifier its English counterpart carries, so it promised full revocation where the product provides forward-only revocation. Every other revocation sentence on the site already says "daarna"; this was the one that did not.
Verified
npm run check0 errors,npm run build33 pages,typosclean. The old phrasing is gone fromdist/; the new phrasing renders on/privacy,/sync,/security,/nl/privacy,/nl/sync,/nl/security,/nl/faqand the home pages.Two sites left alone on purpose, because the false claim originates upstream
src/data/seed-milestones.ts:45— "zero-knowledge relay fallback" reproducesspec 00-overview/roadmap.md:140verbatim and is fetched live from the spec at build time. Editing the seed would only drift from the canonical text it mirrors.spec 90-appendix/faq.md, which still says "changes wait in a relay that only ever holds encrypted data it cannot read". The Dutch translation in this repo is corrected here; the English will keep contradicting it until a spec PR lands.The same claim also sits in
spec 00-overview/glossary.md("Zero-knowledge relay … Holds opaque ciphertext blobs"). A companion spec PR is needed for all three.Spec: REPO-R41, REPO-R43