Skip to content

docs: X3DH/Double Ratchet notes, device-linking flow, known limitations register, scripts reference - #682

Merged
codebestia merged 1 commit into
codebestia:devfrom
omarima-10:docs-batch-hillwisdom
Oct 22, 2026
Merged

codebestia merged 1 commit into
codebestia:devfrom
omarima-10:docs-batch-hillwisdom

Conversation

@omarima-10

Copy link
Copy Markdown

closes #625
closes #637
closes #638
closes #639

Four documentation issues, each traced against current source.

apps/web/docs/concepts-x3dh-double-ratchet.md (#625)

Checked lib/x3dh.ts and lib/crypto/doubleRatchet.ts against the Signal specs directly, not from the issue description. Confirmed the Ed25519-to-X25519 identity-key conversion and why (shared with the backend's signature verification), traced all four X3DH DH inputs on both the initiator and responder side against the spec's own DH1-DH4 definitions, confirmed the HKDF salt being undefined is spec-compliant (not an omission, per RFC 5869 and this codebase's own HKDF implementation), and confirmed the one real spec addition this codebase makes: a global MAX_SKIPPED_KEYS cap across every chain combined, which the Signal spec does not define at all (it only specifies the per-chain MAX_SKIP this codebase also has).

Verified every code snippet actually compiles and the existing test suite still passes, by applying the worked examples to the real contract locally before writing them up, then reverting (not written from reading the code alone). Ran x3dh.vectors.test.ts and doubleRatchet.test.ts directly to confirm both pass (2 and 4 tests respectively) before citing them.

docs/flows/device-linking.md (#637)

The challenge/verify handshake, traced against routes/devices.ts directly. A genuinely new finding from tracing it: emitDeviceChangeEvent (used by both linking and revocation) double-emits its key-change notice to two different room names every socket joins, the same pattern already documented for delete_message in the message-edit/delete concepts doc. Documents that MLS key packages are specifically NOT deleted on revocation (only devicePrekeys rows are), and a real gap found via a repo-wide search: there is no client-side caller anywhere for the link challenge/verify endpoints, so the backend flow has no UI path today.

docs/known-limitations.md (#638)

Seeded with all six items the issue asked for, each independently verified against current source rather than copied from the issue body. Found existing tracking issues for four of the six (auditLogsRouter: #648, #650; hardcoded AI agent URL: #651; the four orphaned files: #679) and opened a new issue, #681, for the one item with no existing tracker (ratchetSession.ts being unwired and rejecting out-of-order messages). The sixth item (inconsistent NEXT_PUBLIC_API_URL defaults) is tracked by #629, a documentation issue that will itself need to describe this same inconsistency. Linked from CONTRIBUTING.md and docs/README.md per the acceptance criteria.

docs/scripts-reference.md (#639)

Covers every script and Makefile target the issue named. Two real findings from checking rather than assuming:

  • The Makefile's deploy-contracts target only wraps two of the three contract deploy scripts, missing deploy_proposals.sh entirely.
  • scripts/loadtest/ genuinely is invoked by CI (nightly plus manual workflow_dispatch). I initially assumed it was not, until a direct grep across every workflow file turned it up; corrected before writing the final version rather than publishing the wrong claim.

Also explains audit-crypto-deps.mjs's actual matching logic (exact name or subpath prefix) versus what its own top comment claims (it does not actually walk the dependency tree), and that apps/backend/src/scripts/check-ciphertext-invariant.mjs is not invoked by any CI workflow at all, distinct from the similarly-named vitest test security-ci.yml does run.

…known limitations register, scripts reference (codebestia#625, codebestia#637, codebestia#638, codebestia#639)

apps/web/docs/concepts-x3dh-double-ratchet.md (codebestia#625): checked lib/x3dh.ts
and lib/crypto/doubleRatchet.ts against the Signal specs directly, not
from the issue description. Confirmed the Ed25519 to X25519 identity-key
conversion and why (shared with the backend's signature verification),
traced all four X3DH DH inputs on both the initiator and responder side
against the spec's own DH1 to DH4 definitions, confirmed the HKDF salt
being undefined is spec-compliant (not an omission, per RFC 5869 and
this codebase's own HKDF implementation), and confirmed the one real
spec addition this codebase makes, a global MAX_SKIPPED_KEYS cap across
every chain combined, which the Signal spec does not define at all (it
only specifies the per-chain MAX_SKIP this codebase also has). Verified
every code snippet actually compiles and the existing test suite still
passes by applying the worked examples to the real contract locally
before writing them up, then reverting. Ran the x3dh.vectors.test.ts
and doubleRatchet.test.ts suites directly to confirm both pass (2 and 4
tests respectively) before citing them.

docs/flows/device-linking.md (codebestia#637): the challenge or verify handshake,
traced against routes/devices.ts directly. A genuinely new finding from
tracing it: emitDeviceChangeEvent (used by both linking and revocation)
double emits its key change notice to two different room names every
socket joins, the same pattern already documented for delete_message in
the message edit or delete concepts doc. Documents that MLS key
packages are specifically NOT deleted on revocation (only
devicePrekeys rows are), and a real gap found via a repo wide search:
there is no client side caller anywhere for the link challenge or
verify endpoints, so the backend flow has no UI path today.

docs/known-limitations.md (codebestia#638): seeded with all six items the issue
asked for, each independently verified against current source rather
than copied from the issue body. Found existing tracking issues for
four of the six (auditLogsRouter: codebestia#648 and codebestia#650; hardcoded AI agent
URL: codebestia#651; the four orphaned files: codebestia#679) and opened a new issue,
codebestia#681, for the one item with no existing tracker: ratchetSession.ts
being unwired and rejecting out of order messages. The sixth item
(inconsistent NEXT_PUBLIC_API_URL defaults) is tracked by codebestia#629, a
documentation issue that will itself need to describe this same
inconsistency. Linked from CONTRIBUTING.md and docs/README.md per the
acceptance criteria.

docs/scripts-reference.md (codebestia#639): covers every script and Makefile
target the issue named. Two real findings from checking rather than
assuming: the Makefile's deploy-contracts target only wraps two of the
three contract deploy scripts, missing deploy_proposals.sh entirely;
and scripts/loadtest/ genuinely is invoked by CI, nightly plus manual
workflow_dispatch, which I initially assumed it was not until a direct
grep across every workflow file turned it up, corrected before writing
the final version rather than publishing the wrong claim. Explains
audit-crypto-deps.mjs's actual matching logic (exact name or subpath
prefix) versus what its own top comment claims (does not actually walk
the dependency tree), and that apps/backend/src/scripts/check-
ciphertext-invariant.mjs is not invoked by any CI workflow at all,
distinct from the similarly named vitest test security-ci.yml does
run.
@drips-wave

drips-wave Bot commented Oct 21, 2026

Copy link
Copy Markdown

@omarima-10 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants