Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
13 commits
Select commit Hold shift + click to select a range
8a35d92
Зафиксировать базовое состояние перед production-hardening
Sep 11, 2026
34c0f59
Ввести авторитетную модель версии RC/stable
Sep 11, 2026
89df65f
Обновить встроенную нагрузку Flowseal до 1.10.2
Sep 11, 2026
0094bb8
Сделать подпись Authenticode обязательной для стабильных выпусков
Sep 11, 2026
c90ee9f
Убрать сетевую проверку обновлений из потока интерфейса
Sep 11, 2026
8ef6bd9
Превращать новый стабильный выпуск Flowseal в устойчивую задачу
Sep 11, 2026
859e533
Добавить релизный шлюз проверки в чистом окружении Windows
Sep 11, 2026
ad18a18
Добавить статический анализ, мутационный фаззинг и решётку отказов
Sep 11, 2026
4d091c7
Добавить локальный экспорт диагностики с редактированием
Sep 11, 2026
4b027f7
Вынести решения восстановления при запуске в проверяемый модуль
Sep 11, 2026
6bf60f4
Зафиксировать сертификацию выпуска и проектную записку v2
Sep 11, 2026
28f52b1
Описать новые модули и экспорт диагностики в документации
Sep 11, 2026
6802c07
Исправить дефект политики подписи и кодировку inline-PowerShell в CI
Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,36 @@ jobs:
scripts\build-release.ps1 -BuildDir build-release
scripts\run-tests.ps1 -BuildDir build-release
scripts\validate-licenses.ps1
- name: Необязательная подпись и проверка Authenticode
# Стабильный тег vX.Y.Z подписывается обязательно: отсутствие
# сертификата, неудачная подпись, отсутствие метки времени или
# непрошедшая проверка подписи останавливают выпуск. Для тега
# предварительной версии vX.Y.Z-rc.N подпись остаётся необязательной —
# это осознанное исключение, описанное в docs/production/RELEASE_SIGNING.md.
- name: Обязательная подпись Authenticode для стабильного тега
if: ${{ !contains(github.ref_name, '-rc.') }}
shell: powershell
env:
AUTHENTICODE_PFX_B64: ${{ secrets.AUTHENTICODE_PFX_B64 }}
AUTHENTICODE_PFX_PASSWORD: ${{ secrets.AUTHENTICODE_PFX_PASSWORD }}
run: scripts\authenticode-sign.ps1 -File build-release\CHEBURNET.exe -Require
- name: Необязательная подпись Authenticode для предварительного выпуска
if: ${{ contains(github.ref_name, '-rc.') }}
shell: powershell
env:
AUTHENTICODE_PFX_B64: ${{ secrets.AUTHENTICODE_PFX_B64 }}
AUTHENTICODE_PFX_PASSWORD: ${{ secrets.AUTHENTICODE_PFX_PASSWORD }}
run: scripts\authenticode-sign.ps1 -File build-release\CHEBURNET.exe
# Хеши и подписанный манифест считаются ТОЛЬКО после подписи, поэтому
# опубликованный SHA-256 описывает именно подписанный файл.
- name: Сборка релиза и подписанных метаданных обновления
shell: powershell
env:
CHEBURNET_SIGNING_KEY_CNG_BLOB_B64: ${{ secrets.CHEBURNET_SIGNING_KEY_CNG_BLOB_B64 }}
run: scripts\prepare-release.ps1 -Tag '${{ github.ref_name }}' -Repository '${{ github.repository }}' -BuildDir build-release -OutDir dist
- name: Независимая проверка подписи публикуемого файла
if: ${{ !contains(github.ref_name, '-rc.') }}
shell: powershell
run: scripts\verify-authenticode.ps1 -File dist\CHEBURNET.exe -RequireTimestamp
- name: Публикация релиза GitHub
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
with:
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Статический анализ

# Два независимых анализатора: встроенный в MSVC /analyze и CodeQL.
# /analyze запускается с /WX, поэтому любая новая находка в коде CHEBURNET
# останавливает задание. Подавлено ровно одно предупреждение — дефект
# SAL-аннотации в заголовке Windows SDK, обоснование в CMakeLists.txt.

on:
push:
branches: ['main', 'claude/**']
pull_request:
schedule:
- cron: '41 5 * * 3'
workflow_dispatch:

permissions:
contents: read

jobs:
msvc-analyze:
runs-on: windows-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Сборка с MSVC /analyze
shell: powershell
run: |
. scripts\vsenv.ps1
Import-VcVars
& $CMakeExe -S . -B build-analyze -G Ninja -DCMAKE_MAKE_PROGRAM="$NinjaExe" `
-DCMAKE_BUILD_TYPE=Release -DCHEBURNET_ENABLE_ANALYZE=ON
if ($LASTEXITCODE -ne 0) { throw 'configure failed' }
& $CMakeExe --build build-analyze
# ASCII only inside an inline PowerShell block: the runner writes it to a
# .ps1 that Windows PowerShell 5.1 reads as ANSI, so non-ASCII breaks parsing.
if ($LASTEXITCODE -ne 0) { throw 'MSVC static analysis reported findings' }

codeql:
runs-on: windows-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: github/codeql-action/init@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4
with:
languages: c-cpp
queries: security-and-quality
- name: Сборка для CodeQL
shell: powershell
run: scripts\build-release.ps1 -BuildDir build-codeql
- uses: github/codeql-action/analyze@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4
with:
category: /language:c-cpp
126 changes: 121 additions & 5 deletions .github/workflows/upstream-check.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
name: Проверка исходного выпуска

# Новый стабильный выпуск Flowseal обязан превращаться в устойчивую задачу,
# а не в разовую строку в журнале запуска.
#
# Почему задача, а не черновой pull request: создание ветки требует
# contents: write у запланированного рабочего процесса, то есть постоянного
# права записи в репозиторий у автоматики, которая обрабатывает содержимое
# стороннего выпуска. Импортёр детерминирован и сверяет архив с неизменяемым
# digest релизного ассета, поэтому локальный запуск воспроизводит ровно то,
# что проверил CI, и права записи ничего не добавляют к полезности задачи.
# Разбор различий доступен в артефактах запуска. Ничто и никогда не
# объединяется автоматически.

on:
schedule:
- cron: '19 7 * * 1'
Expand All @@ -8,15 +21,118 @@ permissions:
contents: read

jobs:
check:
detect:
runs-on: windows-latest
permissions:
contents: read
outputs:
status: ${{ steps.report.outputs.status }}
version: ${{ steps.report.outputs.version }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Проверка последнего неизменяемого стабильного релиза
- name: Сравнение встроенной нагрузки с последним неизменяемым выпуском
id: report
shell: powershell
env:
GITHUB_TOKEN: ${{ github.token }}
run: scripts\sync-upstream.ps1 -CheckOnly
- name: Политика обновления
run: |
scripts\upstream-report.ps1 -JsonOut upstream\report.json -MarkdownOut upstream\report.md
$report = Get-Content upstream\report.json -Raw | ConvertFrom-Json
"status=$($report.status)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"version=$($report.latest_version)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
# ASCII only inside an inline PowerShell block: the runner writes it to a
# .ps1 that Windows PowerShell 5.1 reads as ANSI, so non-ASCII breaks parsing.
if ($report.status -eq 'error') { throw "upstream release check failed: $($report.error)" }
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: upstream-detect
path: upstream/

validate:
needs: detect
if: needs.detect.outputs.status == 'available'
runs-on: windows-latest
permissions:
contents: read
outputs:
validation: ${{ steps.import.outputs.validation }}
detail: ${{ steps.import.outputs.detail }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# Импорт выполняется в одноразовой рабочей копии CI и никуда не
# публикуется. Сам импортёр уже проверяет кандидата в изолированном
# дереве: чистая сборка, полный набор тестов и побайтовая сверка с
# архивом. Здесь дополнительно собирается и тестируется итоговое дерево.
- name: Импорт кандидата и полная проверка
id: import
shell: powershell
run: Write-Host 'Новый исходный релиз требует проверенной ветки и запроса на слияние; этот процесс никогда не объединяет бинарники автоматически.'
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
$validation = 'failed'
$detail = ''
try {
scripts\sync-upstream.ps1 -Version '${{ needs.detect.outputs.version }}'
scripts\build-release.ps1 -BuildDir build-upstream
scripts\run-tests.ps1 -BuildDir build-upstream
scripts\verify-upstream.ps1
$validation = 'passed'
$detail = 'clean build, full test suite and upstream byte fidelity passed'
} catch {
$detail = [string]$_.Exception.Message
}
"validation=$validation" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"detail=$detail" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
git diff --stat -- resources | Out-File -FilePath upstream\payload-diff.txt -Encoding utf8
git status --porcelain -- resources | Out-File -FilePath upstream\payload-status.txt -Encoding utf8
scripts\upstream-report.ps1 -ImportedRoot $PWD -Validation $validation `
-ValidationDetail $detail `
-RunUrl '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}' `
-JsonOut upstream\report.json -MarkdownOut upstream\report.md
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: always()
with:
name: upstream-candidate
path: upstream/

task:
needs: [detect, validate]
if: always() && needs.detect.outputs.status == 'available'
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: upstream-candidate
path: upstream
- name: Создание или обновление одной устойчивой задачи
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
UPSTREAM_VERSION: ${{ needs.detect.outputs.version }}
shell: bash
run: |
set -euo pipefail
marker="<!-- cheburnet-upstream:${UPSTREAM_VERSION} -->"
title="Upstream Flowseal ${UPSTREAM_VERSION} доступен для импорта"
body_file="$(mktemp)"
{
printf '%s\n\n' "$marker"
cat upstream/report.md
if [ -s upstream/payload-diff.txt ]; then
printf '\n### git diff --stat\n\n```\n'
cat upstream/payload-diff.txt
printf '```\n'
fi
} > "$body_file"
# Дедупликация по скрытому маркеру, а не по заголовку: заголовок
# может быть отредактирован человеком, маркер — нет.
existing="$(gh issue list --state all --limit 100 --json number,body \
--jq "[.[] | select(.body != null and (.body | contains(\"${marker}\"))) | .number] | first // empty")"
if [ -n "$existing" ]; then
gh issue edit "$existing" --body-file "$body_file"
echo "updated existing issue #${existing}"
else
gh issue create --title "$title" --body-file "$body_file"
fi
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Build output
/build*/
/dist/
/dist-*/
/artifacts/
*.obj
*.pdb
Expand Down
38 changes: 38 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
# История изменений

## Невыпущенное — подготовка стабильного 1.0.0

### Исправлено

- Семантика версий RC/stable. Сборка по тегу `v1.0.0-rc.N` больше не
сообщает о себе как `1.0.0`: введён единственный источник версии
(`cmake/Version.cmake`), из которого выводятся семантическая версия, числовая
PE-версия и канал. Переход `1.0.0-rc.3 -> 1.0.0` теперь оценивается как
обновление, а не как актуальная версия.
- Порог `minimum_supported_version` включает уже выпущенные RC, иначе
установленный `1.0.0-rc.N` получал бы отказ «слишком старая программа».
- Ревизия upstream вида `1.10.2a` больше не считается понижением
относительно `1.10.2`.
- Полный импорт upstream не мог завершиться: изолированное дерево
проверки собиралось без `docs` и `SECURITY.md`, которые требует шлюз
лицензий. Добавлен регрессионный тест.
- Статический анализ нашёл и исправлено: отсутствие проверки
размера списка атрибутов при создании привилегированного процесса и
буфер передачи 64 КиБ в автоматической памяти.

### Добавлено

- Движок Flowseal `zapret-discord-youtube` обновлён до 1.10.2: новая
стратегия `ALT13` (21 -> 22), обновлённые списки и ресурсы.
- Обязательная подпись Authenticode для стабильных тегов: без действительной
подписи с меткой времени выпуск не публикуется; опубликованные байты
связаны с подписанными по SHA-256.
- Проверка обновлений при запуске вынесена из потока интерфейса:
подключение не ждёт сети, недоступный DNS больше не выглядит
зависанием.
- Новый стабильный выпуск Flowseal автоматически превращается в одну
устойчивую задачу с полными метаданными и результатом проверки.
- Релизный шлюз проверки в чистом окружении Windows и воспроизводимая
подготовка виртуальной машины.
- Статический анализ (MSVC `/analyze` с `/WX` и CodeQL), мутационная
проверка свойств разборщиков и полная решётка внесения отказов.
- Локальный экспорт диагностики с редактированием и без отправки.

## 1.0.0-rc.3 — 2026-08-13

- Стабильный канал обновлений переведён на GitHub `releases/latest/download`:
Expand Down
38 changes: 35 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
cmake_minimum_required(VERSION 3.25)

project(CHEBURNET VERSION 1.0.0 LANGUAGES CXX)
# Единственный авторитетный источник версии (семантическая + числовая PE +
# prerelease + канал). Подключается до project(), поэтому использует
# CMAKE_CURRENT_LIST_DIR.
include("${CMAKE_CURRENT_LIST_DIR}/cmake/Version.cmake")

project(CHEBURNET VERSION "${CHEBURNET_VERSION_PE}" LANGUAGES CXX)

message(STATUS "CHEBURNET: версия ${CHEBURNET_VERSION_SEMANTIC} "
"(PE ${CHEBURNET_VERSION_PE}, канал ${CHEBURNET_RELEASE_CHANNEL})")

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -30,7 +38,7 @@ set(STRATEGY_SRC "${CMAKE_SOURCE_DIR}/resources/strategies_src")
file(MAKE_DIRECTORY "${GEN_DIR}")

# Launcher version is a single source of truth. C++, PE VERSIONINFO and the
# embedded application manifest are all configured from project(VERSION).
# embedded application manifest are all configured from cmake/Version.cmake.
configure_file(
"${CMAKE_SOURCE_DIR}/cmake/GeneratedVersion.h.in"
"${GEN_DIR}/GeneratedVersion.h" @ONLY)
Expand Down Expand Up @@ -122,6 +130,7 @@ set(LIB_SOURCES
src/update/UpdatePackage.cpp
src/update/RuntimeActivation.cpp
src/update/UpdateManager.cpp
src/update/UpdateCheckService.cpp
src/update/RuntimeStateStore.cpp
src/console/ConsoleRenderer.cpp
src/console/Mascot.cpp
Expand All @@ -134,6 +143,8 @@ set(LIB_SOURCES
src/ui/Effects.cpp
src/ui/Widgets.cpp
src/ui/Watchdog.cpp
src/app/Diagnostics.cpp
src/app/RuntimeRecovery.cpp
src/app/UiScreens.cpp
src/app/App.cpp
)
Expand All @@ -144,11 +155,32 @@ target_include_directories(cheburnet_lib PUBLIC
"${GEN_DIR}")
target_compile_definitions(cheburnet_lib PUBLIC
UNICODE _UNICODE WIN32_LEAN_AND_MEAN NOMINMAX _CRT_SECURE_NO_WARNINGS)
target_link_libraries(cheburnet_lib PUBLIC bcrypt crypt32 winhttp advapi32 shell32 ole32 user32)
target_link_libraries(cheburnet_lib PUBLIC bcrypt crypt32 winhttp advapi32 shell32 ole32 user32 wintrust)

# Warnings / hardening for our own code.
set(CHEBURNET_WARN /W4 /WX /permissive- /utf-8)
set(CHEBURNET_HARDEN /guard:cf)

# Статический анализ MSVC. Выключен по умолчанию: он заметно замедляет сборку и
# не должен мешать обычной разработке. Включается отдельным заданием CI
# (см. .github/workflows/static-analysis.yml) и локально:
# cmake -S . -B build-analyze -DCHEBURNET_ENABLE_ANALYZE=ON
# Находки разбираются, а не подавляются: список отключённых предупреждений
# ведётся здесь с обоснованием каждого.
option(CHEBURNET_ENABLE_ANALYZE "Enable MSVC /analyze static analysis" OFF)
if(CHEBURNET_ENABLE_ANALYZE)
# /analyze:external- не анализирует заголовки Windows SDK: их находки не
# наши и тонут в шуме.
#
# C28285 подавляется точечно и с обоснованием: это дефект SAL-аннотации
# CryptStringToBinaryA в самом wincrypt.h Windows SDK 10.0.26100.0
# ("синтаксическая ошибка _Param_(1)"). Он относится к чужому заголовку,
# исправить его на нашей стороне невозможно, и он не указывает ни на какое
# свойство кода CHEBURNET. Никакие другие предупреждения анализа не
# подавляются: все находки в нашем коде разобраны и исправлены.
list(APPEND CHEBURNET_WARN /analyze /analyze:external- /wd28285)
message(STATUS "CHEBURNET: статический анализ MSVC включён")
endif()
target_compile_options(cheburnet_lib PRIVATE ${CHEBURNET_WARN})
target_compile_options(cheburnet_lib PUBLIC ${CHEBURNET_HARDEN}
$<$<CONFIG:Release>:/O2 /Zi>)
Expand Down
Loading
Loading