Files
ProxyWarden/AGENTS.md
T
dokril efda8eb98f
CI / Windows baseline (push) Canceled after 0s
Release v2.0.0
2026-09-10 20:59:52 +03:00

16 KiB
Raw Blame History

AGENTS.md

Назначение

ProxyWarden — standalone Windows desktop-приложение для удобного per-app proxy routing. Стек: Tauri 2, Rust backend, React/TypeScript frontend и Vite. Production install/service/UAC runtime реализован в Rust; PowerShell остаётся только build/release/QA tooling. Приложение управляет выбранными Windows-приложениями через ProxiFyre и, опционально, через локальный sing-box runtime.

Этот файл — главный контракт для кодового агента. Любой агент, который меняет репозиторий, обязан соблюдать эти правила. Да, даже если ему очень хочется «быстренько поправить одну кнопочку» и случайно переписать половину сетевого стека. Особенно тогда.

Продуктовая рамка

Проект не должен превращаться в коммерческий SaaS, Node gateway, VPN-провайдер, proxy server или облачный control plane. Это локальная Windows-утилита для себя и друзей.

Цель: надежно и понятно конфигурировать маршрутизацию выбранных приложений через внешний SOCKS5 proxy или через локальный sing-box, не ломая системную сеть и не пряча опасные действия за безобидными кнопками.

Архитектурные инварианты

  • Control App, ProxiFyre и Local sing-box — разные компоненты. Не смешивать их ответственность.
  • ProxiFyre — обязательный слой для per-app routing.
  • Local sing-box — optional runtime. Внешний SOCKS5 flow обязан работать без sing-box.
  • React UI не пишет generated config напрямую. UI вызывает typed Tauri commands.
  • src/api/tauriCommands.ts — единственная TypeScript-обертка над invoke(...).
  • Rust backend отвечает за storage, validation, config generation, component detection, service/install orchestration и structured errors.
  • C:\ProgramData\ProxyWarden\config и C:\ProgramData\ProxyWarden\state — source of truth.
  • C:\Program Files\ProxyWarden\components\ProxiFyre и C:\Program Files\ProxyWarden\components\sing-box — единственные current managed component roots.
  • config\components.json — только legacy migration input. Реальный component status принадлежит native Windows inventory и проверенным receipts.
  • Packaged component catalog — immutable offline baseline; проверенный download cache лежит отдельно в C:\ProgramData\ProxyWarden\packages.
  • C:\ProgramData\ProxyWarden\generated\proxifyre-app-config.json и sing-box-config.json — derived artifacts. Их можно пересоздавать.
  • Install/start/stop/uninstall — только явные действия пользователя. apply не должен скрыто устанавливать, удалять или «чинить» компоненты.
  • Subscription URL, credentials, proxy passwords и userinfo нельзя выводить полностью в UI, logs, diagnostics, crash text или activity.
  • Summary panel должен оставаться read-only: без install/start/stop/apply/delete/input/subscription mutations.
  • Любые elevated операции должны быть максимально явными и проверяемыми.

Основная структура

src/
  api/tauriCommands.ts       # typed invoke facade
  app/App.tsx                # текущая UI orchestration зона, слишком крупная
  app/readiness.ts           # apply gating logic
  app/viewModel.ts           # display/view helpers
  domain/types.ts            # TypeScript DTO mirror
  ui/*                       # reusable presentational components
  styles/app.css             # основной CSS

src-tauri/
  tauri.conf.json            # Tauri config, security, window config
  capabilities/default.json  # Tauri permissions/capabilities
  src/models.rs              # Rust domain models/defaults
  src/validation.rs          # normalization/validation
  src/storage.rs             # JSON storage, tmp/bak writes
  src/activity.rs            # activity log
  src/subscription.rs        # subscription fetch/parse
  src/component_catalog.rs   # pinned offline component catalog
  src/component_inventory.rs # exact native SCM/process/registry inventory
  src/component_packages.rs  # verified bundled/cache package plans
  src/component_cutover.rs   # durable legacy cutover/rollback/cleanup
  src/migration.rs           # versioned storage migration/adoption
  src/privileged_jobs.rs     # sealed one-shot elevated job records
  src/privileged_runtime.rs  # fixed native elevated action dispatcher
  src/proxifyre_runtime.rs   # native ProxiFyre lifecycle
  src/singbox_runtime.rs     # native sing-box lifecycle
  src/singbox_service.rs     # WinSW service spec/status logic
  src/safe_fs.rs             # safe path/ACL/reparse helpers
  src/adapters/*             # ProxiFyre/sing-box/proxy-router adapters
  src/commands.rs            # Tauri command handlers; currently too large
  tests/*                    # Rust integration/domain tests

scripts/
  check-runtime-powershell-boundary.ps1
  update-component-bundle.ps1
  audit-windows-smoke.ps1
  prepare-release.ps1

Агентские skill-модули

Подробные инструкции лежат в .agent/skills:

  • .agent/skills/repository-orientation/SKILL.md — как быстро понять репозиторий.
  • .agent/skills/rust-tauri-backend/SKILL.md — Rust/Tauri backend changes.
  • .agent/skills/react-typescript-ui/SKILL.md — frontend/UI changes.
  • .agent/skills/security-hardening/SKILL.md — CSP, секреты, temp files, storage, SSRF, elevated boundary.
  • .agent/skills/windows-services-powershell/SKILL.md — Windows service/install/PowerShell изменения.
  • .agent/skills/subscriptions-routing/SKILL.md — subscription, sing-box, ProxiFyre routing.
  • .agent/skills/testing-ci-release/SKILL.md — проверки, CI, release hygiene.
  • .agent/skills/communication-reporting/SKILL.md — короткие понятные планы, ревью и отчеты с таблицами файлов.

Перед сложным изменением прочитать релевантный skill. Перед любым нетривиальным ответом владельцу проекта — прочитать communication-reporting. Да, инструкция про то, как не писать кашу, теперь тоже инструкция. Так мы и живем.

Стиль общения агента

Пользователь — разработчик, но ему не нужен роман о каждом match, useState и переименованном импорте. Писать надо как для человека, которому нужно быстро принять решение: что изменилось, где изменилось, зачем и что проверить.

Перед любым нетривиальным ответом прочитать .agent/skills/communication-reporting/SKILL.md и перед финальным сообщением пройти .agent/checklists/communication.md.

Обязательные правила

  • Сначала результат, потом детали.
  • Короткие абзацы, списки и таблицы вместо полотна текста.
  • Для нетривиальных изменений использовать таблицу Файл / Что изменилось / Зачем.
  • Не объяснять каждую строку. Объяснять важные места, решения, риски и поведение.
  • Технические термины использовать только когда они помогают. Сложный термин объяснять одной простой фразой.
  • Проверки делить на выполненные, не выполненные и требующие Windows/manual check.
  • Для ревью группировать находки по приоритетам: Критично, Важно, Можно потом, Косметика.
  • Не писать корпоративный туман вроде «улучшена архитектура» без указания, что именно стало проще, безопаснее или понятнее.
  • Не заявлять “всё проверено”, если Rust tests, Windows service flow, Tauri build или UAC сценарии не запускались.

Минимальный формат финального ответа

## Коротко

- 1-3 главных результата.

## Файлы

| Файл | Что изменилось | Зачем |
|---|---|---|
| `path/file` | простое описание | практическая причина |

## Проверки

| Проверка | Статус | Комментарий |
|---|---|---|
| `command` | выполнено / не выполнено | почему |

## Риски

- Что осталось проверить или почему риска нет.

Если задача маленькая, формат можно сжать до нескольких строк. Если задача security/service/storage/routing-sensitive, детали обязательны, потому что «ну вроде работает» — это не инженерный метод, а жанр народного фольклора.

Правила изменений

Backend

  • Не добавлять новую Tauri command без typed wrapper в src/api/tauriCommands.ts и соответствующего TypeScript DTO в src/domain/types.ts, если command используется UI.
  • Не возвращать raw strings для сложных ошибок. Использовать structured error DTO: code, message, details.
  • Тяжелые или блокирующие операции должны быть async command + tauri::async_runtime::spawn_blocking.
  • Не вызывать network/process/service/file-heavy logic прямо из async runtime thread.
  • Не использовать unwrap()/expect() в production path, кроме очевидно невозможных bootstrap cases с комментарием.
  • Не писать generated configs неатомарно. Использовать temp + backup + rename where practical.
  • Не расширять commands.rs без необходимости. Для новой логики предпочитать отдельные модули и thin command wrapper.

Frontend

  • Не увеличивать App.tsx, если можно вынести hook/helper/component.
  • Не вызывать invoke(...) напрямую вне src/api/tauriCommands.ts.
  • Не дублировать apply-readiness проверки в JSX. Расширять src/app/readiness.ts.
  • Для UI использовать существующие компоненты из src/ui.
  • Apply/start/install/delete buttons должны иметь disabled state и понятную причину.
  • Не показывать secrets. Для subscription/proxy URL использовать redacted display values.
  • UI должен оставаться compact Windows utility, а не SaaS dashboard с иллюзией корпоративной важности.

Security

  • Не отключать CSP. Если CSP мешает, исправлять source policy, а не ставить csp: null.
  • Не добавлять Tauri shell permissions без жесткого scope и отдельного обоснования.
  • Не запускать произвольные команды из UI input.
  • Runtime-generated elevated scripts запрещены. Elevation использует current exe, fixed early modes и sealed typed job records без arbitrary command/path arguments.
  • Удаление директорий допускается только после safe-path/marker/service-path checks.
  • Subscription fetch должен иметь timeout и защиту от очевидно опасных/local metadata адресов либо explicit allow-mode.

Windows/service boundary

  • PowerShell разрешён только в build/release/QA allowlist: check-runtime-powershell-boundary.ps1, update-component-bundle.ps1, audit-windows-smoke.ps1, prepare-release.ps1.
  • PlanOnly/CheckOnly у этих scripts должны быть side-effect-free, возвращать structured JSON и иметь changed: false.
  • Production Rust, Tauri resources и NSIS hooks не должны запускать powershell.exe, pwsh, .ps1 или generated script text.
  • После изменения этой границы запускать scripts/check-runtime-powershell-boundary.ps1 -CheckOnly.
  • Install/start/stop/uninstall должны быть явными user actions.
  • Fuzzy-detected service не считать managed service без проверки PathName/metadata.
  • В Linux/macOS CI не пытаться «проверить» Windows service operations как реальные. Тестировать pure logic/mocks.

Известный технический долг

  • src-tauri/src/commands.rs слишком большой. Главная цель рефакторинга: разрезать на модули по use-case.
  • src/app/App.tsx слишком большой. Главная цель frontend-рефакторинга: hooks/components/view-model helpers.

Минимальная проверка перед ответом

Для docs-only изменений достаточно проверить структуру файлов и отсутствие очевидных Markdown/JSON ошибок.

Для frontend изменений:

npm ci
npm run build

Для Rust/backend изменений:

cd src-tauri
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets

Для Tauri/toolchain:

npm run tauri -- info
npm run tauri -- dev
npm run tauri -- build

Для offline bundle/release boundaries:

& .\scripts\check-runtime-powershell-boundary.ps1 -CheckOnly
& .\scripts\update-component-bundle.ps1 -PlanOnly
& .\scripts\update-component-bundle.ps1 -CheckOnly
& .\scripts\audit-windows-smoke.ps1 -Mode PlanOnly
& .\scripts\prepare-release.ps1 -PlanOnly -SkipBuild

Не оставлять dev/preview/Tauri dev servers запущенными после проверки.

Формат отчета агента

Использовать один из шаблонов:

  • .agent/templates/work-plan.md — короткий план перед работой.
  • .agent/templates/change-report.md — отчет после изменения кода.
  • .agent/templates/investigation-report.md — аудит, расследование, разбор проблемы.
  • .agent/templates/user-facing-summary.md — краткая сводка для владельца проекта.
  • .agent/templates/pr-description.md — описание PR.

Каждый нетривиальный ответ должен отвечать на вопросы:

  1. Что поменялось или найдено?
  2. В каких файлах?
  3. Зачем это нужно?
  4. Что проверено?
  5. Что не проверено?
  6. Где остался риск?

Не писать «всё готово», если Windows/elevated/service flow не проверялся на Windows. Эта фраза и так слишком много навредила миру.