Files
obsidian-vault/work/projects/macos-cloud-autofix-plan-2026-10-15.md
T

286 lines
42 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 'macOS: cloud flow для автофикса багов и тестов (Claude/Codex) — план'
date: '2026-10-15'
status: proposal
tags:
- ddg
- macos
- ai-agents
- ci
- bitrise
- sentry
- virfield
---
# macOS: cloud flow для автоматического фикса и валидации багов и тестов
Статус: **предложение**, не реализовано. Собрано 2026-10-15 из: Asana (AI Agent Infrastructure / O-T), Obsidian (Virfield, Personal OS, macos-tests-worktrees-2026-10-14, ci-pipeline), `.github/workflows` и `.claude/skills` в apple-browsers, документации Anthropic / OpenAI / Sentry / Bitrise.
Пометки: ✅ подтверждено источником, ⚠️ не проверено / нужен spike.
---
## 1. Что уже есть (чтобы не строить второй раз)
### 1.1 В Asana (опыт компании)
| Что | Суть | Урок для нас |
|---|---|---|
| **Windows crash-triage** ([1214714826035263](https://app.asana.com/1/137249556945/task/1214714826035263)) | Prefect job тянет Sentry через MCP → Claude agent → ежедневный stability report → Release DRI. ~$8/день (~$250–500/мес). Сначала Cursor self-hosted, затем Claude на **GitHub-hosted Windows runner**, который Prefect запускает как GHA. Prefect-variable хранит «память» между запусками → дешевеет день ото дня. | Рабочая схема: **pre-fetch в доверенном контуре → artifact → агент на runner'е**. Агент не ходит в Sentry сам. |
| Там же: отношение разработчиков к авто-PR | В апреле авто-PR встретили враждебно («проверять PR дороже, чем идею»). Решение: каждая находка **валидируется unit/UI-тестом-репродьюсером**, отчёт = root cause + направление + тест. После этого 2 AI-PR влились без комментариев, команда согласилась на авто-PR; ~20 CPMN деградации предотвращено. | Нельзя начинать с авто-PR. Лестница доверия: report → proposal → draft PR. **Без failing-теста фикс не предлагается.** |
| **Find an alternative to Cursor Cloud Agents** ([1216757783325568](https://app.asana.com/1/137249556945/project/72649045549333/task/1216757783325568), DRI Chris Clarke) | 3 класса workflow: analyze-and-report / **build-and-fix** / drive-browser. Interactive Claude runners для Android, SERP, generic уже есть (claude.ai/code). Linux/Windows self-hosted GHA runners — в работе ([1218221113915359](https://app.asana.com/1/137249556945/task/1218221113915359)). **macOS — главный пробел**: в Azure нет macOS, поэтому нет пути к внутренней сети (dub, ClickHouse, Sentry). Проект «Provision Mac Machines» ([1215557028847084](https://app.asana.com/1/137249556945/project/1211983163358654/task/1215557028847084), AWS EC2 Mac) — **ON HOLD**. | Мы закрываем именно этот пробел. Нужно встроиться в проект AI Agent Infrastructure, а не делать параллельный. |
| Context transfer PoC ([1217164276206833](https://app.asana.com/1/137249556945/task/1217164276206833)) | GHA run не resumable → в ZIP-artifact кладут transcript + prompt + metadata, skill восстанавливает контекст в новом чате. Предложено стандартизировать как company-wide GHA. | Решает «человек хочет вмешаться» без интерактивных сессий. |
| **Bitrise** ([1218829288858490](https://app.asana.com/1/137249556945/project/1219113011535833/task/1218829288858490)) | Apple team уже использует **Bitrise как провайдера macOS-раннеров для GHA** (GitHub macOS слишком медленные), 360-мин лимит GHA. Bitrise RDE (remote dev env: SSH/VNC, suspend/resume) в trial: 1 concurrent session, баг Bitrise GitHub App с private repos (Bitrise чинит). | Для автоматических запусков берём то, что уже работает (GHA + Bitrise). RDE — для интерактива. |
| **Security triage Bitrise RDE** ([1219413380003457](https://app.asana.com/1/137249556945/project/1199892415909552/task/1219413380003457), ответ 2026-10-14) | (AT1) прямой доступ Bitrise → внутренние системы **не жизнеспособен** (пришлось бы открывать все пулы Bitrise). (AT2) использовать RDE MCP, локальный Claude — оркестратор; `SSH_AUTH_SOCK` обнулить (forward ключей). (AT3) не auto-approve RDE tools в сессии с ClickHouse/Sentry MCP; всё, что вернулось из RDE, — untrusted. Сами RDE-сессии изолированы. | **Жёсткое ограничение дизайна:** агент на Bitrise-машине не видит Sentry/ClickHouse/dub. Данные приходят артефактом. |
| Bug Squisher / Duck.ai | SERP: `[🤖 Bug Squisher]` PR'ы в ddg. Duck.ai: инженер вручную `$auto fix this bug` (порт pstack) → готовый PR → ревью. Автоматизацию добавят после доказанной надёжности. Artur (Chromium): агент не управляет браузером напрямую, а **пишет воспроизводимый journey-скрипт**, который прогоняется на base и fix коммитах — агент не может «соврать» в валидации. | Берём этот приём для валидации (см. §5). Согласовать с flux/pstack, чтобы не плодить 5-й параллельный фреймворк (см. комментарий о пересечениях в [1213572946361338](https://app.asana.com/1/137249556945/project/1209667197557478/task/1213572946361338)). |
| Модель гейтов (из того же обсуждения) | Consensus-гейты (kick-off, tech design, post-mortem) — людям; unattended agent их пропускает. Review-гейты (privacy/security triage, ship review) обязательны — «стекаются» в конец, коррекции возвращают агента в цикл. | Агентский flow = draft PR + обязательные review-гейты, без consensus. |
| Windows release quality ([1215834564874913](https://app.asana.com/1/137249556945/task/1215834564874913)) | Windows — пилот; **macOS идёт следом**. Preview ловит краши, но их не превращают в bug с owner'ом («conversion problem»). | Наш flow = «конвертер» crash → воспроизведённый тест → draft PR для macOS. |
⚠️ Отдельной задачи именно про **Android cloud AI bug fixing** в Asana не нашлось — только упоминание, что Claude runners доступны для Android/SERP/generic. Если есть конкретная ссылка, надо дочитать.
⚠️ Отдельного «Sentry crash report → Claude cloud» для Apple нет: сегодня это ручной skill `ddg-sentry-report` (пользователь вызывает сам, пишет в Asana).
### 1.2 В репозитории apple-browsers
- `macos_pr_checks.yml` (unit + integration на `macos-26` / `macos-26-xlarge`, release build, retry), `macos_ui_tests.yml` (matrix по классам × macOS 14/15/26, ночью 03:00 UTC, **`workflow_dispatch` с `single_test_class`**, `user_modes`, `workflow_call`), `macos_run_ui_test.yml`, `macos_build_notarized.yml` (UI-тесты требуют notarized Review app), `danger.yml`, `conflict_watch.yml`, `.github/actions/bitrise-build-cache`, `process-test-results`, `asana-failed-pr-checks`.
- Skills: `ddg-diagnose-ci-failure` (JUnit XML из артефактов, классификация, flaky vs deterministic, регрессионная timeline), `ddg-sentry-report`. Оба **user-initiated**: трогают Asana → «lethal trifecta» блокирует прочие MCP.
- `AGENTS.md`, `CLAUDE.md`, `REVIEW.md` — инструкции уже есть.
- `.xcode-version` = 26.4 (ci-pipeline note). У Virfield профиль `uitest-27-v1` = macOS 27 / Xcode 27 → **расхождение**, надо иметь образ под 26.4.
### 1.3 Наши локальные достижения (Obsidian)
**Virfield** (Tart + SSH nodes, Go, MCP из 18 tools: `vm_acquire/vm_lease/vm_release/vm_tunnel`, `image_*`):
- ✅ Disposable macOS VM по lease, pinned SSH, экспорт артефактов, cleanup; golden Xcode 15.2 / 13.4.1 / 27.0.
- ✅ Исправлены вещи, на которых падают DDG UI-тесты: locked keychain (login + default, GUI и SSH контексты), 1920×1080, ASIF/Recovery, SSH banner timeout. Реальный `DownloadsUITests.testDownloadFinishesThenPopupIsShown` — 2 прогона 0 failures (Xcode 27.1 products → guest 27.0).
- ⚠️ Не принято: Broker/Runner → apple-browsers UI suite целиком; установленный `aee89c1` ≠ source `9a740c0`; `vm_drift` ложные срабатывания; admission quirks (storage reserve); **пул = 2 VM на одном Mac**, GitHub CI отложен. Это хорошая **dev/acceptance площадка**, но не production-флот.
**Personal OS / Executor** (3 попытки, 2026-04…10):
- Executor v1 (автономный LLM-оркестратор) → **инцидент** (писал в Asana, утечки задач в Discord). Executor v2 (bash runner/analyzer + 5 worker-промптов: queued / in_progress / fix_ci / fix_comments / pr_review; state machine `queued→in_progress→pr→complete/abandoned`; no-output watchdog 30 мин, hard 3 ч; lockfile; фильтры analyzer'а) — реализован, но кроны на паузе.
- Сквозные уроки: (1) **детерминированный слой работал, агентный — нет**; (2) агенту нельзя писать во внешние системы и иметь канал наружу с рабочими данными; human-in-the-loop — обязательный гейт; (4) слабое железо не тянет агентный стек; (7) провайдер модели — конфиг, не архитектура; Codex bwrap не стартует в Docker; подписочные OAuth-токены не проксировать.
**Тестовые фиксы 2026-10-14** ([[work/projects/macos-tests-worktrees-2026-10-14]]) — готовый эталон качества и eval-набор:
- AddressBarTests: корень = `ensureObjectDeallocated(.interrupt)` шлёт SIGINT при живом объекте; 2 причины (autorelease в `TestRunHelper`, strong `self` в animation completion). Валидация: **main 10/10 FAIL → fix 15/15 PASS**, 7/7 изолированно, полный Integration ×2.
- Fire Window video leak: **не воспроизведено**, итог = 4 guard-теста без фикса (проверка валидности: намеренная утечка → тест падает). «Не воспроизвелось» — легитимный исход.
- Наблюдения среды: **display sleep** ломает dealloc-проверки (display-link анимации стоят) → VM/раннер должен держать дисплей бодрым; `async` тесты маскируют release; нужны мок сети (OHHTTPStubs) и изоляция настроек пользователя.
### 1.4 Внешнее (проверено по документации)
| Платформа | Что умеет | Ограничение для нас |
|---|---|---|
| **`anthropics/claude-code-action@v1`** | Automation mode (`prompt`), триггеры: schedule / dispatch / issue / PR; `claude_args` (`--max-turns`, `--allowedTools`, `--model`); skills из `.claude/skills`; auth: API key, OAuth, **OIDC federation (без долгоживущих секретов)**; по умолчанию создаёт ветку, PR — по ссылке (человек жмёт). Коммиты токеном `GITHUB_TOKEN` не запускают CI → нужен GitHub App/custom token. | ⚠️ Документация говорит «runs on GitHub-hosted runners»; работа на macOS/Bitrise-label **явно не описана** → spike. Ничего не мешает использовать `claude -p` напрямую в job. |
| **`openai/codex-action@v1`** | `codex exec` в job; **Linux или macOS runner**; `sandbox`, `safety-strategy: drop-sudo`, `allow-users`. | Примеров fix-CI нет (только ревью PR). |
| **Claude Code cloud (claude.ai/code, routines)** | Сессии на VM Anthropic; routines: schedule / **API trigger (`POST /fire`, поле `text` = payload алёрта)** / GitHub events; Auto-fix PR (реагирует на CI failures и комментарии). | Anthropic-VM не собирает Xcode. Лимиты routines: 30 fire/час на routine. `text` оборачивается как untrusted. |
| **Claude self-hosted environments** (public beta, Team/Enterprise) | Runner на **нашем** хосте; outbound-only; routines и claude.ai/code роутятся на него; ephemeral runner (`--drain-grace-sec 0` → чистый диск); сессии **resumable с любого устройства**. Runner «лочится» на одного owner'а. | ⚠️ macOS-runner в доках не описан (рецепты — Kubernetes/Compose); Chris Clarke: «supports macOS, but we don't have any provisioned». Спросить Anthropic (в проекте есть похожая подзадача по Windows). |
| **Sentry Seer** | Автоматический Issue Fix: ≥10 events, активность ≤14 дней, fixability score; уровни: stop after RCA / solution / PR / **hand-off в Claude Agent** (или Cursor, Copilot); Seer **никогда не мерджит**. Рекомендуют начинать с «Stop after Solution». | Не собирает macOS-проект; нужен GitHub integration + code mappings; приватность (крэш-данные → внешний агент) — нужен privacy triage. |
| **Bitrise Build Hub (GHA)** | `runs-on: <bitrise-label>`, M4 Pro, Xcode в течение 24 ч после релиза, on-demand ephemeral с GitHub App, US/EU. | Нет явных гарантий egress-контроля. |
| **Bitrise RDE** | SSH/VNC, suspend/resume, MCP server. | См. security triage выше; trial = 1 сессия. |
| **Bitrise AI Build Fixer** | Анализ упавшего билда → PR → ре-билд (Pro/Enterprise). | ⚠️ Описан для Bitrise CI; для «Build Hub под GHA» не подтверждено. Покрывает только build failures, не flaky/crash. |
| **Tart / Orchard / Tartelet / Cilicon** | OSS ephemeral macOS VM на Apple silicon для self-hosted GHA runners. | ⚠️ Новость о закрытии Cirrus CI — из блога конкурента, не проверена; Tart OSS от этого не зависит. |
---
## 2. Постановка
**Цель:** по сигналу (упал/флакает тест на main; новый крэш в Sentry; баг) получить **draft PR с доказательствами**, что фикс работает (до: красный N/N, после: зелёный N/N, lint, нужные схемы собираются), либо **обоснованный отказ** («не воспроизведено», «нужен человек»). Человек ревьюит и мерджит.
**Не цели:** auto-merge; запись в Asana/чаты самим агентом; фиксы фич/UX без владельца; релизные ветки на первом этапе.
**Классы задач (по возрастанию сложности и риска):**
1. Flaky/failing unit & integration test (чистый macOS, без секретов).
2. Failing UI test (нужен notarized Review build, UITestCase, matrix по OS).
3. Crash из Sentry (нужен репродьюсер; данные из внутреннего контура).
4. Bug из Asana (нужны repro steps; наибольший риск prompt injection и архитектурных ошибок).
---
## 3. Целевая архитектура (общая для всех вариантов)
```mermaid
flowchart LR
subgraph Signals[Сигналы]
A[CI: JUnit из main/ночных runs]
B[Sentry: new-in-release, >=N events]
C[Asana bug / ручной запуск]
end
subgraph Trusted[Доверенный контур - Linux, есть dub/Sentry]
D[Детерминированный intake:\nфингерпринт, dedupe, eligibility,\nбюджет, scrub PII]
E[signal.json + артефакты]
end
subgraph Mac[macOS runner - эфемерный, без внутренней сети]
F[Agent job: analyze -> repro -> fix -> validate]
G[evidence bundle:\nxcresult, before/after, summary.json]
end
H[Draft PR ai/fix/fingerprint\nлейбл ai-generated]
I[Существующий PR CI:\nunit+integration+UI на Bitrise]
J[Человек: ревью, мердж]
K[Notifier: Mattermost / Asana-комментарий\n(детерминированный, узкий токен)]
A-->D
B-->D
C-->D
D-->E-->F-->G-->H-->I-->J
H-->K
I-->|падение CI|F
```
Принципы (из уроков Executor и security triage):
1. **Детерминированный каркас, LLM только в узком worker-шаге.** Очередь, дедуп, бюджет, ретраи, нотификации — код, не агент.
2. **Агент не получает ни Asana, ни Sentry, ни ClickHouse.** Вход — файлы (`signal.json`), выход — ветка `ai/fix/<fingerprint>` + `summary.json`.
3. **Запись только draft PR в ветку `ai/*`** (GitHub App; ruleset: пушить можно только `ai/*`, `main` закрыт). Нотификации и Asana-комментарии делает отдельный детерминированный шаг.
4. **Секреты подписи/notarization не в agent-job.** Агентский job гоняет unit/integration без секретов; UI-тесты запускаются **оркестратором** на ветке агента через существующий `macos_run_ui_test` (как для обычного PR).
5. **Провайдер = конфиг:** `agent: claude|codex`, один prompt/skills/schema (`AGENTS.md` ↔ `CLAUDE.md`).
6. Вход — **untrusted** (стектрейсы, bug-тексты, комментарии PR): передаём как данные, `--allowedTools` минимальный, никаких write-MCP.
7. Всё идемпотентно: один fingerprint = одна ветка/PR; повтор не плодит дубли.
---
## 4. Варианты исполнения (venue)
| | Описание | Плюсы | Минусы / риски | Когда |
|---|---|---|---|---|
| **A. GHA + Bitrise Build Hub + `claude -p` / action (рекомендуемый старт)** | Workflow в apple-browsers: `dispatch/schedule` → Linux job (intake) → macOS job на Bitrise-label с агентом. | Уже используем для CI; ничего нового не покупаем; эфемерность; артефакты и OIDC из коробки; PR-цикл как у людей; тот же Xcode, что CI (ключевое для воспроизводимости). | Атомарно (без чата) → context-transfer ZIP; 360-мин лимит; нет внутренней сети (ok — данные приходят артефактом); egress на runner не контролируем → in-VM sandbox (Seatbelt) и prompt-hardening; ⚠️ claude-action на macOS не документирован → spike. | Фазы 1–3. Классы 1, 2, 3. |
| **B. Self-hosted Tart-раннеры (Virfield как база образов)** | Свои Mac mini + Tart + (Orchard/Tartelet/Cilicon) как GHA runner, образ с Xcode 26.4 из нашего image pipeline. | Полный контроль сети (egress allowlist → можно и внутренние данные); интерактивный доступ по SSH-туннелю; нет per-minute. | Нужно железо DDG (проект «Provision Mac» on hold; AWS EC2 Mac — дорого, 24ч минимум аренды dedicated host ⚠️); ops-нагрузка; Virfield не принят и сейчас = личный Mac с 2 VM (bus factor 1). | Фаза 4+, если A упрётся в стоимость/сеть. Virfield остаётся **dev/acceptance песочницей**. |
| **C. Claude self-hosted environment на Mac (Tart VM на сессию)** | Runner Anthropic на macOS-хосте; триггеры: routines `POST /fire` (из Sentry/GHA), claude.ai/code. | **Resumable интерактив** с любого устройства (закрывает главный минус A); routines/API-триггер; ephemeral runner = чистый диск. | Beta, Team/Enterprise, ⚠️ macOS не подтверждён; owner-lock → нужен сервисный аккаунт; privacy/security triage Claude self-hosted уже «revisit»; зависимость от Anthropic control plane. | Фаза 4, после ответа Anthropic. Интерактивный «человек подключается». |
| **D. Bitrise RDE + Claude** | Долгоживущая macOS-VM с SSH/VNC и MCP. | Интерактив, suspend/resume, скриншоты/VNC. | Trial 1 сессия, баг private repos, нет внутренней сети, SSH-agent forwarding (обнулить), не масштабируется, оркестратор = локальный Claude. | Разовые сложные баги / UI-репро, не конвейер. |
| **E. Облачные Linux-агенты + CI как оракул** | Claude auto-fix PR / Seer hand-off / Codex cloud правят код без сборки; Bitrise CI валидирует. | Ноль инфраструктуры; быстро стартовать; хорош для lint/compile/очевидных тестов. | Не воспроизводят и не отлаживают flaky (нет Xcode); каждая итерация = полный CI-цикл (дорого/долго); авто-fix реагирует на CI, но не заменяет репродьюсер. | **Дополнение** к A: (1) Seer RCA как вход, (2) auto-fix на уже открытых AI-PR. |
| **F. Bitrise AI Build Fixer** | Готовая фича Bitrise. | Ничего не писать. | ⚠️ Только build failures и, вероятно, только Bitrise CI; Pro/Enterprise; закрытая логика/валидация. | Не основа. Проверить, если есть частые build-поломки. |
**Рекомендация:** **A как основа + E как дополнение (Seer RCA / auto-fix)**, затем по данным выбрать **C или B** для интерактива и снижения стоимости. Virfield — для разработки/приёмки образов и промптов локально, чтобы не жечь Bitrise-минуты на отладку.
### Claude vs Codex
- Один harness, два backend'а: `scripts/ai-fix/run-agent.sh --agent claude|codex`. Одинаковые вход/выход (`signal.json` → `summary.json` + ветка).
- Claude — первым (корпоративные ключи/плагины, `ddg-required-config`, OIDC federation, наши skills). Codex — как A/B-сравнение на одном eval-наборе и страховка от смены провайдера. Codex-action поддерживает macOS runner и `drop-sudo`; Codex cloud (Linux-контейнер) для Xcode не подходит ⚠️ (документация о macOS молчит).
- Сравнивать по метрикам §8 на одинаковых задачах, не «по ощущениям».
---
## 5. Валидация (ядро плана)
### 5.1 Лестница по типу сигнала
| Тип | Репро | Фикс считается валидным, если |
|---|---|---|
| Flaky unit/integration | `-test-iterations N` / `-run-tests-until-failure` на том же Xcode/OS, **display awake** (иначе ложные dealloc-флаки, см. 10/14). Старт — данные из CI history (rate падений). | Красный до (≥K из N), зелёный **M/M** после (M≥15–20); не маскируется (`async`); весь класс + соседи зелёные; mocks сети/настроек; `swiftlint --strict` 0; собираются схемы `macOS Browser` и `macOS Browser App Store`. |
| Failing test на main | bisect по last-green CI sha | Причина — тест или продукт? Если продукт — фикс + тест; после — unit полностью. |
| Failing UI test | запуск `single_test_class` на notarized Review build через существующий workflow | Зелёный на target OS; потом по запросу matrix 14/15/26; `-retry-tests-on-failure` не считается за «зелёный». |
| Crash (Sentry) | **обязательный репродьюсер** (unit/UI/stress-тест). Нет репродьюсера → только RCA + гипотеза, без PR. | Тест красный до фикса и зелёный после; симптом из stack trace совпадает; нет новых крашей в соседних тестах. |
| Bug (Asana) | journey-скрипт, написанный агентом | Один и тот же скрипт, запущенный на base и на fix, показывает разницу; acceptance criteria из тикета; человек подтверждает направление до PR (двухшаговый режим). |
### 5.2 Обязательный evidence bundle
`summary.json` по схеме: `signal_id`, `classification`, `root_cause`, `confidence`, `repro: {command, before: k/n fail, after: m/n pass}`, `validation: {schemes, lint, test_classes}`, `files_changed`, `outcome: fix | guard_tests_only | not_reproduced | needs_human`, `risks`, `commands_run`, плюс `.xcresult`/логи. PR-описание генерируется детерминированно из этого файла.
### 5.3 Защита от «агент врёт»
- Валидацию выполняет **скрипт**, а не LLM: агент даёт команду/тест, harness сам гоняет N раз и сам считает.
- Приём Artur'а: **единый journey-скрипт для base и fix**.
- Мутационная проверка (как 10/14): намеренно вернуть баг → тест обязан упасть.
- Второй агент в чистом контексте — reviewer по `REVIEW.md` (`/code-review`), результат — комментарий в PR, не блокер.
- **Ограничение диффа:** лимит файлов/строк; изменение тестовой инфраструктуры/assertions без причины → `needs_human`; запрет ослаблять assertions и удалять тесты (как в skill `macos-uitest`).
### 5.4 Eval-набор до включения автоматики
Золотые кейсы (известный «правильный» фикс): AddressBarTests flake (корень в 2 местах), Ask AI Chat button animation leak, DeallocationTests display-sleep crash, Fire Window leak (**ожидаемый исход = not_reproduced**), плюс 5–10 исторических фиксов из `git log`/Asana «Apple CI Failing Tests». Метрики: найден ли корень, валиден ли фикс, **не придуман ли фикс там, где его нет**. Порог включения расписания — оговорённый заранее.
---
## 6. Безопасность и приватность
Угрозы и меры:
- **Prompt injection** через Sentry/Asana/PR-комментарии → входы как данные; минимальный `--allowedTools`; нет write-MCP; бюджет `--max-turns`; запрет сети кроме allowlist.
- **Exfiltration:** агент без секретов приложения; GitHub App-токен узкий (`ai/*`); OIDC вместо статических ключей; **внутренние данные только в `signal.json` после scrub** (user data, URLs, PII) в доверенном Linux job; для Windows-версии уже открыт privacy follow-up по передаче blob → завести аналогичный triage для Apple.
- **Egress на Bitrise-раннерах** не контролируем → in-VM **Seatbelt sandbox** (Claude Code / Codex на macOS) + proxy allowlist (github.com, api.anthropic.com/api.openai.com, нужные registry/CDN); в варианте B — pf на хосте.
- **SSH forwarding** (из triage): не пробрасывать `SSH_AUTH_SOCK`; в RDE-варианте — как в AT2/AT3.
- **Подпись:** build-with-secrets и agent — разные jobs; UI-тесты на ветке `ai/*` идут тем же путём, что человеческий PR (ruleset + environment approvals для secrets).
- **Kill switch:** `vars.AI_FIX_ENABLED`, дневной бюджет $, `maxActiveRuns`, allowlist классов/путей (по умолчанию не трогаем: подписи, entitlements, `Package.swift` внешних зависимостей, релизные workflows, `.github/**`).
- **Аудит:** transcript + commands в артефакт 30 дней (по аналогии с Virfield journal).
- Review-гейты: privacy-triage на изменение (если PR трогает pixels/privacy — Danger/`privacy-review.yml` уже есть); PR template требует Asana-ссылку → **задачу Asana создаёт/привязывает человек или детерминированный сервис**, не агент.
- Не повторять: автономный LLM-оркестратор; запись в Asana/Discord из агента; прокси подписочных OAuth-токенов.
Нужные согласования (параллельно с Phase 0): privacy triage + security triage на (а) Bitrise-runner + Anthropic/OpenAI API с кодом apple-browsers, (б) передачу scrubbed Sentry-данных, (в) Claude self-hosted (если C).
---
## 7. Поэтапный план
### Phase 0 — выравнивание (≈1 нед, 2–3 чел-дня)
- Прийти в «AI Agent Infrastructure» ([проект](https://app.asana.com/1/137249556945/project/1219113011535833)) и к Chris Clarke: зафиксировать, что apple-browsers = build-and-fix на macOS через GHA + Bitrise (то, о чём уже договорились в комментариях), а не новый стек.
- Свести с Artur/Sebastien/Tim (flux/pstack, verification) и Bárdi (Prefect crash flow, Windows runner) — взять **их** harness/skills, не писать свой; наш вклад — macOS-специфика (Xcode, XCTest, display sleep, UITestCase).
- Открыть privacy/security triage (§6). Заказать dedicated API key (форма из тикетов) или OIDC federation.
- Baseline-метрики: доля retry в CI, топ-N flaky-тестов за 30 дней (из JUnit), открытые «Apple CI Failing Tests».
- Результат: решение по venue A, список stakeholders, согласованные guardrails.
### Phase 1 — детерминированный каркас + report-only (≈2 нед, ~8 чел-дней)
- Workflow `ai_triage_macos.yml` (schedule + dispatch): собирает JUnit из последних main/ночных запусков (`process-test-results`, `gh api` — как `ddg-diagnose-ci-failure`), считает fail-rate, фингерпринты, дедуп, eligibility; публикует отчёт (Mattermost/job summary). **Без LLM-записи.**
- Схемы `signal.json` / `summary.json`; `run-agent.sh` (claude|codex), allowlist путей, бюджет.
- Eval-набор из §5.4 + harness локально на **Virfield** (дешёвая отладка промптов на образе Xcode 26.4; при необходимости собрать образ из `image_create`).
- Spike S1 (claude/codex CLI на Bitrise-раннере: установка, auth, Seatbelt, стоимость минуты на одном тесте).
- Exit: отчёт ежедневно; eval-harness прогоняется; S1 дал цифры времени/стоимости.
### Phase 2 — агент для тестов: draft PR по запросу (≈3 нед, ~12 чел-дней)
- `ai_fix_test.yml` (`workflow_dispatch`: `test_id`, `agent`, `mode`): Linux intake → macOS agent job (analyze → repro N раз → fix → validate) → evidence bundle → draft PR `ai/fix/<fp>` с лейблом.
- Человек запускает вручную (как `$auto` у Duck.ai). Дальше — существующий PR CI; UI-тесты — отдельный dispatch оркестратора.
- A/B Claude vs Codex на eval-наборе.
- Цикл PR-feedback: комментарий `@ai-fix` или повторный dispatch → тот же ветка + context-transfer ZIP; опционально Claude auto-fix для CI-падений на `ai/*` (вариант E).
- Exit: ≥ порога по eval (корень найден, нет ложных фиксов); 5 реальных PR прошли ревью; средняя стоимость фикса измерена.
### Phase 3 — крэши: Sentry → proposal → draft PR (≈3 нед, ~12 чел-дней)
- Pre-fetch в доверенном Linux job (Sentry MCP/API; репозитории `apple-ios`, `apple-macos`; фильтр `firstRelease`, `app_version`, события ≥N; переиспользовать логику `ddg-sentry-report`) → scrub → `signal.json`.
- Параллельно **trial Seer** на `apple-macos` в режиме «Stop after Solution» (если approve privacy): использовать RCA как дополнительный вход/бенчмарк; сравнить с нашим агентом.
- Двухшаговый режим по умолчанию: proposal (root cause + репродьюсер-тест + направление) → комментарий владельцу → после «да» агент делает PR. После накопления доверия (как в Windows-кейсе) — авто draft PR для краш-классов с воспроизведённым тестом.
- Exit: ≥X краш-находок с репродьюсером; доля принятых владельцами направлений.
### Phase 4 — автоматизация и интерактив (≈4–6 нед, по результатам)
- Включить расписание (ночной запуск top-K eligible), лимиты/бюджет, дашборд метрик.
- Выбор интерактива по данным: **C** (если Anthropic подтвердит macOS), **B** (если стоимость Bitrise-минут/сеть упрутся), или оставить D для редких случаев.
- Багфиксы из Asana (класс 4) — только после доказанной надёжности на 1–3 и в связке с flux/pstack.
- Решение о релизных ветках — отдельно.
Ориентировочно до Phase 3 включительно: ~**8–10 недель календарно, ~35–45 чел-дней** (оценка грубая; сильно зависит от triage и результатов S1).
---
## 8. Метрики и критерии остановки
- **Acceptance rate:** доля AI-PR, вмёрдженных без существенной переделки.
- **Precision:** доля фиксов, прошедших эксплуатацию без регрессии; доля `not_reproduced`, которые на самом деле были реальными (false negative).
- **Cost per merged fix** (токены + Bitrise-минуты), **time-to-PR**, **reviewer-minutes per PR**.
- **Flaky rate / CI retry rate** в main до/после; для крэшей — CPMN/crash-free дельта по затронутым сигнатурам.
- Стоп-условия: acceptance < порога два цикла подряд; любой инцидент утечки; бюджет превышен → автоматический kill switch.
---
## 9. Риски
| Риск | Митигирование |
|---|---|
| Агент «чинит» симптом (ослабляет assertion, добавляет sleep/retry) | Запрет в prompt + diff-политика + harness сам считает N/N + мутационная проверка |
| Ложные фиксы flaky (сломали тест, а не продукт) | Классификатор «test bug vs product bug» + review-агент + owner |
| Display sleep/окружение даёт другое поведение, чем CI | Тот же образ/Xcode, `caffeinate`/display awake, сравнение с CI-историей |
| Xcode-расхождение (26.4 vs 27) | Образ строго по `.xcode-version`; Virfield-профиль 26.4 |
| Стоимость Bitrise-минут/токенов | Бюджеты, top-K, ночной режим, Claude-sonnet по умолчанию, кэш (Bitrise build cache action) |
| Prompt injection через Sentry/Asana | Scrub + data-only + минимальные tools + sandbox |
| Дублирование чужих усилий (flux/pstack/Prefect/Bug Squisher) | Phase 0, общий harness, наш вклад — macOS-слой |
| Бесконтрольный рост PR'ов | Один fingerprint = один PR, лимит открытых AI-PR, stale-auto-close |
| Зависимость от личной инфраструктуры (Virfield на одном Mac) | Virfield не в production-пути |
| Beta-фичи Anthropic (self-hosted, routines `experimental` header) | Не ставим на критический путь до GA |
---
## 10. Открытые вопросы (нужны решения/данные)
1. Подтвердить venue A: кто DRI по macOS в AI Agent Infrastructure и можно ли выделить runner-label Bitrise под agent-jobs.
2. ⚠️ S1: работает ли `claude -p`/claude-code-action на Bitrise macOS runner (auth, Seatbelt, сеть)? Сколько стоит минута/задача?
3. ⚠️ Ответ Anthropic: macOS runner для self-hosted environments — сроки и поддержка.
4. Privacy/security: можно ли отправлять scrubbed Sentry-стектрейсы и код apple-browsers агенту на Bitrise-раннере (OpenAI — отдельное согласование).
5. Где живёт конвейер: apple-browsers (`.github/workflows`) vs отдельный репозиторий + общий flux-плагин.
6. Кто владеет Asana-привязкой PR (шаблон требует ссылку на Asana): детерминированный сервис или человек.
7. Android: уточнить, есть ли отдельный проект (не нашёлся) — возможно, паттерн можно просто переиспользовать.
8. Нужен ли пилотный режим «только iOS/macOS unit-flaky» перед крэшами (рекомендую да).
---
## 11. Первые конкретные шаги (на эту неделю)
1. Написать короткий комментарий/таск в AI Agent Infrastructure с этим планом и вопросами 1–3 (без дублирования проектов).
2. Собрать eval-набор (4–5 кейсов из 10/14 + 5 из истории) и описать «ожидаемый исход».
3. Локально на Virfield (или на dev-Mac) прогнать `claude -p` по одному кейсу с harness'ом «N× до/после» — получить baseline качества и стоимости до любых CI-интеграций.
4. Сделать spike S1 на Bitrise runner в отдельной ветке (workflow_dispatch, один тест).
5. Подготовить draft privacy/security triage для (а) и (б).
Связанные: [[work/wiki/apple-browsers/ci-pipeline]], [[work/wiki/apple-browsers/vm-ui-testing]], [[personal/projects/virfield]], [[personal/projects/personal-os/executor-v2-redesign]], [[personal/projects/personal-os/executor-security-analysis]], [[personal/projects/personal-os/personal-os-failed-approaches]], [[work/projects/macos-tests-worktrees-2026-10-14]], [[Research/Isolation of Agent Execution - OS and Container Level]].