## 0.2.16 — 07.09.2026
- Тонкий онлайн-інсталятор (~0.2 МБ): не містить пакета проби, а завантажує його з центру за контрактом v0.6.0 (meta/latest → JSON → get.argusnoc.net з фолбеком на api_url → sha256 → ed25519-підпис перевіреним рантаймом). Публічний ключ центру вшито у stub і в agentd (`win/release_pubkey.txt`); непідписаний реліз відхиляється.
- Майстер stub: вибір версії (остання + до 4 старших для відкату) і необовʼязкове поле Email (для майбутніх сповіщень про недоступність проби). email → в enroll.
- Повний офлайн-інсталятор і формат пакета лишаються; автооновлення тепер теж перевіряє підпис (ключ вшито).

## 0.2.15 — 07.09.2026
- Інсталятор при запуску виявляє попередню версію і пропонує спершу її видалити: «Так» — закриває інсталятор і відкриває майстер видалення (після нього запускаєте інсталятор знову), «Ні» — інсталятор не продовжує поверх старої версії. У тихому режимі (/S) оновлення поверх лишається без запитань.
- Майстер видалення: замість запитання Так/Ні — сторінка з галочкою «Залишити попередній токен реєстрації та дані (рекомендуємо)», увімкнена за замовчуванням. Зі збереженим токеном та сама проба (той самий id) під'єднається автоматично; знята галочка видаляє токен/чергу/логи і шле центру unenroll.

## 0.2.14 — 07.09.2026
- Зміна мови у вікні тепер дійсно перемикає інтерфейс (Українська/Русский/English) — вікно перемальовується одразу, меню трею і підказка іконки теж локалізовані. Мова зберігається в HKLM і застосовується також до майстра інсталяції.
- Прибрано слово «python» з рядка старту служби в лозі (тепер «runtime»).

## 0.2.13 — 07.09.2026
- **Тільки дротове з'єднання:** проба визначає тип активного з'єднання; на Wi-Fi вимірювання призупиняються (щоб не спотворювати пінг), у лог/Event Log/подію `wifi_blocked` і жовту іконку йде «потрібне дротове». Автоматично відновлюється при підключенні кабелю.
- **Статистика тестів** у status.json і вікні: окремо Ping, Traceroute, Інші, Разом (накопичувально, `data\stats.json`).
- **Іконка в треї:** колір рахується від стану служби (SCM) + свіжості heartbeat — більше не застрягає жовтим; скрізь «ArgusNOC probe».
- **Вікно керування:** одне на систему (повторний клік активує наявне); статистика; вибір мови інтерфейсу; посилання на сайт; кнопка «Перевірити оновлення проби» з чітким результатом (діалог); показ публічного/локального IP і типу з'єднання; адресу центру приховано.
- **Інсталятор:** повний список країн світу «Назва (КОД)» за абеткою; каталог рантайму перейменовано `python\`→`runtime\`, виконувані — `argusprobe.exe`/`argusprobew.exe` (у Диспетчері задач без слова python); слово «python» прибрано з інтерфейсу.
- status.json більше не містить адреси центру у діагностиці.

## 0.2.12 — 07.09.2026
- **Служба падала в циклі** на `PermissionError: logs\probe.log` — навіть SYSTEM не міг писати в теку логів (стара занадто жорстка ACL лишилась на диску від попередніх версій і не виправлялась при оновленні). Тепер `Set-ArgusAcl` активно скидає ACL: успадкування від ProgramData (Users:Read) + явні повні права SYSTEM/Administrators рекурсивно на root/logs/data/public, видаляє старі лог-файли (служба створює наново), і лишає під замком лише `secrets.env`.
- `setup_logging` (проба і агент) більше не валить процес, якщо лог відкрити не вдалося — працює далі, повідомивши в Event Log.

## 0.2.11 — 07.09.2026
- **Головне:** ACL більше не замикає всю теку `ProgramData\ArgusNOC` на SYSTEM/Administrators — захищається лише `secrets.env` (токен). Раніше трей і вікно керування в сесії користувача діставали WinError 5 (Access denied) навіть на читання `logs\` і `status.json`, тож «Показати логи» показувало «(немає ...)», хоча файли є, а вікно падало. Тепер логи/статус читаються користувачем.
- Служба: ранній слід у `service_boot.log` ще ДО імпортів pywin32 (`_early`) — якщо процес служби падає на імпорті, причина тепер точно фіксується. Вікно керування не падає на помилках доступу до файлів.

## 0.2.10 — 06.09.2026
- Майстер інсталяції: прибрано поле «Адреса центру» (змінювати не потрібно; лишилось у тихому режимі `/CENTER=` та `$env:ARGUS_CENTER`). Додано вибір країни (список ISO-кодів, за замовчуванням UA) та поле міста. Місто — латиницею; якщо ввести кирилицею, воно транслітерується (Львів → Lviv, Запоріжжя → Zaporizhzhia). Значення запам'ятовуються (реєстр) і підставляються при повторній інсталяції.
- `probe.enroll`: нові `--country` (ISO-3166 alpha-2) і `--city`; передаються в `enroll`/`register` (`country`, `city`) — центр показує розташування без залежності від GeoIP. Тихий режим exe: `/COUNTRY=UA /CITY=Lviv`.

## 0.2.9 — 06.09.2026
- Діагностика служби без залежності від вікна: у меню трею з'явився пункт «Показати логи (діагностика)» — збирає `sc qc` обох служб, service_boot/probe.service/probe/agentd/tray-логи і status.json в один файл та відкриває його в Notepad. Це надійний канал, коли вікно не відкривається.
- Вікно керування: якщо не стартує (напр. tkinter/tcl), показує MessageBox із причиною замість тихого нічого; TCL_LIBRARY/TK_LIBRARY виставляються явно (Tcl знаходиться незалежно від робочого каталогу).
- Служба: детальні breadcrumbs у `service_boot.log` навколо `wait_for_network`, створення проби, повернення `probe.run()` (з exit_code) і `SvcStop` — щоб точно локалізувати, чому служба завершується з кодом 0.

## 0.2.8 — 06.09.2026
- **Служба зупинялася одразу, логи порожні.** Причина: на повторній інсталяції binPath служби оновлювався через `sc.exe config binPath=`, а PowerShell 5.1 псує вкладені лапки навколо шляху з пробілом («Program Files») — SCM не міг запустити python.exe, тож процес навіть не стартував. Тепер служби завжди створюються наново через `New-Service` (.NET зберігає рядок як є); інсталятор друкує реальний BINARY_PATH_NAME з `sc qc` для контролю.
- Діагностика служби: `logs\service_boot.log` (пряме дописування ще до налаштування logging — ловить помилки хостингу/імпорту), ранній file-handler для `probe.service.log`, збій `StartServiceCtrlDispatcher` пишеться в лог і Event Log. Вікно керування відкриває найінформативніший журнал (не порожній probe.log), «Копіювати діагностику» включає boot/service-логи.

## 0.2.7 — 06.09.2026
- Трей не стартував: `win32gui.SetTimer` відсутній у pywin32 цього рантайму. Періодичне оновлення тепер робить фоновий потік, що шле вікну власне повідомлення (PostMessage), а не WM_TIMER. `SetMenuDefaultItem`/`GetCursorPos` викликаються захищено (є не в усіх складаннях). Це виправляє помилку «module 'win32gui' has no attribute 'SetTimer'» і зникнення іконки.

## 0.2.6 — 06.09.2026
- Повторна інсталяція падала з «Access to install.json is denied»: цей файл лишався з минулого разу з ACL лише для SYSTEM/Administrators, а його перезапис я помилково зробив критичним. Тепер org/ім'я/центр/мова пишуться насамперед у реєстр (`HKLM\Software\ArgusNOC`), а `install.json` — best-effort (скидання read-only/ACL + запис через тимчасовий файл; невдача не зупиняє інсталяцію). Читання має запасне джерело — реєстр.

## 0.2.5 — 06.09.2026
- Служба показувала «зупинено»: `SvcRun` при штатній зупинці репортив STOP_PENDING замість SERVICE_STOPPED, через що SCM лишав службу у проміжному стані. Тепер завжди фінально SERVICE_STOPPED (ненульовий код → ERROR_SERVICE_SPECIFIC_ERROR → recovery). Вихід через відсутній токен (код 2) більше не крутить recovery, а лишає зрозумілий запис у Event Log; будь-який крах проби пише трасу в Event Log.
- Вікно керування (подвійний клік на іконці в треї або пункт «Відкрити вікно…»): стан служби і проби (ім'я/id, online/pending, версія, IPv6/NAT, центр, останній heartbeat), кнопки Запустити/Зупинити/Перезапустити/Оновити (UAC), перегляд останніх рядків probe.log / agentd.log / служби і подій Windows (ArgusNOC) з автооновленням, «Копіювати діагностику». Реалізація — tkinter (окремий процес).
- Реліз більше не вирізає tkinter/tcl — потрібні для вікна (zip трохи більший).

## 0.2.4 — 06.09.2026
- Трей на Windows 11: іконка додається успішно, але потрапляє в overflow (^) — стандартна поведінка Win11. Промоушен на панель (`NotifyIconSettings\IsPromoted`) тепер із ширшим матчем шляху, повторним додаванням іконки (щоб explorer перечитав) і логуванням; `NIM_ADD` логує успіх. Якщо не спрацює — іконку видно за стрілкою `^`, закріпити можна в Параметрах панелі завдань.
- `tray.py --debug` тепер запускає діагностичний екземпляр навіть коли автозапуск уже підняв трей (раніше писав «already running» і виходив).

## 0.2.3 — 06.09.2026
- Виправлено корінь проблем повторної інсталяції: після зупинки служб SCM (recovery) і watchdog ArgusAgentd піднімали ArgusProbe знову посеред інсталяції → `PermissionError` на `data\firewall_applied.json` і «проба ще не відзвітувала в лог». Тепер перед заміною файлів обидві служби переводяться в Disabled без recovery (agentd першим), потім стоп, трей, процеси з каталогу коду; `Set-ArgusServices` повертає Automatic + recovery. `Stop-ArgusService` знімає recovery перед kill.
- setup.exe: три мови (English типово, Українська, Русский) з вибором на першому екрані; авто — uk для української системи, інакше en; `/LANG=uk|ru|en`; деінсталятор тією ж мовою.
- Інсталятор пам'ятає організацію, ім'я проби, центр і мову (`HKLM\Software\ArgusNOC`, `ProgramData\ArgusNOC\install.json`) — переживає повне видалення, підставляється при наступній інсталяції (`install.ps1` теж).
- Вікно деталей інсталятора: технічний лог англійською (nsExec читає ANSI — кирилиця ставала «◆◆◆»), повідомлення користувачу локалізовані; сторінка параметрів — більше місця під написи.
- Трей: MessageBox з текстом помилки, якщо не стартував; `python.exe win\tray.py --debug` — лог у консоль; `firewall.py` не падає, якщо кеш-файл зайнятий.

## 0.2.2 — 06.09.2026
- setup.exe завжди зупиняє служби, трей і всі процеси з каталогу коду попередньої версії перед копіюванням (`preinstall.ps1`) — повторна інсталяція поверх працюючої проходить без ручних дій.
- Трей: запуск через `tray_start.ps1` (explorer.exe → без підвищення; fallback — прямий запуск), перевірка, що процес живий, і діагностика у вікні інсталятора; `tray.log` пишеться ще до імпорту pywin32; на Windows 11 іконка сама просить показати себе на панелі (`NotifyIconSettings\IsPromoted`); balloon при старті.

## 0.2.1 — 06.09.2026
- setup.exe: PowerShell-кроки запускались у 32-бітному PowerShell (інсталятор NSIS — 32-бітний процес), де `%ProgramFiles%` = `Program Files (x86)` → `postinstall.ps1` падав до реєстрації. Тепер 64-бітний PowerShell через `Sysnative`, каталог коду скрипти беруть зі свого розташування.
- `postinstall.ps1`: повний try/catch зі стеком і діагностичним рядком (PowerShell, розрядність, Base) у вікні інсталятора.

## 0.2.0 — 06.09.2026
Windows-порт (ТЗ TZ-windows-probe v1.1).
- Спільний код Linux/Windows: вибір виконавців у `probe/plat.py`; `config.py` розділяє BASE (код) і ROOT (дані).
- `probe/enroll.py` — самореєстрація на центрі (`POST /probe/enroll`, локальний токен, повтори, повторна інсталяція зберігає токен; `--unenroll`).
- Проба: коректна зупинка (`request_stop`/`stop_threadsafe` → незлиті метрики в чергу, закриття сокетів), 3×401 → «probe removed on center»
  (виміри стоп, register раз на 5 хв), стан `pending` у лозі, інтервали heartbeat/flush перечитуються з конфігу без рестарту.
- Windows: служби ArgusProbe/ArgusAgentd (pywin32, LocalSystem, PRESHUTDOWN, recovery), ICMP-движок на raw-сокетах
  (`runners/win_ping.py`, `win_mtr.py`), фаєрвол `ArgusNOC:*` через netsh, Event Log, sysinfo/diag, автооновлення через
  відв'язаний `update.ps1` з відкатом, `install.ps1` (`irm … | iex`), `uninstall.ps1`, `build_release.py` (embeddable Python або python-build-standalone, pip --target).
- agentd: `data/update.lock` — watchdog/updater не втручаються під час заміни коду; `run(stop_event)` для служби.
- NAT: `register`/`enroll` шлють `nat`, `local_ipv4/6`, `capabilities.kick`; `kick_listen: auto|true|false` у config.yaml — за NAT agentd не слухає :8710, команди йдуть через heartbeat.
- IPv6: has_ipv6 = глобальна адреса (без Teredo/6to4) + реальна зв'язність (пінг v6-резолверів); повторна перевірка IPv6/NAT/адрес кожні 5 хв, зміна → подія `network_changed`, новий HTTP-клієнт, re-register.
- setup.exe (NSIS): майстер/тихий режим, «Програми та компоненти», uninstall.exe, відкат при невдалій реєстрації; трей-іконка `win/tray.py` (стан, версія, старт/стоп, оновлення), `public\status.json` від проби.
- iperf на Windows не підтримується (`ok:false`).

