# Аннотации Telegram со ссылками на исходные записи

Canonical page: https://phishdestroy.github.io/TgWitness/ru/docs/reference/case-board/

Закладки, точные выделения, фрагменты действий, обсуждения, ограниченный доступ и история подписанных аннотаций, используемые в Case Board.

[Project context and measured scale](https://phishdestroy.github.io/TgWitness/ru/docs/reference/overview/)

[Documentation index](https://phishdestroy.github.io/TgWitness/ru/llms.txt)

Закладки, точные выделения, фрагменты действий, обсуждения, ограниченный доступ и история подписанных аннотаций, используемые в Case Board.

[TgWitness](https://github.com/phishdestroy/TgWitness/blob/main/README.md) / [Документация](https://github.com/phishdestroy/TgWitness/blob/main/docs/README.md) · [Расследование](https://phishdestroy.github.io/TgWitness/ru/docs/reference/investigation/)

![Расследование](https://phishdestroy.github.io/TgWitness/assets/chapter-investigate.svg)

Case Board предоставляет следственной группе общий рабочий обзор сохраненных материалов. Добавляйте в закладки наблюдения, выделяйте конкретные фрагменты, сохраняйте набор действий и обсуждайте их с коллегами. Карточки сохраняют ссылки на источники и подписанную историю изменений. Аннотации команды остаются в рабочей области и четко отделяются от исходных наблюдений в Telegram.

[Модель доказательств](https://phishdestroy.github.io/TgWitness/ru/docs/reference/evidence/) · [Доступ](https://phishdestroy.github.io/TgWitness/ru/docs/reference/access/) · [Отчёты](https://phishdestroy.github.io/TgWitness/ru/docs/reference/case-reports/)

![Синтетическая лента расследования](https://phishdestroy.github.io/TgWitness/assets/case-board.png)

**На этой странице**

- [Работа с делом](https://phishdestroy.github.io/TgWitness/ru/docs/reference/case-board/#work-with-a-case)
- [Права доступа](https://phishdestroy.github.io/TgWitness/ru/docs/reference/case-board/#permissions)
- [Сохраненные контракты](https://phishdestroy.github.io/TgWitness/ru/docs/reference/case-board/#stored-contracts)
- [API и экспортные данные](https://phishdestroy.github.io/TgWitness/ru/docs/reference/case-board/#api-and-exports)
- [Пределы эксплуатации](https://phishdestroy.github.io/TgWitness/ru/docs/reference/case-board/#operating-limits)

## Работа с делом

Откройте **«Расследование» → «Case Board»** в стандартном или экспертном режиме. Язык зависит от панели. Используйте **кнопку** **«Добавить в доску»** рядом с записью в журнале или сохраненным сообщением в чате, либо выделите его и нажмите **B**. Закладка добавляется в «Входящие» одним щелчком. Отредактируйте её название, метки и примечание или переместите её в коллекцию. К измененной карточке добавляется подписанная версия; при удалении сохраняется история изменений.

Для первого дела выберите сбор данных и добавьте записи, отвечающие на один вопрос. Используйте комментарии для проверки интерпретации, а затем **раздел «Презентация»**, чтобы пройтись по карточкам и контексту источников. При подготовке итогового документа выбирайте материалы для «Case Board» отдельно в [«Report Studio](https://phishdestroy.github.io/TgWitness/ru/docs/reference/case-reports/)». Сохранение фрагмента не приводит к автоматической настройке фильтров данных отчета.

Выделите текст внутри сохраненного сообщения в чате, чтобы открыть **меню «Выделить» → «Доска**». Выберите цвет и добавьте заметку. Сервер проверяет точность цитаты и сохраненной версии, включая эмодзи, текст с направлением написания справа налево (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`](https://github.com/phishdestroy/TgWitness/blob/main/tgwitness/schemas/board-bookmark.json) и генерируются из моделей 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 для проверки хранения, доступа, отображения и экспорта. См. [раздел «Объем проверки»](https://phishdestroy.github.io/TgWitness/ru/docs/reference/evidence/#verification-scope) для ознакомления с объемом проверки доказательств.
