Справочник / Архив и интеграции
Аннотации Telegram со ссылками на исходные записи
Закладки, точные выделения, фрагменты действий, обсуждения, ограниченный доступ и история подписанных аннотаций, используемые в Case Board.
TgWitness / Документация · Расследование
Case Board предоставляет следственной группе общий рабочий обзор сохраненных материалов. Добавляйте в закладки наблюдения, выделяйте конкретные фрагменты, сохраняйте набор действий и обсуждайте их с коллегами. Карточки сохраняют ссылки на источники и подписанную историю изменений. Аннотации команды остаются в рабочей области и четко отделяются от исходных наблюдений в Telegram.
Модель доказательств · Доступ · Отчёты

На этой странице
Работа с делом#
Откройте «Расследование» → «Case Board» в стандартном или экспертном режиме. Язык зависит от панели. Используйте кнопку «Добавить в доску» рядом с записью в журнале или сохраненным сообщением в чате, либо выделите его и нажмите B. Закладка добавляется в «Входящие» одним щелчком. Отредактируйте её название, метки и примечание или переместите её в коллекцию. К измененной карточке добавляется подписанная версия; при удалении сохраняется история изменений.
Для первого дела выберите сбор данных и добавьте записи, отвечающие на один вопрос. Используйте комментарии для проверки интерпретации, а затем раздел «Презентация», чтобы пройтись по карточкам и контексту источников. При подготовке итогового документа выбирайте материалы для «Case Board» отдельно в «Report Studio». Сохранение фрагмента не приводит к автоматической настройке фильтров данных отчета.
Выделите текст внутри сохраненного сообщения в чате, чтобы открыть меню «Выделить» → «Доска». Выберите цвет и добавьте заметку. Сервер проверяет точность цитаты и сохраненной версии, включая эмодзи, текст с направлением написания справа налево (RTL) и комбинирующие знаки. Интерфейс не отображает выделенный фрагмент в замаскированном или преобразованном тексте.
Нажмите Shift и щелкните две записи в одном чате, чтобы выделить фрагмент между ними, воспользуйтесь функцией «Выделить по времени» или сохраните текущие фильтры журнала по чату, периоду и типу события. Сохраненный фрагмент имеет собственное авторитетное условие: при его открытии в журнале также применяются фильтры по нескольким чатам, ограничения по количеству сообщений и фильтры по участникам . Функция «Показать записи, добавленные после закладки» выделяет более поздние добавления. Изменение фильтров в Journal приводит к выходу из фрагмента. В разделе «Люди» функция «Выделить действия этого человека» использует записанный ID участника; она не предполагает, что автор сообщения редактировал, удалял или реагировал на сообщение.
В диалоговом окне выбора фрагмента перед созданием отображается предварительный просмотр количества записей. Термин «all» (все) включает все типы записей,
в том числе снимки экрана, правки, удаления, реакции, обновления членства/сервиса, собственные действия,
кнопки, мультимедийные результаты, восстановленные сообщения и типы будущих событий. Выбор описывает
сохраненные наблюдения. Уведомления об удалении неизвестных чатов представляют собой отдельный контекст,
доступный только при полном доступе к рабочей области и никогда не привязанный к одному из выбранных чатов.
Коллекции имеют заданную область охвата чатов. Пустая область охвата означает всю рабочую область. Коллекция не может содержать карточки, выходящие за пределы её области охвата; участник, доступ к которому ограничен конкретным чатом, не может просматривать более широкую коллекцию. «Входящие» — это виртуальная коллекция для неназначенных карточек. Поиск и фильтры охватывают только видимые карточки; ветки обсуждений и упоминания наследуют права доступа родительской карточки. Удалённые комментарии имеют метку «удалён» в обсуждении. История просмотров не записывается.
В режиме презентации открываются все карточки в выбранной коллекции с видами «Карточка», «Контекст источника» и «Комментарии команды», а также с клавишами «Назад» и «Вперед». В этом режиме отсутствуют элементы управления для редактирования. Обычная лента имеет разбивку на страницы; в режиме презентации список загружается по страницам, и подробная информация по одной карточке отображается за раз.
Разрешения#
Все операции требуют доступа к view, рабочей области/чату и board.read. board.write добавляет карточки,
комментарии, перемещает и устанавливает статусы «открыто»/«на рассмотрении». board.manage позволяет управлять коллекцией,
устанавливать статусы «подтверждено»/«отклонено», а также редактировать или удалять чужие карточки. Статус является
решением команды, а не результатом криптографической проверки.
Доступ к предустановкам форм: «Рецензент» = чтение; «Аналитик» = чтение/запись; «Оператор» = чтение/запись/управление, в дополнение к их существующим правам. Существующие права не приводят к автоматическому получению новых прав. Главный администратор обладает всеми правами и публикует сообщения как «Главный администратор». Используйте именованные права доступа для указания авторства. В списке упоминаний перечислены только те текущие пользователи, которые имеют доступ к просмотру полной родительской карточки.
Пользователь чата A не может получить карту или фрагмент для A+B, даже угадав его ID или указав
ложный target.chat_id. Метаданные целевого объекта определяются на сервере по подписанному хешу события.
Перед отправкой ответа фильтруются коллекции, количество обсуждений, связанные карты и оперативные уведомления.
Для экспорта требуется как export, так и board.read; существующий экспортер без доступа к доске получает
обычный архив доказательств без заметок команды. SSE повторно проверяет текущие разрешения перед каждой партией.
Сохраненные контракты#
Как и наблюдения, аннотации записываются транзакционно в таблицу SQLite с добавлением только данных в
рабочей области. Файл annotations.jsonl представляет собой точный канонический экспорт из того же моментального снимка для чтения, что и
events.jsonl. Не существует второго конкурирующего хранилища аннотаций, а также события журнала board.activity.
Каждая строка должна содержать именно:
{
"seq": 1,
"at": "2026-11-02T14:00:00.000+00:00",
"access_id": "admin",
"access_label": "Main administrator",
"kind": "board.bookmark",
"payload": {"id": "32 lowercase hex digits", "target": {"event_hash": "64 lowercase hex digits"}},
"previous_hash": "64 zeroes for the first record",
"hash": "SHA-256 described below",
"signature": "base64 Ed25519 signature"
}
Приведенный выше сокращенный пример иллюстрирует конверт; фактические полезные нагрузки включают свои
значения по умолчанию и целевые поля, определяемые сервером. Схемы запросов API находятся в каталоге
tgwitness/schemas и генерируются из моделей Pydantic
во время выполнения с помощью скрипта python tools/build_board_schemas.py. Дополнительные поля запроса отклоняются. Идентификаторы
генерируются на стороне сервера, если они опущены. Авторство, время, моментальный снимок и подпись не могут быть указаны
вызывающей стороной. Идентификаторы именованных разрешений соответствуют существующему 16-шестнадцатеричному формату Access; идентификаторы карт — 32-шестнадцатеричные.
Канонический JSON — это UTF-8, отсортированные ключи объектов, отсутствие пробелов между токенами, неэкранированный Unicode,
а также отсутствие значений NaN и бесконечности. Хеш аннотации — это SHA-256 канонического объекта, содержащего тег
format: "tgwitness-annotations-v1", а также все семь полей конверта вплоть до previous_hash.
Этот тег формата отделяет домен хеша от наблюдений. Подпись формируется с помощью алгоритма Ed25519 над
32 байтами исходного хеша. Нумерация начинается с 1. Ревизии сохраняют идентификатор карты и указывают предыдущий
хэш аннотации в поле «supersedes»; они не могут изменять область действия чата. Перемещения, статусы и удаления представляют собой
отдельные записи. Таблица SQLite не допускает операций UPDATE и DELETE.
Файл case-board.json содержит {statement, signature}. Каноническое заявление подписывается
ключом рабочей области и содержит format: "tgwitness-case-board-v1", public_key, created_at,
journal_head, meaning и state. Состояние представляет собой детерминированное воспроизведение: annotations_head,
упорядоченный массив items (коллекции, карточки, комментарии, включая «надгробные камни») и status_history.
Элементы сохраняют хеш последней аннотации, последовательность, автора и время, а также исходного
создателя и время создания при всех ревизиях. Воспроизведение проверяет ревизии,
родители, ссылки на коллекции и дубликаты идентификаторов действий. Файлы `manifest.json` и новые контрольные точки
также связывают `annotations_head`. Сохраняйте контрольную точку независимо, чтобы обнаружить усечение или перезапись
с использованием скопированного ключа подписи.
Текстовые версии#
range.start — это смещение кодовой точки Unicode с нулевой базой, length — положительное число кодовых точек,
а quote должно равняться точной подстроке из payload.text или payload.caption в целевом
событии. Не применяются NFC/NFKC, преобразование регистра или нормализация графем. Срезки строк в Python и
метод JavaScript `Array.from(text)` реализуют ту же индексацию. Сочетание знаков и эмодзи ZWJ может
занимать несколько кодовых точек. `range.version` — это хеш целевого события, а не текущая версия сообщения
или смещение UTF-16-сущности в Telegram. Последующие правки никогда не перемещают выделение автоматически.
Выделение идентификаторов и времени#
query принимает ровно один chat_id или непустой набор chat_ids, опциональные диапазоны from/to с включением границ,
диапазоны message-ID с включением границ (только для одного чата), kinds: "all" или точные/префиксные виды с подстановочными знаками,
явно указанных actors, search, hide_system и include_unscoped. Группы видов журнала расширяются до
их точных предикатов. Поиск использует поиск по полезной нагрузке журнала с учетом NFC и игнорированием регистра без изменения
подписанного исходного текста. Даты требуют указания часового пояса и нормализуются до UTC.
Даты фильтруют поле `observed_at`. Поле `source_at` из Telegram отображается отдельно. Удаление без
метаданных источника не имеет вымышленного времени удаления. Поздняя запись, обнаруженная за пределами временного интервала,
не попадает в него; фрагмент по идентификаторам сообщений может включать более позднее удаление для этих идентификаторов.
«snapshot» фиксирует время создания, границу последовательности/хеша журнала, количество совпадений, первую/последнюю
последовательность и result_hash. Последний представляет собой SHA-256 канонического массива JSON в кодировке UTF-8, содержащего хеши совпадающих
событий, отсортированные в лексикографическом порядке, включая [] для пустого фрагмента. Он также содержит точное
количество типов и миниатюру времени наблюдения с 24 бинами. Фрагмент хранит запрос, а не дубликаты исходных
записей. При экспорте файл board/slices/<id>.json перечисляет текущие хеши и добавленные/удалённые последовательности.
Верификатор восстанавливает исходный результат на границе создания, а затем — текущий результат.
Добавленные записи фиксируются как факт изменения. Удаление исходного события нарушает неизменяемую
цепочку доказательств; оно не принимается без предупреждения как обычное удаление из среза.
Снимки реакций содержат неполные списки недавних участников. Программа просмотра сравнивает соседние снимки одного и того же чата/сообщения, включая предшествующий снимок, находящийся за пределами фрагмента, и сообщает об агрегированных разностях между наблюдениями. Отсутствие недавних участников не означает, что реакция была удалена. Первый снимок не имеет выведенного более раннего состояния. Наблюдения за участниками остаются привязанными к тому снимку, в котором они были предоставлены, а не к вымышленному времени действия.
API и экспорт данных#
GET /api/board принимает collection/chat/author/label/state/from/to/q/kind/comments, offset/limit
и порядок newest/oldest. GET /api/board/card/{id} возвращает карту, предварительный просмотр источника, ветку,
историю статусов и связанные карты. Подраут «участники» возвращает подходящие варианты упоминаний.
POST /api/board/{bookmark|highlight|slice|collection|comment|status|move|remove} добавляет запись.
POST /api/board/slice-preview вычисляет запрос. Записи фрагмента paginated при
GET /api/board/slice/{id}/records; при повторном вычислении всегда используется текущий стабильный снэпшот чтения.
Live /api/stream передаёт уведомления board без полезной нагрузки, отдельно от курсоров журнала.
GET /api/board/export возвращает подписанный документ. Пользователи с ограниченным доступом к чату получают четко маркированное
подписанное раскрытие информации, но никогда не получают аннотации из других чатов или полную цепочку сообщений. ZIP-архивы с полными доказательствами
содержат файл annotations.jsonl, подписанный файл case-board.json и приложения в формате JSON с фрагментами данных. Настройки отчёта в формате
HTML/PDF/JSON позволяют выбрать вариант без доски, закладки/фрагменты без обсуждения или карточки с комментариями. В
разделе чётко отделены мнения команды от наблюдений. Фильтры данных отчёта также ограничивают
доступные для чтения заметки; полные подписанные исходные файлы в ZIP-архиве с доказательствами остаются в полном объёме.
GET /api/board/slice/{id}/export генерирует подписанный фрагмент JSON в формате tgwitness-board-selection-v1;
?format=csv генерирует удобную таблицу без отдельной подписи. Сохраните JSON и ZIP:
python -m tgwitness.verify evidence.zip --fingerprint TRUSTED_KEY_SHA256 --board
python -m tgwitness.verify board-slice.json --evidence evidence.zip --fingerprint TRUSTED_KEY_SHA256
python -m tgwitness.verify case-board.json --evidence evidence.zip --fingerprint TRUSTED_KEY_SHA256
Проверка выбора подтверждает подлинность подписанного заявления, точность исходных записей и полноту запроса в пределах указанного диапазона. ZIP-архив с доказательствами может быть более поздней версии, но должен содержать этот префикс. О отсутствующей цели сообщается явно. Несоответствие оригинального снимка фрагмента, изменение аннотации, несовпадение состояния воспроизведения или изменение источника приводят к сбою. Старые архивы без аннотаций сохраняют своё существующее поведение при проверке.
По умолчанию для передачи установлено значение «Не включать». Явное включение отображает карточки проектов в уже
сжатых записях, опускает недоступные/пропущенные объекты, утаивает выделенные фрагменты, исходный текст которых
был сжат, очищает текст команды с применением тех же правил упоминаний/контактов и, по желанию, заменяет
метки следователей на R01, R02… в метаданных и известных вхождениях в заметках. Исходный файл
annotations.jsonl не раскрывается. Подписанный файtgwitness-case-board-handover-v1-sidecar и отчет
содержат один и тот же сжатый материал. Количество фрагментов описывает только раскрытые записи, при этом исходные
детали участника моментального снимка/запроса не раскрываются. Имена в свободном тексте, неизвестные программе минимизации, по-прежнему требуют
проверки, как и при обычной передаче материалов. Данный производный файл не претендует на сохранение исходных
подписей аннотаций после редактирования.
Ограничения использования#
Параметры включают мягкие ограничения: 10 000 карточек и 50 000 комментариев, страницу фрагмента до 5 000 записей и управление предварительным просмотром медиафайлов. При превышении мягких ограничений выдается предупреждение без удаления истории. Страницы ленты содержат не более 200 карточек. Размер автономных выдержек в формате JSON ограничен 64 MiB; для больших объемов данных сузьте запрос или используйте подписанный ZIP-архив. Автономный верификатор ограничивает воспроизведение аннотаций 256 MiB. Case Board не поддерживает и не реализует уведомления о внешних комментариях.
Автоматизированный прием функции использует фиктивные данные и имитированную передачу данных через Telegram для проверки хранения, доступа, отображения и экспорта. См. раздел «Объем проверки» для ознакомления с объемом проверки доказательств.