Automatic · every commit to main
Every commit, tested in the open.
Each new TgWitness commit runs the whole suite on a clean machine: the signed journal and its verifier, evidence exports and reports, the panel in a real browser, sessions against synthetic Telegram clients. Larger runs drive real test accounts on a test server. Every result is published here, failures included.
3a614fb780cd · Detect secret chats the peer endedFinished 2026-11-14 08:29 UTC- Pick up the commitEach new commit on main, checked out exactly as published
- Run the full suite2,255 tests in 137 files, browser checks included
- Drive real accountsCapture, export and verify on test accounts and test chats
- Publish every resultTotals, each failure with its message, raw JUnit and logs
COVERAGE
What the suite checks
Tests grouped by the part of TgWitness they exercise; the bar is the share that passed.
FAILURES
Every failure, in full
New failures turn the run red. Known failures are listed with the reason they are expected until fixed.
tools/test_proxy_source_settings.py
test_invalid_settings_prevent_refresh_before_networkError message
Failed: DID NOT RAISE ValueError
test_permission_error_never_restores_enabled_defaultsError message
Failed: DID NOT RAISE ValueError
test_unreadable_settings_never_restore_enabled_defaults[[]]Error message
Failed: DID NOT RAISE ValueError
test_unreadable_settings_never_restore_enabled_defaults[\xff]Error message
Failed: DID NOT RAISE ValueError
test_unreadable_settings_never_restore_enabled_defaults[]Error message
Failed: DID NOT RAISE ValueError
test_unreadable_settings_never_restore_enabled_defaults[null]Error message
Failed: DID NOT RAISE ValueError
test_unreadable_settings_never_restore_enabled_defaults[{"countries":"invalid"}]Error message
Failed: DID NOT RAISE ValueError
test_unreadable_settings_never_restore_enabled_defaults[{"github":{"enabled":[]}}]Error message
Failed: DID NOT RAISE ValueError
test_unreadable_settings_never_restore_enabled_defaults[{"unknown":true}]Error message
Failed: DID NOT RAISE ValueError
test_unreadable_settings_never_restore_enabled_defaults[{]Error message
Failed: DID NOT RAISE ValueError
tools/test_verifier_sources.py
test_frozen_verification_decisions_are_unchangedThe verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
assert False [+2 more lines; full report in element text]
test_old_and_new_decisions_and_statuses_match[pinned---json]The verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
assert False [+3 more lines; full report in element text]
test_old_and_new_decisions_and_statuses_match[pinned---plain]The verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
assert False [+5 more lines; full report in element text]
test_old_and_new_decisions_and_statuses_match[unmet_tier---json]The verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
assert False [+3 more lines; full report in element text]
test_old_and_new_decisions_and_statuses_match[unmet_tier---plain]The verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
assert False [+5 more lines; full report in element text]
test_old_and_new_decisions_and_statuses_match[unpinned---json]The verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
assert False [+3 more lines; full report in element text]
test_old_and_new_decisions_and_statuses_match[unpinned---plain]The verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
assert False [+5 more lines; full report in element text]
test_old_verifier_accepts_new_archive_with_identical_signed_eventsThe verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
assert False [+3 more lines; full report in element text]
test_review_modules_import_without_application_stateThe verifier's readable answer was shortened (93976cde9): plain output starts with EVIDENCE instead of ASSURANCE, and frozen JSON decisions differ in note wording. Frozen fixtures need regeneration.
Error message
AssertionError: assert False [+2 more lines; full report in element text]
tools/test_deletion_semantics.py
test_deletion_of_subset_keeps_actor_and_whole_history_unknown[10--1000000000555]Expects the batch-deletion caveat "does not identify who deleted them, whether deletion applied to all participants…", shortened in 3f5f0fbcb. Pending decision: restore the caveat or update the test.
Error message
AssertionError: assert 'does not identify who deleted them' in 'Telegram reported several message IDs as deleted in one update.'
test_deletion_of_subset_keeps_actor_and_whole_history_unknown[10-55123]Expects the batch-deletion caveat "does not identify who deleted them, whether deletion applied to all participants…", shortened in 3f5f0fbcb. Pending decision: restore the caveat or update the test.
Error message
AssertionError: assert 'does not identify who deleted them' in 'Telegram reported several message IDs as deleted in one update.'
test_deletion_of_subset_keeps_actor_and_whole_history_unknown[15--1000000000555]Expects the batch-deletion caveat "does not identify who deleted them, whether deletion applied to all participants…", shortened in 3f5f0fbcb. Pending decision: restore the caveat or update the test.
Error message
AssertionError: assert 'does not identify who deleted them' in 'Telegram reported several message IDs as deleted in one update.'
test_deletion_of_subset_keeps_actor_and_whole_history_unknown[15-55123]Expects the batch-deletion caveat "does not identify who deleted them, whether deletion applied to all participants…", shortened in 3f5f0fbcb. Pending decision: restore the caveat or update the test.
Error message
AssertionError: assert 'does not identify who deleted them' in 'Telegram reported several message IDs as deleted in one update.'
test_deletion_of_subset_keeps_actor_and_whole_history_unknown[2--1000000000555]Expects the batch-deletion caveat "does not identify who deleted them, whether deletion applied to all participants…", shortened in 3f5f0fbcb. Pending decision: restore the caveat or update the test.
Error message
AssertionError: assert 'does not identify who deleted them' in 'Telegram reported several message IDs as deleted in one update.'
test_deletion_of_subset_keeps_actor_and_whole_history_unknown[2-55123]Expects the batch-deletion caveat "does not identify who deleted them, whether deletion applied to all participants…", shortened in 3f5f0fbcb. Pending decision: restore the caveat or update the test.
Error message
AssertionError: assert 'does not identify who deleted them' in 'Telegram reported several message IDs as deleted in one update.'
test_deletion_of_subset_keeps_actor_and_whole_history_unknown[9--1000000000555]Expects the batch-deletion caveat "does not identify who deleted them, whether deletion applied to all participants…", shortened in 3f5f0fbcb. Pending decision: restore the caveat or update the test.
Error message
AssertionError: assert 'does not identify who deleted them' in 'Telegram reported several message IDs as deleted in one update.'
test_deletion_of_subset_keeps_actor_and_whole_history_unknown[9-55123]Expects the batch-deletion caveat "does not identify who deleted them, whether deletion applied to all participants…", shortened in 3f5f0fbcb. Pending decision: restore the caveat or update the test.
Error message
AssertionError: assert 'does not identify who deleted them' in 'Telegram reported several message IDs as deleted in one update.'
tools/test_case_package.py
test_package_contains_readable_report_files_and_explanations[ots]Expects the heading "Timestamp receipts (not verified)", renamed in the case package.
Error message
assert ('Timestamp receipts (not verified)' in '<!doctype html><html lang="en"><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="default-src ...lank"></span></p><p>Date: <span class="blank"></span></p><p>Place: <span class="blank"></span></p></div></body></html>')test_package_contains_readable_report_files_and_explanations[tsr]Expects the heading "Timestamp receipts (not verified)", renamed in the case package.
Error message
assert ('Timestamp receipts (not verified)' in '<!doctype html><html lang="en"><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="default-src ...lank"></span></p><p>Date: <span class="blank"></span></p><p>Place: <span class="blank"></span></p></div></body></html>')
tools/test_session_import.py
test_independent_login_browser[False]The sign-in form no longer has the "other sign-in methods" block (.other-sign-in, removed in 3f5f0fbcb); the browser test still follows the old flow.
Error message
playwright._impl._errors.TimeoutError: Locator.evaluate: Timeout 30000ms exceeded. Call log: - waiting for locator(".other-sign-in")test_independent_login_browser[True]The sign-in form no longer has the "other sign-in methods" block (.other-sign-in, removed in 3f5f0fbcb); the browser test still follows the old flow.
Error message
playwright._impl._errors.TimeoutError: Locator.evaluate: Timeout 30000ms exceeded. Call log: - waiting for locator(".other-sign-in")
tools/test_verifier_dispatch.py
test_direct_check_preserves_policy_and_archive_without_printing[tgwitness.verifier.cli]Same frozen verifier decisions as test_verifier_sources.
Error message
AssertionError: assert False [+2 more lines; full report in element text]
test_direct_check_preserves_policy_and_archive_without_printing[tgwitness.verify]Same frozen verifier decisions as test_verifier_sources.
Error message
AssertionError: assert False [+2 more lines; full report in element text]
addons/capture/tests/test_trusted_anchors.py
test_cloudflare_queries_are_read_only_scoped_and_token_is_not_exportedExpects "no proof of continuous presence"; the capture add-on now says "provider state sampled at the polled time".
Error message
AssertionError: assert 'no proof of continuous presence' in 'provider state sampled at the polled time'
tools/test_analyzer_graphs.py
test_edges_cite_journal_records_across_chosen_chatsExpects the contact-graph limit "does not mean there was no contact", removed after v0.9.3.
Error message
assert False + where False = any(<generator object test_edges_cite_journal_records_across_chosen_chats.<locals>.<genexpr> at 0x7101b5b0b6b0>)
tools/test_analyzer_linking.py
test_rotated_account_ranks_first_with_explanation_and_citationsExpects the account-linking limit "not identification", removed after v0.9.3.
Error message
assert False + where False = any(<generator object test_rotated_account_ranks_first_with_explanation_and_citations.<locals>.<genexpr> at 0x7101b638d2f0>)
tools/test_chat_export_integrity.py
test_sparse_message_numbers_are_counted_without_expansionMissing-number counting now returns (numbers, count) instead of a sized collection; test not yet updated to the new API.
Error message
assert 2 == 1999999998 + where 2 = len((<tgwitness.message_numbers.MissingNumbers object at 0x7101a37e14c0>, 1))
tools/test_cli.py
test_local_commandsExpects the default workspace name "Main account"; it is now "Main workspace".
Error message
AssertionError: assert [{'workspace'...n workspace'}] == [{'workspace'...ain account'}] At index 0 diff: {'workspace': 'default', 'name': 'Main workspace'} != {'workspace': 'default', 'name': 'Main account'} Use -v to get more diff
tools/test_device_attribution.py
test_the_dossier_counts_clients_sticker_sets_and_prepared_mediaExpects the wording "Metadata hypothesis about the client that encoded the file"; the dossier now says "Client that encoded the file, read from the file's own metadata".
Error message
assert 'Metadata hypothesis about the client that encoded the file' in "Client that encoded the file, read from the file's own metadata. A forwarded or re-uploaded file carries the encoder of whoever made it first."
tools/test_mtproto_forensics.py
test_outbox_read_watermark_does_not_identify_a_personExpects the caveat that a read watermark does not identify a person, shortened in 3f5f0fbcb.
Error message
AssertionError: assert 'does not identify' in 'Observed outgoing read watermark.'
tools/test_verifier_comparison.py
test_ots_structure_only_does_not_get_a_positive_indicator[unknown]Expects an OTS-structure-only receipt to be labelled unknown; it is now labelled synthetic.
Error message
AssertionError: assert 'unknown' in 'synthetic'
tools/test_watchlists.py
test_terms_patterns_wallets_usernames_and_domains_are_matchedExpects the watchlist-hit caveat "nothing about who wrote it", removed after v0.9.3.
Error message
assert False + where False = all(<generator object test_terms_patterns_wallets_usernames_and_domains_are_matched.<locals>.<genexpr> at 0x7101b6be35a0>)
LIVE
Real accounts on a test server
Long runs with disposable test accounts and our own test chats: capture, export, independent verification. Account names, chats and message texts are not published. All live runs as JSON.
| Finished | Scenario | Result | What was checked |
|---|---|---|---|
| 2026-11-14 08:09 UTC | Online status after actions | passed | With hide-online on, the peer saw the account go offline 1.2 s after a panel action and stay offline. With it off (the default), the same action showed the account online for at least 40 s to anyone allowed to see its last seen. |
| 2026-11-14 08:01 UTC | Secret chat close, after the fix | passed | Telegram does not notify the side that accepted a secret chat when the peer ends it (confirmed with two plain clients). Since 3a614fb78 TgWitness checks accepted chats with an invisible protocol no-op: the close was recorded 61 s after it happened, with the last time the chat was known open. The peer saw no typing, read or message. |
| 2026-11-14 06:46 UTC | Secret chat close | failed | Closing on either side was not delivered by Telegram within 3 minutes: the peer saw no update. TgWitness records the close when it next tries to send, with the reason 'Telegram reports the chat no longer exists'. |
| 2026-11-14 06:39 UTC | Ghost behaviour | passed | No read receipt for a direct message or for secret messages; no typing indicator before sending in a group or a secret chat; read-only mode refused a send and nothing reached the peer. |
| 2026-11-14 06:34 UTC | Secret chats, both directions | passed | Protocol module installed from GitHub with its SHA-256 checked; an incoming request waited for manual accept; texts in both directions recorded exactly; timer, screenshot and deletion notices recorded with the earlier text kept; a PNG saved with the same SHA-256; no decryption failures. |
| 2026-11-14 06:29 UTC | Online status after actions | not observable | The test account hides last seen from everybody, so the peer only sees 'recently'; whether hide-online-after-actions works could not be observed from outside. |
| 2026-11-14 05:36 UTC | Journal export and offline verification | passed | A live test account exported its 67 MB signed journal; the bundled verifier exited 0; HTML and PDF reports were generated, including chats over time. |
| 2026-11-14 04:53 UTC | Same text in two test chats | passed | An identical message posted to two of our test chats was listed once under repeated texts, linked to both journal records. |
HISTORY
Run after run
One column per tested commit, newest on the right. Select a column or a row for the full run. Archive of all 6 runs.
| Finished | Commit | Result | Passed | Failed |
|---|---|---|---|---|
| 2026-11-14 08:29 UTC | 3a614fb78 Detect secret chats the peer ended | New failures | 2,178 | 42 |
| 2026-11-14 07:42 UTC | c06a2ba5a Improve jurisdiction guidance and report recovery (#306) | Passing, known failures listed | 1,909 | 152 |
| 2026-11-14 06:58 UTC | 0911462bc Show the chosen chats and the account on the last setup step (#305) | Passing, known failures listed | 1,912 | 79 |
| 2026-11-14 06:35 UTC | db86ca0b4 Show a chat's charts and assessment on its first export page only (#304) | Passing, known failures listed | 1,912 | 79 |
| 2026-11-14 06:24 UTC | 23c7cc65e Label service messages in reports and tidy the chat list and account counters (# | Passing, known failures listed | 1,912 | 79 |
| 2026-11-14 06:11 UTC | 29741904d Show chat export progress by messages and translate its states (#301) | New failures | 1,880 | 111 |
Raw results: tgwitness-tests-3a614fb780cd.tar.gz (all three) · summary.json · junit.xml · pytest.log · archive of all runs