# Workforce Operations Model Статус: implemented in Worktime API and DetMir portal. Модель отвечает на главный управленческий вопрос AWatch-rus Workforce: рабочая активность сотрудников, загрузка, простои, перегруз и дисциплина рабочего процесса. Это rule-based слой операционного контроля. Он не является HR-оценкой, не использует ML/LLM и не выполняет автоматических санкций. ## Где смотреть Основные точки: - Worktime API: `GET /reports/worktime/management?format=json`; - Worktime HTML: `GET /reports/worktime/management?format=html`; - DetMir portal: `/api/reports`, блок `workforce_operations`; - UI портала: роли `Руководитель` и вкладка `Отчеты`, блок `Операционная загрузка`. ## Источники Модель использует только подтвержденные рабочие источники: - ActivityWatch worktime rows; - bucket рабочих сессий RDP; - интервалы активности в рабочем окне; - configured owner/department aliases; - freshness/coverage metadata, которые уже возвращает Worktime API. Отсутствие данных не считается простоем. При пропусках источников строка получает `data_confidence=low` и guardrail `low_confidence_not_for_discipline`. ## Runtime-настройки Основной файл политики: - пример: `configs/worktime-interpretation-policy.example.json`; - runtime: `/etc/activitywatch/worktime-interpretation-policy.json`; - env path: `AW_WORKTIME_MANAGER_INTERPRETATION_POLICY`. Поля policy: | Поле | Смысл | Рекомендуемое значение | | --- | --- | --- | | `underload_threshold` | порог недогруза от рабочего окна | `0.35..0.45` | | `overload_threshold` | порог перегруза от рабочего окна | `1.10..1.25` | | `drop_threshold_pct` | порог просадки тренда | `10..25` | | `night_work_after` | начало вечернего/ночного отклонения | `20:00` | | `weekend_work` | учитывать выходные отклонения | `true` | | `min_trend_points` | минимум daily points для тренда | `3..7` | | `off_hours_threshold_seconds` | минимум внерабочей активности для флага | `1800` | `underload_threshold` и `overload_threshold` можно задавать дробью или процентом: `0.45` равно `45`, `1.15` равно `115`. Для перегруза effective threshold fail-closed зажат в диапазон `100..300`, чтобы значение ниже 100% не создавало ложный статус перегруза. Env fallback: - `AW_WORKTIME_MANAGER_TARGET_COVERAGE_PCT`; - `AW_WORKTIME_MANAGER_LOW_COVERAGE_PCT`; - `AW_WORKTIME_MANAGER_OVERLOAD_COVERAGE_PCT`; - `AW_WORKTIME_MANAGER_TREND_MIN_POINTS`; - `AW_WORKTIME_MANAGER_TREND_DELTA_PCT`; - `AW_WORKTIME_MANAGER_OFF_HOURS_THRESHOLD_SECONDS`; - `AW_WORKTIME_MANAGER_NIGHT_WORK_AFTER`; - `AW_WORKTIME_MANAGER_WEEKEND_WORK_ENABLED`. Веса приложений остаются отдельной политикой: - пример: `configs/detmir-workforce-policy.example.json`; - runtime: `/etc/detmir-portal-workforce-policy.json`. Она влияет на explainable KPI и weighted activity, но не подменяет операционные статусы загрузки/простоя. ## API contract `/reports/worktime/management?format=json` содержит: ```json { "workday": { "target_coverage_pct": 75, "low_coverage_pct": 35, "overload_coverage_pct": 115 }, "workforce_operations": { "status": "ATTENTION", "summary": {}, "rows": [], "model": { "type": "rule_based", "ml": false, "llm": false, "version": "workforce-operations-v1" } } } ``` Каждая строка сотрудника содержит: - `workday_active_seconds`, `workday_active_hhmm`; - `workday_idle_seconds`, `workday_idle_hhmm`; - `coverage_pct`; - `load_status`; - `idle_status`; - `discipline_status`; - `data_confidence`; - `recommended_action`. Полный roster в `rows[]` дополнительно содержит `operations`, `operations.evidence`, `operations.guardrail` и `operations_recommended_action`. ## Статусы загрузки | Status | Значение | Действие | | --- | --- | --- | | `insufficient_data` | рабочее окно еще не началось или равно нулю | не делать вывод | | `no_data` | нет сессий или worktime samples | проверить источники | | `no_activity` | сессия/данные есть, активности в окне нет | проверить присутствие и задачи | | `underloaded` | ниже low threshold | проверить загрузку и доступ к процессам | | `below_target` | ниже target threshold | уточнить причину отклонения | | `normal` | в рабочем диапазоне | наблюдать | | `overloaded` | выше overload threshold | проверить переработку и риск аврала | ## Статусы простоя | Status | Значение | | --- | --- | | `not_applicable` | нет рабочего окна | | `unknown` | нет достаточных источников | | `full_workday_idle_or_absent` | активность в рабочем окне отсутствует | | `idle_detected` | простой выше порога | | `no_significant_idle` | существенный простой не найден | ## Дисциплина процесса `discipline_status` показывает отклонение от рабочего процесса, а не автоматическое нарушение: - `ok`; - `off_hours`; - `late_start`; - `early_finish`; - `multiple_flags`. Для текущего дня `early_finish` не выставляется до завершения рабочего окна. ## Достоверность `data_confidence`: - `high`: есть session samples, worktime samples и active samples; - `medium`: данных мало или нет active samples; - `low`: нет сессий/worktime samples или рабочее окно невалидно. Правило: low confidence строки сначала проверяются как проблема источников. Их нельзя использовать как персональный дисциплинарный вывод. ## Summary `workforce_operations.summary` содержит: - `users_count`; - `action_required_users`; - `load.unknown_or_no_data_users`; - `load.underloaded_users`; - `load.normal_users`; - `load.overloaded_users`; - `idle.idle_users`; - `discipline.review_users`; - `confidence.low_users`; - `confidence.medium_users`; - `confidence.high_users`; - `guardrail`. Summary status: - `LOW_CONFIDENCE`: нет строк или все строки low confidence; - `ATTENTION`: есть перегруз, простой или дисциплинарные флаги; - `WATCH`: есть недогруз, нет данных или low confidence; - `OK`: отклонений нет. ## UI contract Портал показывает отдельный блок `Операционная загрузка`: - сводка: требуют разбора, недогруз, перегруз, простой, дисциплина, low confidence; - таблица сотрудников: active/idle/coverage/load/idle/discipline/confidence; - рекомендуемое действие; - guardrail и версию rule-based модели. Это отдельный блок от `Почему такой индекс активности?`: explainable KPI отвечает на вопрос "почему такой процент", а Workforce Operations отвечает "кого и почему нужно разобрать". ## Ограничения - Не утверждать автоматическую оценку эффективности сотрудника. - Не считать missing data простоем. - Не смешивать Security/Forensics claims с Workforce Operations. - Не заявлять ML/LLM detection. - Не выполнять автоматическое remediation/action. - Не использовать GitHub Actions или демо-данные как registry release evidence. ## Проверка после изменения Минимальный локальный контур: ```bash cd /mnt/usb_hdd2/Projects/ActivityWatch-Russian/adk-rust export CARGO_TARGET_DIR=/home/igor/.cache/detmir-adk-rust-target cargo fmt --all --check cargo test -p worktime-api -p detmir-portal --locked cargo clippy -p worktime-api -p detmir-portal --all-targets --locked -- -D warnings ``` Минимальный live smoke: ```bash curl -fsS 'http://10.10.10.13:5610/reports/worktime/management?format=json' \ | jq '.workforce_operations.summary' curl -fsS 'http://10.10.10.2:8720/api/reports?role=manager' \ | jq '{status: .workforce_operations.summary.status, rows: (.workforce_operations.rows | length)}' ``` Браузерный smoke: открыть `http://10.10.10.2:8720/`, выбрать представление менеджера и проверить блок `Операционная загрузка`. В рабочем состоянии должны быть видны summary-карточки, таблица сотрудников, `workforce-operations-v1` и guardrail про `low confidence`.