420 lines
20 KiB
Markdown
420 lines
20 KiB
Markdown
# Business Risk
|
||
|
||
`Business Risk` - расчетный слой AWatch-rus, который показывает не
|
||
просто активность сотрудников, а зоны организационного риска по подразделениям.
|
||
|
||
Над ним расположен основной управленческий слой `Risk Narrative`: единая
|
||
связанная картина риска для руководителя. Он не создает новых сущностей и не
|
||
добавляет workflow, а связывает уже рассчитанные слои в один вывод:
|
||
`Trust KPI → Agent Coverage → Business Risk → Risk Heatmap → Security
|
||
Correlation → Incident Candidates → Cases`.
|
||
|
||
## Назначение
|
||
|
||
Слой предназначен для руководителя и собственника бизнеса. Он отвечает на
|
||
вопросы:
|
||
|
||
- где KPI активности нельзя считать надежным;
|
||
- где активность подразделения снижена;
|
||
- где есть падение тренда;
|
||
- где проблемные рабочие места портят доверие к отчету.
|
||
|
||
Business Risk и Risk Narrative не являются автоматическим обвинением
|
||
сотрудников или подразделений. Это read-only приоритизация управленческой
|
||
проверки.
|
||
|
||
## API
|
||
|
||
`GET /api/reports` отдает массив `business_risk`.
|
||
|
||
Элемент массива:
|
||
|
||
- `department` - подразделение;
|
||
- `trust_score` - доверие к KPI в процентах;
|
||
- `activity_score` - индекс активности подразделения в процентах;
|
||
- `trend` - `RISING`, `STABLE`, `FALLING` или `UNKNOWN`;
|
||
- `risk_level` - `LOW`, `MEDIUM`, `HIGH` или `CRITICAL`;
|
||
- `reasons` - список человеко-понятных причин риска;
|
||
- `recommendation` - рекомендуемое действие;
|
||
- `problem_nodes_count` - сколько проблемных узлов относится к подразделению;
|
||
- `missing_nodes_count` - сколько ожидаемых узлов не прислали telemetry;
|
||
- `stale_nodes_count` - сколько узлов присылали telemetry, но данные устарели.
|
||
|
||
Также `GET /api/reports` отдает управленческую сводку и историю:
|
||
|
||
- `executive_dashboard` - сводка руководителя по Trust KPI, покрытию агентов,
|
||
рискам, кандидатам, делам и готовности расследований;
|
||
- `risk_heatmap` - карта рисков подразделений по Trust KPI, активности,
|
||
покрытию агентов, открытым делам и кандидатам в инциденты;
|
||
- `security_correlation` - аналитическая связка Workforce и Security:
|
||
активность, Trust KPI, Business Risk, кандидаты и открытые дела;
|
||
- `business_risk_history` - timeline риска по подразделениям;
|
||
- `business_risk_history_summary` - сводка динамики.
|
||
- `risk_incident_candidates` - read-only кандидаты для ручной проверки.
|
||
|
||
`executive_dashboard`:
|
||
|
||
- `trust_kpi_score` - доверие к KPI активности в процентах, если доступно;
|
||
- `agent_coverage_pct` - покрытие ожидаемых рабочих мест агентами, если
|
||
настроен список expected nodes;
|
||
- `high_risk_departments` - до 10 подразделений с уровнем риска `HIGH` или
|
||
`CRITICAL`;
|
||
- `critical_candidates` - до 10 кандидатов в инциденты с уровнем `HIGH` или
|
||
`CRITICAL`;
|
||
- `open_cases` - количество открытых дел;
|
||
- `resolved_cases_30d` - количество дел, закрытых за последние 30 дней;
|
||
- `forensics_readiness` - готовность доказательного слоя: `READY`, `PARTIAL`,
|
||
`OBSERVE` или `LIMITED`;
|
||
- `summary.main_risk` - главный риск текущего среза;
|
||
- `summary.main_improvement` - главное подтвержденное улучшение;
|
||
- `summary.main_data_gap` - главный пробел в данных.
|
||
- `summary.risk_narrative_status` - optional единый статус связанной картины
|
||
риска: `NORMAL`, `ATTENTION`, `HIGH_RISK` или `CRITICAL`;
|
||
- `summary.main_risk_cause` - optional связанная причина риска:
|
||
Trust KPI, Agent Coverage, Risk Heatmap, Business Risk, Security
|
||
Correlation, Incident Candidates, Cases и готовность Forensics.
|
||
|
||
`risk_heatmap`:
|
||
|
||
- `department` - подразделение;
|
||
- `trust_kpi_score` - доверие к KPI активности, если доступно;
|
||
- `activity_score` - индекс активности подразделения, если доступен;
|
||
- `agent_coverage_pct` - оценка покрытия агентов; если список expected nodes
|
||
не настроен, поле отсутствует, а UI показывает `UNKNOWN`;
|
||
- `business_risk_level` - текущий уровень Business Risk;
|
||
- `open_cases` - открытые дела по кандидатам этого подразделения;
|
||
- `critical_candidates` - кандидаты `HIGH`/`CRITICAL`;
|
||
- `heat_level` - итоговая зона карты: `LOW`, `MEDIUM`, `HIGH`,
|
||
`CRITICAL` или `UNKNOWN`.
|
||
- `links` - optional read-only переходы к уже существующим слоям портала:
|
||
Trust KPI, Agent Coverage, Business Risk, Risk Heatmap, Security
|
||
Correlation, Incident Candidates и Cases.
|
||
- `summary` - optional связанная строка
|
||
`Trust → Coverage → Business Risk → Risk Heatmap → Security Correlation →
|
||
Candidates → Cases → вывод`.
|
||
|
||
`security_correlation`:
|
||
|
||
- `department` - подразделение;
|
||
- `trust_kpi_score` - доверие к KPI активности, если доступно;
|
||
- `activity_score` - индекс активности подразделения, если доступен;
|
||
- `business_risk_level` - уровень Business Risk;
|
||
- `critical_candidates` - число кандидатов `HIGH`/`CRITICAL`;
|
||
- `open_cases` - открытые дела по подразделению;
|
||
- `correlation_score` - сила связки Workforce и Security от 0 до 100;
|
||
- `correlation_reason` - человеко-понятное объяснение связи, например
|
||
`низкий Trust KPI + высокий риск` или
|
||
`снижение активности + рост кандидатов`.
|
||
- `explanation` - optional управленческое объяснение: какие слои связаны,
|
||
почему корреляция высокая и что это значит для руководителя.
|
||
|
||
Элемент `business_risk_history`:
|
||
|
||
- `date` - дата daily point;
|
||
- `department` - подразделение;
|
||
- `risk_level` - `LOW`, `MEDIUM`, `HIGH` или `CRITICAL`;
|
||
- `trust_score` - доверие к KPI на момент расчета;
|
||
- `activity_score` - активность подразделения;
|
||
- `reasons` - причины риска для этой точки.
|
||
|
||
`business_risk_history_summary`:
|
||
|
||
- `departments_worsened` - сколько подразделений ухудшили риск;
|
||
- `departments_improved` - сколько подразделений улучшили риск;
|
||
- `stable_high_risk` - сколько подразделений 3+ дня остаются в `HIGH`/`CRITICAL`;
|
||
- `new_high_risk` - сколько подразделений впервые вошли в `HIGH`/`CRITICAL`.
|
||
|
||
Элемент `risk_incident_candidates`:
|
||
|
||
- `id` - стабильный идентификатор кандидата;
|
||
- `department` - подразделение, если известно;
|
||
- `owner` - ответственный, если известен;
|
||
- `hostname` - рабочее место, если кандидат связан с узлом;
|
||
- `risk_level` - ориентировочный уровень риска;
|
||
- `reason` - причина постановки в очередь проверки;
|
||
- `evidence` - технические признаки, на которых основан кандидат;
|
||
- `first_seen_utc` - первое наблюдение;
|
||
- `last_seen_utc` - последнее наблюдение;
|
||
- `recommendation` - рекомендуемое действие.
|
||
- `incident_review` - статус проверки кандидата.
|
||
- `incident_review_audit` - история изменений статуса проверки кандидата.
|
||
|
||
`incident_review`:
|
||
|
||
- `candidate_id` - идентификатор кандидата;
|
||
- `status` - `NEW`, `IN_REVIEW`, `CONFIRMED`, `FALSE_POSITIVE` или `POSTPONED`;
|
||
- `reviewer` - проверяющий, если указан;
|
||
- `comment` - комментарий проверки;
|
||
- `updated_at` - время последнего изменения статуса.
|
||
|
||
`incident_review_audit`:
|
||
|
||
- `candidate_id` - идентификатор кандидата;
|
||
- `old_status` - предыдущий статус;
|
||
- `new_status` - новый статус;
|
||
- `reviewer` - проверяющий, если указан;
|
||
- `comment` - комментарий к изменению;
|
||
- `changed_at_utc` - время изменения в UTC.
|
||
|
||
Для изменения review-статуса используется:
|
||
|
||
```http
|
||
POST /api/incident-review
|
||
```
|
||
|
||
Пример тела:
|
||
|
||
```json
|
||
{
|
||
"candidate_id": "risk-candidate-example",
|
||
"status": "IN_REVIEW",
|
||
"reviewer": "operator",
|
||
"comment": "Назначена ручная проверка"
|
||
}
|
||
```
|
||
|
||
Хранение пока файловое:
|
||
|
||
```text
|
||
<state_dir>/data/incident_reviews.json
|
||
<state_dir>/data/incident_review_audit.jsonl
|
||
```
|
||
|
||
Если файла нет, все кандидаты отображаются как `NEW`.
|
||
Если audit-файла нет, портал продолжает работать, а история изменений
|
||
отображается как отсутствующая. Audit JSONL является append-only журналом:
|
||
история изменений не удаляется и не перезаписывается при смене статуса.
|
||
|
||
## Investigation Pack Export
|
||
|
||
Для каждого кандидата можно выгрузить доказательный пакет расследования:
|
||
|
||
```http
|
||
GET /api/investigation-pack/{candidate_id}
|
||
GET /api/investigation-pack/{candidate_id}?format=markdown
|
||
```
|
||
|
||
Пакет не создает инцидент автоматически и не меняет review-статус. Это только
|
||
экспорт текущего кандидата для руководителя, ИБ или внутренней проверки.
|
||
|
||
JSON/Markdown содержит:
|
||
|
||
- `candidate_id`;
|
||
- подразделение, ответственного и рабочее место;
|
||
- уровень риска;
|
||
- причины риска;
|
||
- evidence-признаки;
|
||
- первое и последнее наблюдение;
|
||
- текущий review-статус и комментарий;
|
||
- `review_audit_history`;
|
||
- `trust_kpi_snapshot`;
|
||
- `agent_quality_snapshot`;
|
||
- `business_risk_snapshot`.
|
||
|
||
Markdown-версия содержит разделы:
|
||
|
||
```text
|
||
Краткое резюме
|
||
Причины риска
|
||
Доказательства
|
||
История проверки
|
||
Снимок доверия к KPI
|
||
Качество данных агента
|
||
Бизнес-риск
|
||
Вывод
|
||
```
|
||
|
||
Если audit-файл отсутствует, пакет всё равно формируется, а раздел истории
|
||
проверки показывает, что изменения не зафиксированы.
|
||
|
||
## Логика риска
|
||
|
||
На риск влияют:
|
||
|
||
- низкий `trust_score`;
|
||
- низкий `activity_score`;
|
||
- падающий тренд активности;
|
||
- отсутствие телеметрии;
|
||
- наличие проблемных узлов в SLA покрытия агентов.
|
||
|
||
`local_fallback` не считается подтвержденным KPI. Если телеметрия свежая, но
|
||
пришла из диагностического fallback-источника, она может подтверждать факт
|
||
наличия агента, но снижает доверие к KPI и повышает бизнес-риск.
|
||
|
||
Типовые причины:
|
||
|
||
- `низкий Trust KPI`;
|
||
- `низкая активность`;
|
||
- `падающий тренд`;
|
||
- `нет свежей телеметрии`;
|
||
- `много проблемных узлов`.
|
||
|
||
## UI
|
||
|
||
В портале отображается карточка `Риски подразделений`.
|
||
|
||
Показывается ТОП-10 подразделений с максимальным риском:
|
||
|
||
- подразделение;
|
||
- уровень риска;
|
||
- причины;
|
||
- рекомендация.
|
||
|
||
Карточка `Динамика рисков` показывает:
|
||
|
||
- ухудшившиеся подразделения;
|
||
- улучшившиеся подразделения;
|
||
- стабильный высокий риск;
|
||
- новый высокий риск;
|
||
- последние точки timeline с причинами.
|
||
|
||
Карточка `Кандидаты в инциденты` показывает TOP-10 записей для ручной
|
||
проверки. Это не автоматическое создание инцидента и не подтвержденное
|
||
нарушение.
|
||
|
||
В карточке можно сменить review-статус кандидата:
|
||
|
||
- `В проверку` -> `IN_REVIEW`;
|
||
- `Подтвердить` -> `CONFIRMED`;
|
||
- `Ложный` -> `FALSE_POSITIVE`;
|
||
- `Отложить` -> `POSTPONED`.
|
||
|
||
Для каждого кандидата портал показывает текущий статус, проверяющего, время
|
||
последнего изменения, последний комментарий и раскрываемую историю изменений.
|
||
Это формирует доказательную цепочку:
|
||
|
||
```text
|
||
кандидат -> проверка -> решение -> кто/когда/почему
|
||
```
|
||
|
||
Кнопка `Скачать пакет расследования` выгружает Markdown-пакет по выбранному
|
||
кандидату без создания инцидента.
|
||
|
||
## Case Management
|
||
|
||
Подтвержденный кандидат можно вручную перевести в дело. Дело не создается
|
||
автоматически: оператор должен нажать `Создать дело` у кандидата со статусом
|
||
`CONFIRMED`.
|
||
|
||
Сущность `case`:
|
||
|
||
- `case_id`;
|
||
- `candidate_id`;
|
||
- `title`;
|
||
- `status`;
|
||
- `owner`;
|
||
- `created_at_utc`;
|
||
- `updated_at_utc`;
|
||
- `summary`;
|
||
- `decision`.
|
||
|
||
Статусы:
|
||
|
||
```text
|
||
OPEN
|
||
IN_PROGRESS
|
||
RESOLVED
|
||
REJECTED
|
||
ARCHIVED
|
||
```
|
||
|
||
API:
|
||
|
||
```http
|
||
POST /api/cases
|
||
GET /api/cases
|
||
GET /api/cases/{case_id}
|
||
GET /api/cases/{case_id}?format=markdown
|
||
POST /api/cases/{case_id}/status
|
||
```
|
||
|
||
Хранение:
|
||
|
||
```text
|
||
<state_dir>/data/cases.json
|
||
```
|
||
|
||
Правила:
|
||
|
||
- дело создается только из `CONFIRMED` кандидата;
|
||
- повторное создание для того же кандидата возвращает существующее активное
|
||
дело, если оно не архивировано;
|
||
- дело содержит ссылку на кандидата, решение и текущий Investigation Pack;
|
||
- Markdown-экспорт карточки дела включает пакет расследования, статус
|
||
проверки, audit review и решение по делу;
|
||
- создание/смена статуса дела не создает обычный инцидент автоматически.
|
||
|
||
## Markdown
|
||
|
||
Оперативный отчет выводит раздел `Связанная картина риска` первым
|
||
содержательным разделом после заголовка, даты и краткого итога. Это главный
|
||
управленческий вывод: что происходит, почему это риск и какие слои это
|
||
подтверждают.
|
||
|
||
Такой же порядок используется в UI `/portal` и `/reports`: сначала отдельная
|
||
карточка `Связанная картина риска`, затем `Сводка руководителя`, далее
|
||
доверие к KPI/качество данных, Business Risk/Heatmap/Correlation, кандидаты,
|
||
дела и технические детали. В `/api/reports` narrative остается в существующих
|
||
обратно совместимых полях: первый `executive_points[]` и
|
||
`executive_dashboard.summary.main_risk_cause`.
|
||
|
||
Оперативный отчет содержит разделы:
|
||
|
||
```text
|
||
## Связанная картина риска
|
||
## Сводка руководителя
|
||
## KPI
|
||
## Достоверность данных
|
||
## SLA покрытия агентов
|
||
## Карта рисков подразделений
|
||
## Корреляция Workforce ↔ Security
|
||
## Риски подразделений
|
||
## Динамика бизнес-рисков
|
||
## Кандидаты в инциденты
|
||
## Проверка кандидатов в инциденты
|
||
## Аудит проверки инцидентов
|
||
```
|
||
|
||
Раздел можно использовать в PDF/Markdown-отчете для руководителя.
|
||
|
||
## Executive Summary
|
||
|
||
Executive summary сначала показывает связанный управленческий вывод по Risk
|
||
Narrative, а затем только поддерживающие технические пункты. Отдельные строки
|
||
по Business Risk и кандидатам не дублируют главный вывод, если эти причины уже
|
||
вошли в narrative.
|
||
|
||
Формат:
|
||
|
||
```text
|
||
Главный управленческий вывод: В подразделении Бухгалтерия связаны слои:
|
||
Trust KPI 50%, Agent Coverage 80%, Risk Heatmap HIGH, Business Risk MEDIUM,
|
||
Security Correlation 40/100, Incident Candidates 1, Cases 0. риск связан из-за
|
||
слабого Trust KPI, падения активности, слабого покрытия агентов.
|
||
```
|
||
|
||
Если подразделение 3+ дня подряд находится в `HIGH` или `CRITICAL`,
|
||
добавляется отдельный вывод:
|
||
|
||
```text
|
||
Подразделение Бухгалтерия сохраняет высокий риск несколько дней подряд.
|
||
```
|
||
|
||
Также выводятся до 3 кандидатов в инциденты:
|
||
|
||
```text
|
||
Кандидат в инцидент risk-candidate-...: HIGH — KPI не принят
|
||
```
|
||
|
||
## Ограничения
|
||
|
||
- Это proxy-модель управленческого риска, а не юридическое заключение.
|
||
- Для точной интерпретации нужны корректные expected nodes, стабильная
|
||
telemetry и актуальные department rollups.
|
||
- Если данных по подразделению нет, риск может повышаться из-за недостаточной
|
||
доказательной базы, а не из-за фактической работы сотрудников.
|
||
- `risk_incident_candidates` - только очередь `review required`; реальные
|
||
инциденты создаются отдельно ответственным сотрудником.
|
||
- Смена `incident_review.status` не создает запись в обычной очереди
|
||
`incidents` и не подтверждает нарушение автоматически.
|