Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae048ac1c8 | ||
|
|
ded569207e | ||
|
|
55c0d06baa | ||
|
|
3b5fe0c116 | ||
|
|
a2575233b7 | ||
|
|
8236789781 | ||
|
|
e217ed509a | ||
|
|
02967629ff | ||
|
|
a8c0482e76 | ||
|
|
b3b2ff1f07 | ||
|
|
248afd2253 | ||
|
|
fd5c788569 | ||
|
|
ff6d7155cd |
@@ -23,6 +23,12 @@ jobs:
|
||||
- name: Run production inventory placeholder guard self-test
|
||||
run: bash scripts/check_production_inventory_placeholders.sh --self-test
|
||||
|
||||
- name: Run private-config guard
|
||||
run: bash scripts/check_private_config_guard.sh
|
||||
|
||||
- name: Run portal contract sync guard
|
||||
run: node scripts/check_portal_contract_sync.mjs
|
||||
|
||||
rust-runtime-guard:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
name: rust-workspace
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
rust-workspace:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust 1.85
|
||||
uses: dtolnay/rust-toolchain@1.85.0
|
||||
with:
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Format
|
||||
run: cargo fmt --manifest-path adk-rust/Cargo.toml --all -- --check
|
||||
|
||||
- name: Test
|
||||
run: cargo test --manifest-path adk-rust/Cargo.toml --workspace
|
||||
|
||||
- name: Clippy
|
||||
run: cargo clippy --manifest-path adk-rust/Cargo.toml --workspace --all-targets -- -D warnings
|
||||
|
||||
- name: Release build
|
||||
run: cargo build --manifest-path adk-rust/Cargo.toml --workspace --release
|
||||
+6
-2
@@ -1,7 +1,11 @@
|
||||
# Local secrets
|
||||
/secrets/
|
||||
/private-config/*.env
|
||||
/private-config/*.local
|
||||
/private-config/*
|
||||
!/private-config/
|
||||
!/private-config/README.md
|
||||
!/private-config/.gitkeep
|
||||
!/private-config/*.example
|
||||
!/private-config/*.template
|
||||
/ansible/inventory.ini
|
||||
/codex_history.txt
|
||||
|
||||
|
||||
@@ -38,3 +38,82 @@
|
||||
Продукт относится к классу средств управления ИТ-службой,
|
||||
ИТ-инфраструктурой и ИТ-активами. Продукт не заявляется как
|
||||
сертифицированная DLP, SIEM, EDR/XDR или средство защиты информации.
|
||||
|
||||
|
||||
## Профессиональные сильные стороны проекта
|
||||
|
||||
Ниже — краткая и профессиональная сводка ключевых преимуществ AWatch-rus,
|
||||
предназначенная для реестра программного обеспечения и технического аудитa.
|
||||
|
||||
### 1. Архитектура и инженерный дизайн
|
||||
|
||||
- Rust-first, модульная архитектура: более 40 специализированных крейтов в
|
||||
workspace, четкая декомпозиция ответственности и воспроизводимые сборки
|
||||
(Cargo.lock).
|
||||
- Разделение на логические уровни: endpoint -> серверные хранилища ->
|
||||
processing -> operator -> automation, что упрощает тестирование и валидацию.
|
||||
- Четкие migration-runbooks для последовательного перехода legacy-python → Rust.
|
||||
|
||||
### 2. Операционная зрелость
|
||||
|
||||
- Полноценный Ansible-ensemble для end-to-end развёртывания (Proxmox, Linux,
|
||||
централизованный Windows rollout по WinRM), включая retry-политику,
|
||||
smoke-тесты и валидацию после деплоя.
|
||||
- Safe-run pattern: dry-run/apply planners, backup-before-delete, atomic
|
||||
операции и conservative no-restart paths.
|
||||
- Набор модулей для диагностики и качества (detmir-*, aw-*, quality-gate,
|
||||
smoke checks) обеспечивает fast feedback при внедрении.
|
||||
|
||||
### 3. Безопасность и работа с evidence
|
||||
|
||||
- Изолированный путь evidence: opaque IDs, bearer-upload, magic validation
|
||||
для изображений, размерные лимиты, SHA-256 валидация, atomic write и audit
|
||||
trails.
|
||||
- Security hardening guide: TLS по умолчанию, reverse-proxy, firewall
|
||||
рекомендации, сервисные аккаунты и минимальные привилегии.
|
||||
- Ясные границы продукта: не позиционируется как сертифицированная СЗИ/DLP;
|
||||
это снижает юридические риски при регистрации и аудите.
|
||||
|
||||
### 4. Production-readiness и валидация пилота
|
||||
|
||||
- Полный комплект acceptance и pilot-checklists (30-дневный pilot success
|
||||
criteria) с метриками доступности, coverage, freshness и времени реакции.
|
||||
- Runbooks и операционная документация для восстановления, резервного копирования
|
||||
и отката.
|
||||
|
||||
### 5. Наблюдаемость и качество данных
|
||||
|
||||
- Встроенные SLO/health monitoring, Prometheus/ Grafana витрины и
|
||||
детализированные smoke/contour тесты.
|
||||
- Механизмы объяснимости: UEBA v1 rule-based с reason-codes и объяснениями KPI
|
||||
coverage/confidence.
|
||||
|
||||
### 6. Поддержка Windows/RDP и forensics
|
||||
|
||||
- Централизованный Windows rollout и валидация (API smoke-checks для
|
||||
aw-watcher-afk/aw-watcher-window).
|
||||
- Серверная автоматическая обработка Hayabusa: auto-upload, severity scoring,
|
||||
case creation и уведомления (Telegram) с пороговой фильтрацией.
|
||||
|
||||
### 7. Документированность и готовность к реестру
|
||||
|
||||
- Полный набор документов для регистрации: product passport, architecture,
|
||||
functional scope, dependency statement, deployment model и readiness checklist.
|
||||
- Демонстрационные сценарии и фикстуры, исключающие реальные персональные и
|
||||
сетевые данные — соответствует требованиям для публичных материалов.
|
||||
|
||||
### 8. Честное позиционирование и риски
|
||||
|
||||
- Прозрачность ограничений (что реализовано, что planned/future) — важный
|
||||
аспект при подаче в реестр и при взаимодействии с заказчиком.
|
||||
- Документированная gap-analysis и roadmap-conformance audit облегчают
|
||||
процессы оценки соответствия и планирования доработок.
|
||||
|
||||
|
||||
---
|
||||
|
||||
Если нужно, могу:
|
||||
- добавить этот раздел как отдельный файл в docs/ (например,
|
||||
docs/PROFESSIONAL_HIGHLIGHTS_RU.md), либо
|
||||
- вставить в другой документ (например, в architecture или registry passport),
|
||||
- сгенерировать краткую выдержку на 1 страницу для подачи в реестр.
|
||||
|
||||
@@ -5,21 +5,17 @@ AWatch-rus - программный комплекс операционного
|
||||
корпоративной ИТ-инфраструктуры на базе ActivityWatch, Rust-сервисов
|
||||
автоматизации, Grafana/Prometheus-витрин и модулей расследования инцидентов.
|
||||
|
||||
Проект не позиционируется как сертифицированная DLP/SIEM/EDR/XDR/СЗИ. DLP,
|
||||
evidence и Hayabusa используются как прикладные модули внутри платформы
|
||||
операционного контроля и технического аудита.
|
||||
Проект не позиционируется как сертифицированная DLP/SIEM/EDR/XDR/СЗИ,хотя DLP,evidence и Hayabusa используются в проекте.
|
||||
|
||||
## Назначение
|
||||
|
||||
- AWatch-rus Workforce: активность сотрудников, загрузка, RDP/1C/рабочие
|
||||
приложения и управленческие отчеты для владельца бизнеса.
|
||||
- AWatch-rus Security: DLP-сигналы, evidence, очередь кейсов и audit действий
|
||||
оператора без заявления продукта как сертифицированной СЗИ.
|
||||
- AWatch-rus Forensics: цепочки событий, Hayabusa/offline-разбор и материалы для
|
||||
внутреннего расследования.
|
||||
- AWatch-rus Security: DLP-сигналы, evidence, очередь кейсов и audit действий оператора без заявления продукта как сертифицированной СЗИ.
|
||||
- AWatch-rus Forensics: цепочки событий, Hayabusa/offline-разбор и материалы для внутреннего расследования.
|
||||
- Контроль доступности и свежести данных ActivityWatch.
|
||||
- Учет активного времени, RDP-сессий, окон, приложений и рабочих интервалов.
|
||||
- Витрины Grafana для администратора, оператора ИБ и руководителя.
|
||||
- Учет активного времени, Windows RDP-сессий окон, приложений и рабочих интервалов а также активности пользователей в Linux/Unix системах.
|
||||
- витрины Grafana для администратора, оператора ИБ и руководителя(dashboards).
|
||||
- Автоматизация runbook-проверок, health-check, SLO и безопасного auto-heal.
|
||||
- Сбор evidence по инцидентам и аудит действий оператора.
|
||||
|
||||
@@ -28,18 +24,17 @@ evidence и Hayabusa используются как прикладные мод
|
||||
Основной серверный runtime AWatch-rus переведен на Rust: status/check/auto-heal,
|
||||
SLO, worktime, DLP server-side helpers, evidence и install-kit tooling.
|
||||
|
||||
Python в репозитории остается для вспомогательных направлений: Telegram bot
|
||||
runtime, OCR/content-analysis, 1C/AI/ETL integration и MCP/dev helpers. Эти
|
||||
части не являются ядром Rust-first runtime.
|
||||
Python, присутствующий в коде репозитория, остается для вспомогательных направлений: Telegram bot
|
||||
runtime(для оперативного оповещения), OCR/content-analysis, 1C/AI/ETL integration и MCP/dev helpers. Эти части не являются ядром Rust-first runtime.
|
||||
|
||||
Портальный слой зафиксирован как Rust server-rendered HTML + HTMX-compatible
|
||||
JSON API, OpenAPI и TypeScript declarations. Dioxus не используется и не
|
||||
рассматривается для Pilot v1.0. React, Tauri и Electron также не входят в
|
||||
текущий основной UI.
|
||||
текущий основной UI, но возможна их интеграция в проект.
|
||||
|
||||
## Product Evolution
|
||||
|
||||
AWatch-rus уже является рабочей платформой Workforce + Security + Forensics.
|
||||
AWatch-rus является рабочей платформой Workforce + Security + Forensics.
|
||||
Архитектура предусматривает расширение на агентные и agentless-источники
|
||||
данных. Planned/Future элементы ниже не являются реализованной функциональностью
|
||||
и не должны трактоваться как готовые collectors или integrations.
|
||||
|
||||
@@ -13,23 +13,22 @@ Forensics с прозрачными rule-based объяснениями.
|
||||
| Продукт | Публичная категория | Сильная сторона | Как позиционировать AWatch-rus рядом |
|
||||
| --- | --- | --- | --- |
|
||||
| ActivityWatch | Open-source automated time tracker | Локальный, открытый и понятный сбор активности приложений и сайтов | AWatch-rus развивает этот подход в пилотный корпоративный контур с ролями, отчетами, Risk Narrative и эксплуатационной документацией |
|
||||
| Стахановец | Контроль сотрудников, мониторинг активности, DLP-возможности | Зрелый классический контроль рабочих мест и политик мониторинга | AWatch-rus не должен заявлять функциональный паритет; его сильная зона - объяснимый управленческий KPI, Security Analytics и пилотная прозрачность |
|
||||
| StaffCop | Employee Monitoring, Insider Risk, Workforce Analytics, DLP | Широкий набор функций мониторинга, productivity analytics, расследований и DLP-направления | AWatch-rus нужно показывать как более узкий и прозрачный пилотный контур, без обещания заменить StaffCop по широте функций |
|
||||
| SearchInform | DLP, Risk Monitor, SIEM, TimeInformer и смежные продукты | Комплексная линейка ИБ-продуктов и мониторинга внутренних рисков | AWatch-rus не конкурирует как полноценный SIEM/DLP; он может быть легким аналитическим слоем для Workforce-first пилота |
|
||||
| Стахановец | Контроль сотрудников, мониторинг активности, DLP-возможности | Зрелый классический контроль рабочих мест и политик мониторинга | AWatch-rus не заявляет функциональный паритет; его сильная зона - объяснимый управленческий KPI, Security Analytics и пилотная прозрачность |
|
||||
| StaffCop | Employee Monitoring, Insider Risk, Workforce Analytics, DLP | Широкий набор функций мониторинга, productivity analytics, расследований и DLP-направления | AWatch-rus это более узкий и прозрачный пилотный контур, без обещания заменить StaffCop по широте функций |
|
||||
| SearchInform | DLP, Risk Monitor, SIEM, TimeInformer и смежные продукты | Комплексная линейка ИБ-продуктов и мониторинга внутренних рисков | AWatch-rus не конкурирует как полноценный SIEM/DLP; он является легким аналитическим слоем для Workforce-first пилота |
|
||||
| InfoWatch | DLP и защита от утечек конфиденциальной информации | Сильное DLP-направление, политики, интеграции и регуляторный контекст | AWatch-rus не заменяет DLP; он показывает операционную активность, объяснимые риски и материалы для внутренней проверки |
|
||||
|
||||
## Где AWatch-rus уместен
|
||||
|
||||
- Быстрый пилот для руководителя, ИБ и эксплуатации без тяжелого SIEM/DLP
|
||||
внедрения.
|
||||
внедрения в организациях,желающих иметь современное программное обеспечение такого типа.
|
||||
- Workforce-first аналитика с объяснением KPI, coverage и confidence.
|
||||
- Разделение Executive, Workforce, Security и Forensics сценариев.
|
||||
- Прозрачная rule-based модель UEBA Score v1 и Risk Narrative без ML/LLM.
|
||||
- Прозрачная rule-based модель UEBA Score v1 и Risk Narrative без дорогих средств использования Искусственного Интеллекта ML/LLM.
|
||||
- Подготовка evidence package и Markdown-отчетов для ручной проверки.
|
||||
- Честная демонстрация границ: planned, future и contract_only не выдаются за
|
||||
implemented.
|
||||
- Честная демонстрация границ: planned, future и contract_only не выдаются за implemented.
|
||||
|
||||
## Где зрелые конкуренты обычно сильнее
|
||||
## Где зрелые тяжелые конкуренты обычно сильнее
|
||||
|
||||
- Глубокие DLP-политики, контентная фильтрация и блокировки каналов утечки.
|
||||
- Масштабные SIEM/SOC-процессы и готовые интеграции ИБ.
|
||||
@@ -39,12 +38,10 @@ Forensics с прозрачными rule-based объяснениями.
|
||||
- Поддержка сложных enterprise-сценариев с централизованным управлением
|
||||
агентами и политиками.
|
||||
|
||||
## Что нельзя заявлять
|
||||
## Что не заявляется
|
||||
|
||||
- Что AWatch-rus заменяет DLP, SIEM, EDR или XDR.
|
||||
- Что planned или future providers уже работают в production.
|
||||
- Что pfSense readiness означает готовый ingestion, если он находится в статусе
|
||||
`contract_only`.
|
||||
- Что Risk Narrative является ML-прогнозом.
|
||||
- Что система автоматически оценивает персонал или принимает кадровые решения.
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
# Профессиональные сильные стороны проекта AWatch-rus
|
||||
|
||||
Ниже — структурированная, формальная сводка ключевых преимуществ AWatch-rus,
|
||||
подходит для включения в пакет документов при регистрации в реестре ПО и для
|
||||
технического аудита.
|
||||
|
||||
## 1. Архитектура и инженерный дизайн
|
||||
|
||||
- Rust-first, модульная архитектура: более 40 специализированных крейтов в
|
||||
workspace, четкая декомпозиция ответственности и воспроизводимые сборки
|
||||
(Cargo.lock).
|
||||
- Разделение на логические уровни: endpoint → серверные хранилища → processing
|
||||
→ operator → automation, что упрощает тестирование, валидацию и аудит.
|
||||
- Workspace resolver v3 и требуемая версия rust (1.85) — современный базис для
|
||||
поддержки и сопровождения.
|
||||
- Четкие migration-runbooks для последовательного и безопасного перехода
|
||||
legacy Python → Rust.
|
||||
|
||||
## 2. Операционная зрелость и автоматизация
|
||||
|
||||
- Полноценный Ansible-ensemble для end-to-end развёртывания (Proxmox, Linux,
|
||||
централизованный Windows rollout по WinRM) с retry-политикой, smoke-тестами
|
||||
и пост-deploy валидацией.
|
||||
- Safe-run pattern: dry-run/apply planners, backup-before-delete, atomic
|
||||
операции, conservative no-restart paths — минимизация риска при операциях.
|
||||
- Набор диагностических модулей (detmir-*, aw-*, quality-gate, smoke checks)
|
||||
обеспечивает быстрый feedback и ускоряет внедрение.
|
||||
|
||||
## 3. Безопасность и обращение с evidence
|
||||
|
||||
- Изолированный путь evidence: opaque IDs, bearer-upload, magic validation для
|
||||
PNG/JPEG, ограничение размера, SHA-256 валидация, atomic write и детальные
|
||||
audit trails.
|
||||
- Security hardening guide: обязательное TLS, reverse-proxy, firewall rules,
|
||||
минимальные привилегии для сервисных аккаунтов и контроль доступа к
|
||||
evidence-материалам.
|
||||
- Позиционирование: продукт не позиционируется как сертифицированная DLP/SIEM/
|
||||
EDR — это уменьшает юридические риски при регистрации и определяет четкие
|
||||
ожидания заказчика.
|
||||
|
||||
## 4. Production-readiness и критерии приёмки
|
||||
|
||||
- Полный комплект acceptance и pilot-checklists (30-дневный Pilot Success
|
||||
Criteria) с метриками: доступность портала, coverage источников, freshness
|
||||
данных, время загрузки сценариев Executive/Reporting, доля подтверждённых
|
||||
incident candidates.
|
||||
- Runbooks для восстановления, backup & restore сценарии и documented rollback
|
||||
steps.
|
||||
|
||||
## 5. Наблюдаемость, качество данных и объяснимость
|
||||
|
||||
- Встроенные SLO/health monitoring, Prometheus + Grafana витрины и
|
||||
детализированные smoke/contour тесты для проверки консистентности данных.
|
||||
- UEBA v1 — прозрачная rule-based модель с reason-codes; KPI показывают
|
||||
coverage и confidence, что повышает доверие заказчика.
|
||||
|
||||
## 6. Поддержка Windows/RDP и forensic pipelines
|
||||
|
||||
- Централизованный Windows rollout: deploy-скрипты, winrm retry logic, API
|
||||
smoke-checks (aw-watcher-afk / aw-watcher-window).
|
||||
- Серверная Hayabusa pipeline: auto-upload EVTX, severity scoring, automatic
|
||||
case creation, bounded metadata storage и Telegram-уведомления с пороговой
|
||||
фильтрацией.
|
||||
|
||||
## 7. Документированность и готовность к реестру
|
||||
|
||||
- Набор документов для регистрации: product passport, architecture, functional
|
||||
scope, dependency statement, deployment model, readiness checklist.
|
||||
- Demo fixtures и скриншоты анонимизированы (не содержат реальных IP/логинов/ФИО)
|
||||
— соответствует требованиям для публичных материалов и подачи в реестр.
|
||||
|
||||
## 8. Честное позиционирование и управление рисками
|
||||
|
||||
- Ясно задокументированы границы продукта и planned/future элементы — это
|
||||
облегчает аудит и формирует реалистичные expectations у заказчика.
|
||||
- Наличие gap-analysis и roadmap-conformance audit ускоряет планирование
|
||||
необходимых доработок перед масштабированием.
|
||||
|
||||
---
|
||||
|
||||
Файл сохранён в ветке `docs/add-professional-highlights` по пути
|
||||
`docs/PROFESSIONAL_HIGHLIGHTS_RU.md`.
|
||||
|
||||
Далее могу:
|
||||
- открыть Pull Request в main с этим изменением (рекомендуется для review),
|
||||
- смержить напрямую в main (если вы хотите немедленно обновить основную ветку),
|
||||
- или создать краткую 1-страничную выдержку для подачи в реестр.
|
||||
|
||||
Как предпочитаете поступить дальше?
|
||||
@@ -0,0 +1,111 @@
|
||||
# RC Evidence Pack: Pilot v1
|
||||
|
||||
Документ фиксирует доказательства финальной проверки release candidate процесса для ветки `hardening/pilot-v1-defects-cleanup`.
|
||||
|
||||
## Идентификаторы проверки
|
||||
|
||||
- Branch/ref: `origin/hardening/pilot-v1-defects-cleanup`
|
||||
- Commit: `a8c0482e760cc17b53182999355f65c17457d7f2`
|
||||
- Commit short: `a8c0482`
|
||||
- Дата проверки: `2026-06-12`
|
||||
- Clean worktree: `<LOCAL_VALIDATION_WORKTREE>/AWatch-rus-rc-validation-a8c0482`
|
||||
- RC name: `v1.0.2-rc-validation`
|
||||
- RC output: `dist/release-candidate/v1.0.2-rc-validation/`
|
||||
- `CARGO_TARGET_DIR`: `$HOME/.cache/aw-rus-hardening-target`
|
||||
|
||||
Абсолютный путь локального операторского home-каталога намеренно не фиксируется в tracked-документации. Это не влияет на воспроизводимость: команда использует стандартный `$HOME`.
|
||||
|
||||
## Команды проверки
|
||||
|
||||
Preflight без вынесенного target dir:
|
||||
|
||||
```bash
|
||||
bash scripts/build_release_candidate.sh --preflight
|
||||
```
|
||||
|
||||
Preflight с вынесенным cargo target dir:
|
||||
|
||||
```bash
|
||||
CARGO_TARGET_DIR=$HOME/.cache/aw-rus-hardening-target \
|
||||
bash scripts/build_release_candidate.sh --preflight
|
||||
```
|
||||
|
||||
Полная RC-сборка:
|
||||
|
||||
```bash
|
||||
CARGO_TARGET_DIR=$HOME/.cache/aw-rus-hardening-target \
|
||||
bash scripts/build_release_candidate.sh v1.0.2-rc-validation
|
||||
```
|
||||
|
||||
Команда полной сборки без имени RC проверена отдельно и корректно завершается с `exit=2`, потому что первый аргумент обязателен.
|
||||
|
||||
## Созданные RC artifacts
|
||||
|
||||
В каталоге `dist/release-candidate/v1.0.2-rc-validation/` созданы:
|
||||
|
||||
- `FILES.txt`
|
||||
- `SHA256SUMS.txt`
|
||||
- `SHA256SUMS-v0.2.txt`
|
||||
- `git-commit.txt`
|
||||
- `RELEASE_ASSETS_MANIFEST-v0.2.json`
|
||||
- `sbom/cargo-metadata-v0.2.json`
|
||||
- `sbom/cargo-tree-v0.2.txt`
|
||||
- `sbom/cyclonedx-rust-v0.2.json`
|
||||
- `sbom/python-inputs-v0.2.txt`
|
||||
- `sbom/spdx-rust-v0.2.json`
|
||||
|
||||
`git-commit.txt` содержит `a8c0482e760cc17b53182999355f65c17457d7f2`.
|
||||
|
||||
## Artifact verification
|
||||
|
||||
Подтверждено:
|
||||
|
||||
- `sha256sum -c SHA256SUMS.txt`: OK
|
||||
- `sha256sum -c SHA256SUMS-v0.2.txt`: OK
|
||||
- JSON parse для `RELEASE_ASSETS_MANIFEST-v0.2.json`: OK
|
||||
- JSON parse для `sbom/cargo-metadata-v0.2.json`: OK
|
||||
- JSON parse для `sbom/cyclonedx-rust-v0.2.json`: OK
|
||||
- JSON parse для `sbom/spdx-rust-v0.2.json`: OK
|
||||
- `FILES.txt` соответствует фактическому набору checksum-covered файлов: OK
|
||||
|
||||
Повторный запуск с тем же `RC_NAME` блокируется сообщением `release candidate output already exists`; существующий `SHA256SUMS.txt` не изменяется.
|
||||
|
||||
## Dirty-tree guard
|
||||
|
||||
Clean-tree requirement сохранен и проверен двумя сценариями:
|
||||
|
||||
- non-ignored untracked file блокирует настоящую RC-сборку;
|
||||
- tracked modification блокирует настоящую RC-сборку.
|
||||
|
||||
В обоих случаях скрипт завершается до создания RC-каталога. Ignored files намеренно не блокируют сборку, иначе `dist/` ломал бы повторные проверки и локальную валидацию артефактов.
|
||||
|
||||
## dist/ и git
|
||||
|
||||
Подтверждено:
|
||||
|
||||
- `git ls-files dist` возвращает `0` tracked files;
|
||||
- `git status --ignored dist` показывает `!! dist/`;
|
||||
- `dist/` не добавляется в git и остается локальным output-каталогом.
|
||||
|
||||
## Обязательные проверки
|
||||
|
||||
В clean validation worktree выполнены:
|
||||
|
||||
- `bash -n scripts/build_release_candidate.sh`: OK
|
||||
- `bash scripts/build_release_candidate.sh --preflight`: OK
|
||||
- `CARGO_TARGET_DIR=$HOME/.cache/aw-rus-hardening-target bash scripts/build_release_candidate.sh --preflight`: OK
|
||||
- `git diff --check`: OK
|
||||
- `bash scripts/check_private_config_guard.sh`: OK
|
||||
- `node scripts/check_portal_contract_sync.mjs`: OK
|
||||
- `bash scripts/quality-gate.sh`: OK
|
||||
|
||||
Внутри полной RC-сборки также прошли:
|
||||
|
||||
- `cargo fmt --manifest-path adk-rust/Cargo.toml --all -- --check`
|
||||
- `cargo test --manifest-path adk-rust/Cargo.toml --workspace`
|
||||
- `cargo clippy --manifest-path adk-rust/Cargo.toml --workspace --all-targets -- -D warnings`
|
||||
- `cargo build --manifest-path adk-rust/Cargo.toml --workspace --release`
|
||||
|
||||
## Вывод
|
||||
|
||||
Release candidate процесс подтвержден как воспроизводимый в чистом рабочем дереве. Clean-tree requirement сохранен. Сборка не требует ослабления защитных проверок. Ветка готова к review и merge в main.
|
||||
@@ -0,0 +1,108 @@
|
||||
# Release Candidate Runbook
|
||||
|
||||
Этот документ описывает техническую сборку Release Candidate для AWatch-rus. RC-сборка нужна, чтобы одной воспроизводимой командой собрать проверенные артефакты, зафиксировать git commit, сформировать SBOM/manifest/checksums и сложить результат в отдельный каталог под конкретное имя кандидата.
|
||||
|
||||
Release Candidate не равен юридической готовности к подаче в реестр и не заменяет финальную процедуру релиза.
|
||||
|
||||
## Evidence pack
|
||||
|
||||
Финальная проверка RC-процесса для ветки `hardening/pilot-v1-defects-cleanup` зафиксирована в `docs/RC_EVIDENCE_PACK_PILOT_V1_RU.md`.
|
||||
|
||||
## Запуск
|
||||
|
||||
Команда выполняется из корня репозитория:
|
||||
|
||||
```bash
|
||||
bash scripts/build_release_candidate.sh v1.0.2-rc1
|
||||
```
|
||||
|
||||
Первый аргумент обязателен. Имя кандидата используется как имя каталога в `dist/release-candidate/`, поэтому скрипт требует начало с буквы или цифры и дальше принимает только буквы, цифры, точку, подчеркивание и дефис.
|
||||
|
||||
Перед сборкой рабочее дерево git должно быть чистым. Если есть незакоммиченные, staged или untracked файлы, скрипт завершится с ошибкой. Это защищает RC от незафиксированного состояния.
|
||||
|
||||
## Preflight
|
||||
|
||||
Перед полной RC-сборкой можно проверить локальные предпосылки без создания каталога release candidate и без запуска cargo build/test:
|
||||
|
||||
```bash
|
||||
bash scripts/build_release_candidate.sh --preflight
|
||||
```
|
||||
|
||||
Preflight проверяет наличие команд `git`, `cargo`, `bash`, `node`, `sha256sum`, наличие обязательных внутренних скриптов, а также то, что `dist/` игнорируется git. Этот режим не требует чистого git tree, не создает артефакты и не заменяет полную RC-сборку.
|
||||
|
||||
## Если проект лежит на USB/HDD mount
|
||||
|
||||
На локальном контуре проект может лежать под `/mnt/` или `/media/`. В таком случае cargo build artifacts в стандартном `adk-rust/target` могут падать на filesystem-ограничениях mount, например на `libsqlite3-sys` с `Operation not permitted`.
|
||||
|
||||
Рекомендуемый запуск для такого контура:
|
||||
|
||||
```bash
|
||||
CARGO_TARGET_DIR=$HOME/.cache/aw-rus-hardening-target bash scripts/build_release_candidate.sh v1.0.2-rc1
|
||||
```
|
||||
|
||||
Это не обход проверок. Все `cargo fmt`, `cargo test`, `cargo clippy`, `cargo build`, `quality-gate`, private-config guard, OpenAPI contract guard и SBOM generation продолжают выполняться. Меняется только место, куда cargo складывает build artifacts.
|
||||
|
||||
`dist/` по-прежнему не коммитится. Требование чистого git tree для настоящей RC-сборки также остается обязательным.
|
||||
|
||||
## Проверки
|
||||
|
||||
Скрипт выполняет обязательные проверки и сборку Rust workspace:
|
||||
|
||||
```bash
|
||||
cargo fmt --manifest-path adk-rust/Cargo.toml --all -- --check
|
||||
cargo test --manifest-path adk-rust/Cargo.toml --workspace
|
||||
cargo clippy --manifest-path adk-rust/Cargo.toml --workspace --all-targets -- -D warnings
|
||||
cargo build --manifest-path adk-rust/Cargo.toml --workspace --release
|
||||
bash scripts/quality-gate.sh
|
||||
bash scripts/check_private_config_guard.sh
|
||||
node scripts/check_portal_contract_sync.mjs
|
||||
```
|
||||
|
||||
Если любая проверка падает, RC-сборка считается несостоявшейся.
|
||||
Неполный output-каталог при ошибке удаляется, чтобы не смешивать частичные артефакты с валидной сборкой.
|
||||
|
||||
## Артефакты
|
||||
|
||||
Результат складывается в:
|
||||
|
||||
```text
|
||||
dist/release-candidate/<RC_NAME>/
|
||||
```
|
||||
|
||||
Для примера выше итоговый каталог будет:
|
||||
|
||||
```text
|
||||
dist/release-candidate/v1.0.2-rc1/
|
||||
```
|
||||
|
||||
В каталоге создаются:
|
||||
|
||||
- `git-commit.txt` - commit, из которого собран кандидат;
|
||||
- `FILES.txt` - список файлов, покрытых итоговыми checksum, кроме самого `SHA256SUMS.txt`;
|
||||
- `SHA256SUMS.txt` - SHA-256 для всех файлов каталога, кроме самого `SHA256SUMS.txt`;
|
||||
- `sbom/` - SBOM-файлы, созданные существующим генератором `scripts/generate_release_sbom_v0_2.sh`;
|
||||
- `RELEASE_ASSETS_MANIFEST-v0.2.json` и `SHA256SUMS-v0.2.txt` - manifest/checksums, которые формирует существующий SBOM generator.
|
||||
|
||||
Каталог `dist/` не предназначен для коммита в git.
|
||||
|
||||
## Проверка checksum
|
||||
|
||||
Для проверки итоговых checksum:
|
||||
|
||||
```bash
|
||||
cd dist/release-candidate/v1.0.2-rc1
|
||||
sha256sum -c SHA256SUMS.txt
|
||||
```
|
||||
|
||||
Ожидаемый результат - `OK` для всех записей. Любая ошибка означает, что набор артефактов изменился после сборки или поврежден.
|
||||
|
||||
## Перед реальной подачей
|
||||
|
||||
Release Candidate подтверждает техническую воспроизводимость сборки, но перед реальной подачей все еще нужны:
|
||||
|
||||
- release tag;
|
||||
- release-specific SBOM;
|
||||
- license review;
|
||||
- signed/checksummed artifacts;
|
||||
- проверка отсутствия live/private data;
|
||||
- финальные install/user/admin guide под конкретную версию.
|
||||
@@ -0,0 +1,174 @@
|
||||
# Резолюция по проекту AWatch-rus
|
||||
|
||||
## 📋 РЕЗОЛЮЦИЯ ПО ПРОЕКТУ AWatch-rus
|
||||
|
||||
### 1. ОБЗОР ПРОЕКТА
|
||||
|
||||
**Название:** AWatch-rus — платформа операционного контроля и технического аудита
|
||||
|
||||
**Статус:** Активный проект в стадии Pilot v1.0
|
||||
|
||||
**Язык реализации:** Rust (основной backend) + Python (вспомогательные компоненты)
|
||||
|
||||
**Лицензия:** Apache License 2.0
|
||||
|
||||
**Видимость:** Открытый репозиторий
|
||||
|
||||
---
|
||||
|
||||
### 2. НАЗНАЧЕНИЕ И ЦЕННОСТЬ
|
||||
|
||||
Проект предназначен для:
|
||||
- Workforce Analytics — мониторинг активности сотрудников, загруженности, использования приложений
|
||||
- Security Operations — DLP-сигналы, detection событий, управление инцидентами
|
||||
- Forensics & Incident Response — сбор evidence, offline-анализ через Hayabusa, расследования
|
||||
|
||||
**Целевая аудитория:** руководители, операторы ИБ, администраторы ИТ-инфраструктуры, forensics-специалисты
|
||||
|
||||
---
|
||||
|
||||
### 3. КЛЮЧЕВЫЕ КОМПОНЕНТЫ АРХИТЕКТУРЫ
|
||||
|
||||
| Компонент | Технология | Назначение |
|
||||
|-----------|------------|-----------|
|
||||
| Rust Backend | Rust runtime | Основной сервер, SLO, DLP-обработка, evidence, auto-heal |
|
||||
| Windows Collector | PowerShell/Rust | Сбор данных: AFK, window-tracking, RDP-сессии, DLP-события |
|
||||
| Grafana/Prometheus | Dashboards | Витрины для админов, операторов, руководителей |
|
||||
| ActivityWatch | Modified base | Основа для сбора telemetry и worktime |
|
||||
| Portal UI | Rust server-rendered HTML + HTMX | Веб-интерфейс на основе server-side rendering |
|
||||
|
||||
---
|
||||
|
||||
### 4. ФУНКЦИОНАЛЬНЫЕ ВОЗМОЖНОСТИ (Implemented)
|
||||
|
||||
✅ Workforce Module:
|
||||
- Отслеживание активности: рабочее время, простои, переключение окон
|
||||
- RDP-сессии с детализацией
|
||||
- Профилирование приложений и сайтов
|
||||
- KPI-отчёты для руководства
|
||||
|
||||
✅ Security Module:
|
||||
- DLP-детектирование (копирование, печать, USB)
|
||||
- UEBA v1 (прозрачная rule-based модель, без ML)
|
||||
- Управление очередью инцидентов
|
||||
- Audit действий оператора
|
||||
|
||||
✅ Forensics Module:
|
||||
- Hayabusa integration для EVTX-анализа
|
||||
- Offline investigation packs
|
||||
- Timeline и Evidence-галереи
|
||||
- Расследование инцидентов
|
||||
|
||||
✅ Operations:
|
||||
- Role-based access (executive, manager, security, forensics, admin)
|
||||
- Pilot v1.0 validation
|
||||
- Deployment topologies & sizing guide
|
||||
- Production hardening
|
||||
|
||||
---
|
||||
|
||||
### 5. ПЛАНЫ И РАСШИРЕНИЕ
|
||||
|
||||
Planned:
|
||||
- PowerShell Provider для мониторинга
|
||||
- SSH Provider
|
||||
- Syslog Provider
|
||||
- 1C Integration Provider
|
||||
- Russian OS support validation
|
||||
|
||||
Future:
|
||||
- Extended Enterprise connectors
|
||||
- SCUD/VPN integrations
|
||||
- React/TypeScript Enterprise UI
|
||||
- Tauri Desktop Forensics
|
||||
|
||||
---
|
||||
|
||||
### 6. ТЕХНИЧЕСКОЕ СОСТОЯНИЕ
|
||||
|
||||
| Метрика | Значение |
|
||||
|---------|----------|
|
||||
| Open Issues | 1 |
|
||||
| Forks | 2 |
|
||||
| Stars | 2 |
|
||||
| Repository Size | ~10.5 MB |
|
||||
| Last Push | 2026-06-12T19:17:35Z |
|
||||
| Default Branch | main |
|
||||
|
||||
---
|
||||
|
||||
### 7. DEPLOYMENT И PRODUCTION-READINESS
|
||||
|
||||
Инструменты развёртывания:
|
||||
- Ansible playbooks (полный automation stack)
|
||||
- Proxmox provisioning (CT creation)
|
||||
- Windows WinRM rollout (centralized deployment)
|
||||
- Docker/CT topologies (multi-node)
|
||||
|
||||
Документация и валидация:
|
||||
- Pilot v1.0 демо-сценарии
|
||||
- Enterprise deployment guide
|
||||
- Security hardening & backup/recovery
|
||||
- Sizing guide
|
||||
- Registry readiness документы
|
||||
|
||||
---
|
||||
|
||||
### 8. ТЕХНИЧЕСКИЕ ПРЕИМУЩЕСТВА
|
||||
|
||||
- Rust-first approach — производительность, безопасность памяти, надёжность
|
||||
- Server-side rendering — снижение нагрузки на клиент
|
||||
- API-first — OpenAPI contracts, TypeScript declarations
|
||||
- Observability — Prometheus metrics, Grafana dashboards
|
||||
- Security by default — read-only по умолчанию, безопасные mutation paths
|
||||
- Modular Rust workspace — четкая декомпозиция модулей
|
||||
|
||||
---
|
||||
|
||||
### 9. ОГРАНИЧЕНИЯ И ПОЗИЦИОНИРОВАНИЕ
|
||||
|
||||
Не позиционируется как:
|
||||
- Сертифицированная DLP/SIEM/EDR/XDR
|
||||
- ML-based UEBA
|
||||
- Юридически гарантированная неизменность evidence
|
||||
|
||||
Позиционируется как:
|
||||
- Операционная платформа контроля (Workforce + Security + Forensics)
|
||||
- Pilot-ready решение для технического аудита
|
||||
- Расширяемая архитектура для агентных и agentless-источников
|
||||
|
||||
---
|
||||
|
||||
### 10. РЕКОМЕНДАЦИИ
|
||||
|
||||
Для потенциальных пользователей:
|
||||
1. Начать с Pilot v1 demo
|
||||
2. Пройти Pilot validation checklist
|
||||
3. Использовать Ansible automation для развёртывания
|
||||
4. Ознакомиться с Security hardening guide
|
||||
5. Планировать интеграции через role-based contracts
|
||||
|
||||
Для разработчиков:
|
||||
1. Контрибутировать через PR согласно guidelines
|
||||
2. Использовать migration runbook для изменений
|
||||
3. Поддерживать quality gates и smoke tests
|
||||
|
||||
---
|
||||
|
||||
### 11. ИТОГОВАЯ ОЦЕНКА
|
||||
|
||||
- Качество кода: высокое (Rust-first, модульная архитектура)
|
||||
- Документация: полная, пригодна для реестра
|
||||
- Production-readiness: готов к пилоту, требуется валидация
|
||||
- Сообщество: ранняя стадия
|
||||
- Расширяемость: высокая
|
||||
|
||||
---
|
||||
|
||||
## ✅ ИТОГОВЫЙ ВЕРДИКТ
|
||||
|
||||
AWatch-rus — профессиональный, хорошо структурированный проект для операционного контроля корпоративной ИТ-инфраструктуры. Проект готов к оценке и пилотному развёртыванию; перед production рекомендуется пройти валидацию по чеклистам.
|
||||
|
||||
---
|
||||
|
||||
*Файл добавлён в ветку `docs/add-professional-highlights` как `docs/RELEASE_RESOLUTION_RU.md`.*
|
||||
@@ -1,4 +0,0 @@
|
||||
*.env
|
||||
*.local
|
||||
!.gitignore
|
||||
!*.example
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# private-config
|
||||
|
||||
This directory is reserved for local, host-specific, or secret configuration.
|
||||
|
||||
Do not commit real runtime values here. Git only allows:
|
||||
|
||||
- `private-config/README.md`
|
||||
- `private-config/.gitkeep`
|
||||
- `private-config/*.example`
|
||||
- `private-config/*.template`
|
||||
|
||||
Use `scripts/check_private_config_guard.sh` before commits and in CI to verify
|
||||
that no private config file has entered the git index.
|
||||
Executable
+159
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
print_cargo_target_dir() {
|
||||
if [[ -n "${CARGO_TARGET_DIR:-}" ]]; then
|
||||
echo "CARGO_TARGET_DIR=$CARGO_TARGET_DIR"
|
||||
else
|
||||
echo "CARGO_TARGET_DIR is not set; cargo default target dir will be used"
|
||||
fi
|
||||
}
|
||||
|
||||
preflight_ok() {
|
||||
echo "[OK] $1"
|
||||
}
|
||||
|
||||
preflight_fail() {
|
||||
echo "[FAIL] $1" >&2
|
||||
PREFLIGHT_FAILED=1
|
||||
}
|
||||
|
||||
check_command() {
|
||||
local command_name="$1"
|
||||
if command -v "$command_name" >/dev/null 2>&1; then
|
||||
preflight_ok "command available: $command_name"
|
||||
else
|
||||
preflight_fail "missing command: $command_name"
|
||||
fi
|
||||
}
|
||||
|
||||
check_file() {
|
||||
local path="$1"
|
||||
if [[ -f "$path" ]]; then
|
||||
preflight_ok "required file exists: $path"
|
||||
else
|
||||
preflight_fail "required file is missing: $path"
|
||||
fi
|
||||
}
|
||||
|
||||
run_preflight() {
|
||||
PREFLIGHT_FAILED=0
|
||||
|
||||
echo "release candidate preflight"
|
||||
print_cargo_target_dir
|
||||
|
||||
check_command git
|
||||
check_command cargo
|
||||
check_command bash
|
||||
check_command node
|
||||
check_command sha256sum
|
||||
|
||||
check_file scripts/generate_release_sbom_v0_2.sh
|
||||
check_file scripts/check_private_config_guard.sh
|
||||
check_file scripts/check_portal_contract_sync.mjs
|
||||
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
if git check-ignore -q dist/release-candidate/.preflight-probe; then
|
||||
preflight_ok "dist/ is ignored by git"
|
||||
else
|
||||
preflight_fail "dist/ is not ignored by git"
|
||||
fi
|
||||
else
|
||||
preflight_fail "cannot verify git ignore rules without git"
|
||||
fi
|
||||
|
||||
case "$ROOT_DIR" in
|
||||
/mnt/*|/media/*)
|
||||
cat <<'EOF'
|
||||
[HINT] Project is under /mnt or /media. If cargo fails on the mount with Operation not permitted, run the full RC build with a writable target dir:
|
||||
CARGO_TARGET_DIR=/home/igor/.cache/aw-rus-hardening-target bash scripts/build_release_candidate.sh v1.0.2-rc1
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$PREFLIGHT_FAILED" -ne 0 ]]; then
|
||||
echo "release candidate preflight: FAIL" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "release candidate preflight: OK"
|
||||
}
|
||||
|
||||
if [[ "${1:-}" == "--preflight" ]]; then
|
||||
run_preflight
|
||||
exit $?
|
||||
fi
|
||||
|
||||
print_cargo_target_dir
|
||||
|
||||
RC_NAME="${1:-}"
|
||||
if [[ -z "$RC_NAME" ]]; then
|
||||
cat >&2 <<'EOF'
|
||||
usage: bash scripts/build_release_candidate.sh <rc-name>
|
||||
example: bash scripts/build_release_candidate.sh v1.0.2-rc1
|
||||
|
||||
preflight: bash scripts/build_release_candidate.sh --preflight
|
||||
EOF
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ ! "$RC_NAME" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]]; then
|
||||
echo "invalid release candidate name: start with a letter or number; use only letters, numbers, dot, underscore, and hyphen" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ -n "$(git status --porcelain --untracked-files=normal)" ]]; then
|
||||
echo "git working tree is not clean; commit, stash, or remove changes before building release candidate" >&2
|
||||
git status --short >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUT_DIR="$ROOT_DIR/dist/release-candidate/$RC_NAME"
|
||||
if [[ -e "$OUT_DIR" ]]; then
|
||||
echo "release candidate output already exists: $OUT_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BUILD_SUCCESS=0
|
||||
cleanup_on_failure() {
|
||||
status=$?
|
||||
if [[ $status -ne 0 && $BUILD_SUCCESS -ne 1 && -d "$OUT_DIR" ]]; then
|
||||
rm -rf "$OUT_DIR"
|
||||
fi
|
||||
exit "$status"
|
||||
}
|
||||
trap cleanup_on_failure EXIT
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
git rev-parse HEAD > "$OUT_DIR/git-commit.txt"
|
||||
|
||||
cargo fmt --manifest-path adk-rust/Cargo.toml --all -- --check
|
||||
cargo test --manifest-path adk-rust/Cargo.toml --workspace
|
||||
cargo clippy --manifest-path adk-rust/Cargo.toml --workspace --all-targets -- -D warnings
|
||||
cargo build --manifest-path adk-rust/Cargo.toml --workspace --release
|
||||
bash scripts/quality-gate.sh
|
||||
bash scripts/check_private_config_guard.sh
|
||||
node scripts/check_portal_contract_sync.mjs
|
||||
|
||||
bash scripts/generate_release_sbom_v0_2.sh "$OUT_DIR"
|
||||
|
||||
(
|
||||
cd "$OUT_DIR"
|
||||
{
|
||||
printf '%s\n' "FILES.txt"
|
||||
find . -type f ! -name 'FILES.txt' ! -name 'SHA256SUMS.txt' -print \
|
||||
| sort \
|
||||
| sed 's#^\./##'
|
||||
} > FILES.txt
|
||||
|
||||
find . -type f ! -name 'SHA256SUMS.txt' -print0 \
|
||||
| sort -z \
|
||||
| xargs -0 sha256sum > SHA256SUMS.txt
|
||||
)
|
||||
|
||||
BUILD_SUCCESS=1
|
||||
echo "release candidate built: $OUT_DIR"
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const root = path.resolve(__dirname, "..");
|
||||
const contractPath = path.join(
|
||||
root,
|
||||
"adk-rust/crates/detmir-portal/src/contracts/openapi.json",
|
||||
);
|
||||
|
||||
const requiredPublicPaths = [
|
||||
"/api/contracts",
|
||||
"/api/contracts/openapi.json",
|
||||
"/api/contracts/typescript.d.ts",
|
||||
"/api/reports",
|
||||
"/api/executive",
|
||||
"/api/workforce",
|
||||
"/api/security",
|
||||
"/api/forensics",
|
||||
"/api/ueba",
|
||||
"/api/pfsense",
|
||||
"/api/incidents",
|
||||
"/api/cases",
|
||||
"/api/readiness/latest",
|
||||
"/api/readiness/bundle",
|
||||
"/api/readiness/verify",
|
||||
];
|
||||
|
||||
function fail(message, details = []) {
|
||||
console.error(message);
|
||||
for (const detail of details) {
|
||||
console.error(`- ${detail}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let contract;
|
||||
try {
|
||||
contract = JSON.parse(fs.readFileSync(contractPath, "utf8"));
|
||||
} catch (error) {
|
||||
fail(`failed to read OpenAPI contract: ${contractPath}`, [error.message]);
|
||||
}
|
||||
|
||||
if (!contract || typeof contract !== "object" || !contract.paths || typeof contract.paths !== "object") {
|
||||
fail("OpenAPI contract has no object 'paths' section.");
|
||||
}
|
||||
|
||||
const contractPaths = Object.keys(contract.paths);
|
||||
const forbiddenPaths = contractPaths.filter((contractPathName) =>
|
||||
/dioxus|prototype-mirror|mirror/i.test(contractPathName),
|
||||
);
|
||||
if (forbiddenPaths.length > 0) {
|
||||
fail("OpenAPI contract contains legacy/prototype paths.", forbiddenPaths);
|
||||
}
|
||||
|
||||
const effectivePublicPaths = new Set();
|
||||
for (const contractPathName of contractPaths) {
|
||||
effectivePublicPaths.add(contractPathName);
|
||||
if (contractPathName.startsWith("/") && !contractPathName.startsWith("/api/")) {
|
||||
effectivePublicPaths.add(`/api${contractPathName}`);
|
||||
}
|
||||
}
|
||||
|
||||
const missingPaths = requiredPublicPaths.filter((requiredPath) => !effectivePublicPaths.has(requiredPath));
|
||||
if (missingPaths.length > 0) {
|
||||
fail("OpenAPI contract is missing required public API paths.", missingPaths);
|
||||
}
|
||||
|
||||
console.log("portal contract sync guard: OK");
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
violations=()
|
||||
|
||||
while IFS= read -r -d '' path; do
|
||||
rest="${path#private-config/}"
|
||||
case "$path" in
|
||||
private-config/README.md|private-config/.gitkeep)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
if [[ "$rest" != */* && ( "$rest" == *.example || "$rest" == *.template ) ]]; then
|
||||
continue
|
||||
fi
|
||||
violations+=("$path")
|
||||
done < <(git ls-files -z -- private-config)
|
||||
|
||||
if (( ${#violations[@]} > 0 )); then
|
||||
printf 'private-config guard failed: tracked private files are forbidden. Allowed files are README.md, .gitkeep, *.example, *.template.\\n' >&2
|
||||
printf '%s\\n' "${violations[@]}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "private-config guard: OK"
|
||||
@@ -7,6 +7,16 @@ cd "$ROOT_DIR"
|
||||
TARGET_ROOT="${CARGO_TARGET_DIR:-$ROOT_DIR/adk-rust/target}"
|
||||
RUST_BIN="${QUALITY_GATE_RUST:-}"
|
||||
|
||||
echo "[preflight] Private-config guard"
|
||||
bash scripts/check_private_config_guard.sh
|
||||
|
||||
echo "[preflight] Portal contract sync guard"
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
node scripts/check_portal_contract_sync.mjs
|
||||
else
|
||||
echo "node not found, skipping portal contract sync guard."
|
||||
fi
|
||||
|
||||
rust_candidates=()
|
||||
if [[ -n "$RUST_BIN" ]]; then
|
||||
rust_candidates+=("$RUST_BIN")
|
||||
@@ -39,6 +49,7 @@ fi
|
||||
echo "[3/6] Node syntax check (if node available)"
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
node --check scripts/aw-webui-browser-smoke.mjs >/dev/null
|
||||
node --check scripts/check_portal_contract_sync.mjs >/dev/null
|
||||
else
|
||||
echo "node not found, skipping."
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user