{
  "schema": "disroot-chat-security-tests/v1",
  "generatedAt": "2026-09-14T21:42:57.521Z",
  "runtime": "v26.8.2",
  "platform": "darwin/arm64",
  "classification": "Automated integration and MLS regression tests",
  "gitHead": "2a13d64ad7f9c3cb0b765f17d879cd10f32c4b89",
  "sourceSha256": {
    "lib/secure-chat-protocol.ts": "ea0ad4ab25670df049c420e853914f36e661fb0bd415eeb1aaa02ccf5b893ed9",
    "lib/secure-chat-invite.ts": "f487dff425901c461ac96dc59a867f3a281145dad55b6173f6532b79806b75fe",
    "lib/secure-chat-mls.ts": "d155de3e0abf32fa94062d35fe2f9f7012e6fa113387252a75143d64268c08f3",
    "lib/secure-chat-mls-adapter.ts": "32545ce180774d80daf5aaf112ed554dbdc9a0b99b3736abd4e9d94c0572c46b",
    "lib/secure-chat-client.ts": "9d1384a1fd927a2ee324429397a67b22234969ced4ed58648ccae012014e887e",
    "lib/secure-chat-store.ts": "10929a422618e0eed160b10b7c74dec9e59c7eec82d7bd3f931c4de5eb7df7bd",
    "lib/secure-chat-handler.ts": "ba989b31d21e67d0d20a80031c5cc30fe7b7a56625d43c027f7a2ef9414d5b6d",
    "lib/secure-chat-guard.ts": "a4794b43be5abccc44b0c3b6829f8ae7e6d34c0c48ef7f4901a75ea9fa398aa7",
    "app/api/secure-chat/route.ts": "c471ce096f55c14a14ec4d68a7a0c729ca4ce34c264dc438e3edd5ae6ba5a6c7",
    "scripts/secure-chat-relay.mjs": "163f41adc892a87de6fa2426e5ed0b75aac2a86a615025ade8db740a65024ced",
    "lib/secure-chat-v2.test.mjs": "3f3599c9ba3128ab6506b51cb730ab45ef6d5667b7a0fd43ab903cba20fe090a",
    "tests/secure-chat/ratchet.test.mjs": "187c66bd607cc01cbc3c712ff5fb464f5db969ddc453441b7107df7e42cbf56c",
    "package-lock.json": "fda4f1d4c21d65f86b19fa4031f947619e385b24b9a5d6f55c82ce1ee7e552f7",
    "lib/secure-chat-interactions.ts": "dedb9a21a8b81af84ed96def3100d1c44156de87ca048bc53026dcabaf48d213",
    "lib/secure-chat-session.ts": "78f948468b4638a7806de917c5bdfcab9e2c3c9e8c2498e2b201d81623245506",
    "lib/secure-chat-runtime.ts": "af99e847ee6c3cb1e345c35ab96efb55a7c935f9e70296fff450f76eaa129e24",
    "lib/secure-chat-polling.ts": "543a3a3e6886bbf553aae7848987d75e839c4edd5943cf08ba66cc4c3b2082f6",
    "lib/secure-chat-vault.ts": "7d89ebd6e9d79b03d65066cbdd15b78fd154eb49455c6c55d212187c05ee2d18",
    "lib/secure-chat-browser-session.ts": "7c9acd3902aaf2b9538ae1b2157893c35c4acbd343f18f72d58e1c9a9d54cdc6"
  },
  "passed": true,
  "total": 115,
  "results": [
    {
      "suite": "Production integration and hostile inputs",
      "command": "node --experimental-strip-types --test --test-reporter=tap lib/secure-chat-v2.test.mjs",
      "exitCode": 0,
      "passed": true,
      "tests": [
        {
          "name": "production clients: creator remains in the same chat after a guest joins",
          "passed": true
        },
        {
          "name": "production clients: bidirectional Unicode and emoji survive relay serialization",
          "passed": true
        },
        {
          "name": "a third client joins through a non-founder and cannot read earlier messages",
          "passed": true
        },
        {
          "name": "lost publish acknowledgement retries identical wire and appends once",
          "passed": true
        },
        {
          "name": "uncertain writes discard the session instead of reusing MLS generations",
          "passed": true
        },
        {
          "name": "expired write lease fails closed after encryption",
          "passed": true
        },
        {
          "name": "simultaneous sends serialize without duplicate delivery",
          "passed": true
        },
        {
          "name": "nickname and cleartext never enter the production relay state or request bodies",
          "passed": true
        },
        {
          "name": "the invitation secret is domain-separated from the transport capability",
          "passed": true
        },
        {
          "name": "invitation parser rejects duplicates, downgrade, expired and oversized links",
          "passed": true
        },
        {
          "name": "bootstrap AEAD binds packet purpose and room deadline",
          "passed": true
        },
        {
          "name": "tampered manifest and wrong founder anchor are rejected",
          "passed": true
        },
        {
          "name": "one-use login challenge rejects replays and concurrent authentication",
          "passed": true
        },
        {
          "name": "invalid signature consumes a challenge and cannot be retried with the correct key",
          "passed": true
        },
        {
          "name": "login challenge binds the browser origin",
          "passed": true
        },
        {
          "name": "private transport JWK fields are rejected before importing a key",
          "passed": true
        },
        {
          "name": "a transport key cannot create a second conversation",
          "passed": true
        },
        {
          "name": "concurrent authentication at the binding limit leaves no orphan conversations",
          "passed": true
        },
        {
          "name": "wrong invitation capability and extended deadline cannot join",
          "passed": true
        },
        {
          "name": "24-hour cleanup removes room, messages, sessions, pending joins and bindings",
          "passed": true
        },
        {
          "name": "join and key updates do not extend the shared deadline",
          "passed": true
        },
        {
          "name": "challenge floods are bounded without IP storage",
          "passed": true
        },
        {
          "name": "cross-site Origin, fetch-site and unconfigured Host are denied",
          "passed": true
        },
        {
          "name": "API rejects malformed JSON, oversize body and legacy admin actions",
          "passed": true
        },
        {
          "name": "MLS rejects a replayed message and accepts the following generation",
          "passed": true
        },
        {
          "name": "tampered ciphertext fails without consuming the valid generation",
          "passed": true
        },
        {
          "name": "message identifier substitution fails even with valid MLS ciphertext",
          "passed": true
        },
        {
          "name": "MLS framing rejects truncated, trailing and noncanonical base64 data",
          "passed": true
        },
        {
          "name": "an invitation holder cannot substitute another participant's signed nickname",
          "passed": true
        },
        {
          "name": "case-insensitive nickname collisions cannot enter the verified roster",
          "passed": true
        },
        {
          "name": "Welcome is one-use and cannot be consumed by a different KeyPackage",
          "passed": true
        },
        {
          "name": "a pending encrypted packet blocks generation of a second ciphertext",
          "passed": true
        },
        {
          "name": "padding equalizes two short application messages",
          "passed": true
        },
        {
          "name": "closing the client clears its active identity state and invitation secret",
          "passed": true
        },
        {
          "name": "bounded parser fuzz: 256 deterministic malformed MLS packets never render text",
          "passed": true
        },
        {
          "name": "integrity mutation matrix: 32 ciphertext bit flips are rejected",
          "passed": true
        },
        {
          "name": "an old relay snapshot cannot roll back a live client's cursor",
          "passed": true
        },
        {
          "name": "a substituted event packet closes the client without rendering unverified text",
          "passed": true
        },
        {
          "name": "unknown bearer token cannot read, claim, publish or enumerate a room",
          "passed": true
        },
        {
          "name": "cross-conversation packets cannot decrypt even with a reused message id",
          "passed": true
        },
        {
          "name": "audit regression: an invitation holder's alternate MLS group lacks the pinned founder",
          "passed": true
        },
        {
          "name": "audit regression: a real founder roster without a valid admission chain is rejected",
          "passed": true
        },
        {
          "name": "audit regression: an admitted peer cannot rewrap Alice's signed text as its MLS message",
          "passed": true
        },
        {
          "name": "audit regression: a signed request with an invalid inner KeyPackage cannot close incumbents",
          "passed": true
        },
        {
          "name": "audit regression: current state drops withheld prior-epoch ciphertext after refresh",
          "passed": true
        },
        {
          "name": "audit regression: the state adapter discards retained old epochs without aliasing live secrets",
          "passed": true
        },
        {
          "name": "audit regression: repeated unadmitted logouts release all member reservations",
          "passed": true
        },
        {
          "name": "audit regression: an abandoned login without enqueue expires after two minutes",
          "passed": true
        },
        {
          "name": "audit regression: sixteen full relay windows keep accepting bounded replacement writes",
          "passed": true
        },
        {
          "name": "simultaneous incumbent admission attempts leave all three clients usable",
          "passed": true
        },
        {
          "name": "closing during asynchronous key refresh cannot resurrect a cryptographic session",
          "passed": true
        },
        {
          "name": "sixteen real MLS participants fit the relay packet budgets and exchange text",
          "passed": true
        },
        {
          "name": "only the configured v3 onion authority is allowed, with exact same-origin POST",
          "passed": true
        },
        {
          "name": "encrypted replies bind the exact original author and message",
          "passed": true
        },
        {
          "name": "reactions set, replace and remove only the authenticated participant's reaction",
          "passed": true
        },
        {
          "name": "identical reaction operations and a lost acknowledgement are idempotent",
          "passed": true
        },
        {
          "name": "new guests see reply references without receiving the earlier message or its reactions",
          "passed": true
        },
        {
          "name": "invalid drafts and forged or unavailable targets do not consume a lease or close the session",
          "passed": true
        },
        {
          "name": "message views do not expose mutable internal reply or reaction state",
          "passed": true
        },
        {
          "name": "reply and reaction metadata never enter relay request fields or stored plaintext",
          "passed": true
        },
        {
          "name": "receiver rejects unsigned, altered and oversized interactions from an admitted peer",
          "passed": true
        },
        {
          "name": "interaction projection has bounded history and no queue for missing targets",
          "passed": true
        },
        {
          "name": "returning through the invitation reuses the live browser identity without a relay login",
          "passed": true
        },
        {
          "name": "owner and mirrored tabs serialize sends and reactions through one MLS client",
          "passed": true
        },
        {
          "name": "closing a mirrored view leaves the original session and keys active",
          "passed": true
        },
        {
          "name": "explicit End session in a mirror destroys the owner's keys and closes other views",
          "passed": true
        },
        {
          "name": "an altered invitation cannot discover a live browser session",
          "passed": true
        },
        {
          "name": "owner shutdown invalidates mirrored views and cannot be resumed from stale state",
          "passed": true
        },
        {
          "name": "presence follows authenticated reads, times out, reconnects and disappears on logout",
          "passed": true
        },
        {
          "name": "presence reveals no nicknames or signing fingerprints to the relay",
          "passed": true
        },
        {
          "name": "participant connection bindings cannot be copied from another signing identity",
          "passed": true
        },
        {
          "name": "a validly signed duplicate transport binding is rejected before the write lease",
          "passed": true
        },
        {
          "name": "connection bindings are one-time and client views do not expose mutable profiles",
          "passed": true
        },
        {
          "name": "old relays without presence do not fabricate participant status",
          "passed": true
        },
        {
          "name": "malformed or oversized presence snapshots fail closed before rendering",
          "passed": true
        },
        {
          "name": "orphaned invitations reject new guests instead of leaving everyone waiting",
          "passed": true
        },
        {
          "name": "a guest waiting when the last admitted participant leaves receives an explicit error",
          "passed": true
        },
        {
          "name": "silent abandoned sessions do not create a misleading new waiting guest",
          "passed": true
        },
        {
          "name": "the background session poller admits a guest while its document is hidden",
          "passed": true
        },
        {
          "name": "poll wakeups do not overlap and teardown removes event listeners",
          "passed": true
        },
        {
          "name": "SPA view detach and return retain identity, history and admission without a new login",
          "passed": true
        },
        {
          "name": "invitations preserve the chat document path for same-tab hash navigation",
          "passed": true
        },
        {
          "name": "send waits for another participant's write lease and delivers without manual retry",
          "passed": true
        },
        {
          "name": "background admission yields to a held lease without reporting a connection failure",
          "passed": true
        },
        {
          "name": "ending the session while waiting for a lease cancels sending before encryption",
          "passed": true
        },
        {
          "name": "four concurrent writers deliver once each without user retries",
          "passed": true
        },
        {
          "name": "saved sessions: reload retains nickname, fingerprint, history and the existing relay identity",
          "passed": true
        },
        {
          "name": "saved sessions: both browsers can close and resume the same conversation",
          "passed": true
        },
        {
          "name": "saved sessions: pending admission survives reload and consumes Welcome safely",
          "passed": true
        },
        {
          "name": "saved sessions: accepted write interrupted before acknowledgement retries identical ciphertext once",
          "passed": true
        },
        {
          "name": "saved sessions: unsent journal resumes under a fresh lease without re-encryption",
          "passed": true
        },
        {
          "name": "saved sessions: end session removes the checkpoint and revokes its transport",
          "passed": true
        },
        {
          "name": "saved sessions: storage failure prevents publishing ciphertext",
          "passed": true
        },
        {
          "name": "saved sessions: expiry and wrong signing keys cannot restore a checkpoint",
          "passed": true
        },
        {
          "name": "saved vault: AES-GCM hides text and rejects modified ciphertext, context and key",
          "passed": true
        },
        {
          "name": "saved sessions: reload between durable Welcome and its ACK remains ready",
          "passed": true
        },
        {
          "name": "saved sessions: interrupted admission commit restores the existing members and guest",
          "passed": true
        },
        {
          "name": "saved sessions: temporary relay outage keeps the local checkpoint for another attempt",
          "passed": true
        },
        {
          "name": "saved sessions: expired relay session removes the local checkpoint without recreating a room",
          "passed": true
        },
        {
          "name": "HTTP transport: interrupted streams and invalid JSON remain recoverable gateway errors",
          "passed": true
        },
        {
          "name": "durable outbox: lost publish ACK preserves the participant and retries once without duplicate text",
          "passed": true
        },
        {
          "name": "durable outbox: offline before publication survives reload and preserves unsent ciphertext",
          "passed": true
        },
        {
          "name": "legacy links: root invitations enter the standalone route without losing the secret fragment",
          "passed": true
        },
        {
          "name": "durable outbox: interrupted refresh does not end the participant",
          "passed": true
        },
        {
          "name": "mirrored tabs do not multiply relay polling or exhaust the owner's read quota",
          "passed": true
        },
        {
          "name": "room capacity reclaims closed conversations without evicting offline sessions",
          "passed": true
        }
      ],
      "artifact": "integration.tap"
    },
    {
      "suite": "MLS retention and compromise scenarios (laboratory fixtures)",
      "command": "node --experimental-strip-types --test --test-reporter=tap tests/secure-chat/ratchet.test.mjs",
      "exitCode": 0,
      "passed": true,
      "tests": [
        {
          "name": "three independent clients exchange serialized, encrypted Unicode messages",
          "passed": true
        },
        {
          "name": "a later member cannot process pre-join ciphertext but can read new messages",
          "passed": true
        },
        {
          "name": "copied state before consumption reads a message; current consumed state rejects it",
          "passed": true
        },
        {
          "name": "another member's refresh does not heal a copied participant state",
          "passed": true
        },
        {
          "name": "the compromised participant's honest refresh prevents its old snapshot following the new epoch",
          "passed": true
        },
        {
          "name": "a different key cannot reuse a pinned identity",
          "passed": true
        },
        {
          "name": "tampered wire data is rejected without consuming the valid message",
          "passed": true
        },
        {
          "name": "framing rejects trailing bytes and padding hides the difference between two short texts",
          "passed": true
        },
        {
          "name": "local crypto timing sample (not browser or network latency)",
          "passed": true
        }
      ],
      "artifact": "mls-ratchet.tap"
    }
  ],
  "limits": [
    "The source hashes identify the tested files, including uncommitted work. gitHead alone does not identify this build.",
    "Expiry is tested by advancing an injected relay clock; this is not a 24-hour endurance test.",
    "The parser test contains 256 deterministic malformed packets; the integrity test mutates 32 ciphertext bytes. These are bounded negative tests, not exhaustive fuzzing.",
    "Laboratory compromise fixtures exercise pinned ts-mls 1.6.4 and record behavior after state capture and participant key updates.",
    "The timing sample measures local Node cryptography, not browser or network latency.",
    "Browser, HTTP and deployment checks are recorded separately and are not implied by this report."
  ]
}
