178 lines
13 KiB
Markdown
178 lines
13 KiB
Markdown
# Task 11: Зелёный пайплайн и достоверность отчётов (hermes-android)
|
||
|
||
**Repo:** `ochenstarik-ui/hermes-android`
|
||
**Assigned to:** Antigravity (режим оркестратора, два кодера)
|
||
**Priority:** BLOCKER (десять заданий приняты по непроверенным отчётам)
|
||
**Date:** 2026-08-25
|
||
**Base SHA:** `bf4e2db` (task 10)
|
||
|
||
## Статус
|
||
|
||
Задания 01–10 выполнены и запушены. Существенная часть работы сделана корректно: мёртвый слой удалён, R8 включён, строки вынесены в ресурсы, таймлайн атомарен, порядок событий детерминирован.
|
||
|
||
Но **CI не отработал ни одного раза за всё время**. Все прогоны после задания 04 красные, включая три последних пуша:
|
||
|
||
```text
|
||
32764324445 task 10 failure
|
||
32760656082 task 09 failure
|
||
32758701648 task 08 failure
|
||
32753786705 task 07 failure
|
||
32750927851 task 06 failure
|
||
```
|
||
|
||
Значит: юнит-тесты, lint, `assembleDebug` и инструментальные тесты в CI **не выполнялись ни разу** ни на одном коммите. Все отчёты, заявляющие «83/83 passed», «BUILD SUCCESSFUL», «0 errors», опираются на локальные прогоны `gradlew.bat` на Windows-хосте. Ни один из них не подтверждён средой, которую задание 04 объявило работающей.
|
||
|
||
## Проблема
|
||
|
||
**1. `gradlew` без бита исполнения.** В индексе git режим `100644`:
|
||
|
||
```text
|
||
$ git ls-files -s gradlew
|
||
100644 faf93008b77e7b52e18c44e4eef257fc2f8fd76d 0 gradlew
|
||
```
|
||
|
||
Оба Android-джоба падают на первом же шаге:
|
||
|
||
```text
|
||
/home/runner/work/_temp/....sh: line 1: ./gradlew: Permission denied
|
||
##[error]Process completed with exit code 126
|
||
```
|
||
|
||
Шаги `Run Android Lint` и `Assemble Debug APK` в логе помечены `-` — они не запускались. Джоб инструментальных тестов падает там же, после `adb ... failed with exit code 1`.
|
||
|
||
**2. Clippy падает на коде задания 07.** Не исправлено с 2026-08-24:
|
||
|
||
```text
|
||
error: this `if` statement can be collapsed
|
||
--> src/pairing.rs:190:5
|
||
= note: `-D clippy::collapsible-if` implied by `-D warnings`
|
||
error: could not compile `hermes-pair` (lib) due to 1 previous error
|
||
```
|
||
|
||
**3. Ложное «закрыто» в итоговой таблице задания 10.**
|
||
|
||
```text
|
||
| SEC-02 | ... | 06 | закрыто | 861e04b (hermes://auth-callback) |
|
||
| BUILD-03 | ... | 04 | закрыто | 3ec16c4 |
|
||
```
|
||
|
||
`SEC-02` не закрыт: живой путь входа по-прежнему открывает loopback-сокет (подробности — задание 12). `BUILD-03` не закрыт: пайплайн не отработал ни разу. Анти-чеклист задания 10 пункт 11 предупреждал ровно об этом и был отмечен пройденным.
|
||
|
||
**4. Таймингозависимые ожидания вернулись.** Задание 04 убрало пять `delay(50)`, задания 02, 08 и 09 внесли семь новых:
|
||
|
||
```text
|
||
app/src/test/java/app/hermes/mobile/core/network/ReadyDeferredRaceTest.kt
|
||
app/src/test/java/app/hermes/mobile/core/repository/CacheEvictionTest.kt
|
||
app/src/test/java/app/hermes/mobile/core/repository/SessionCreateRaceTest.kt
|
||
app/src/test/java/app/hermes/mobile/core/repository/ToolAttributionTest.kt
|
||
```
|
||
|
||
**5. Мусор в репозитории.** `agy-work/` — 11 продублированных файлов заданий вне `agents/<agent-id>/`, что запрещает `AGENTS.md §4`. `schemas/1.json` в корне — осиротевший дамп схемы Room из задания 02, рабочие схемы лежат в `app/schemas/`.
|
||
|
||
**6. Битая строка манифеста.** `AndroidManifest.xml:7` — `<uses-feature .../>` и `<uses-permission .../>` склеены в одну строку.
|
||
|
||
## Роли и протокол
|
||
|
||
| Роль | Модель | Что делает |
|
||
|---|---|---|
|
||
| Оркестратор | Antigravity | Маршрутизирует, принимает результат |
|
||
| Кодер 1 | Gemini Flash 3.7 high | Пункты 1–6 §Scope |
|
||
| Кодер 2 | Gemini Pro high | Независимая проверка, доводка, пункт 7 |
|
||
|
||
**Изменение протокола приёмки, действует с этого задания и далее.**
|
||
|
||
Отчёт больше не является доказательством. Пункт `§Required verification` считается выполненным только при выполнении обоих условий:
|
||
|
||
1. приложен вывод `gh run list --limit 5` с прогоном на итоговом SHA в статусе `success`;
|
||
2. приложен вывод `gh run view <id>` со всеми джобами в `✓`.
|
||
|
||
Формулировки «BUILD SUCCESSFUL», «tests passed», «green» без этих двух выводов не принимаются ни от одного из кодеров. Локальный прогон на Windows — вспомогательное свидетельство, а не замена.
|
||
|
||
## Scope
|
||
|
||
**1. Бит исполнения.**
|
||
```text
|
||
git update-index --chmod=+x gradlew
|
||
```
|
||
Проверить `git ls-files -s gradlew` → `100755`. Убедиться, что в `.gitattributes` нет правила, сбрасывающего режим.
|
||
|
||
**2. Clippy.** Схлопнуть вложенный `if` в `hermes-pair/src/pairing.rs:190`:
|
||
|
||
```rust
|
||
if (!trimmed_host.starts_with('[') || !trimmed_host.ends_with(']'))
|
||
&& trimmed_host.contains(':')
|
||
{
|
||
return Err(PairingError::InvalidHost(format!(
|
||
"Host '{}' contains forbidden colon delimiter outside IPv6 brackets",
|
||
payload.host
|
||
)));
|
||
}
|
||
```
|
||
|
||
Затем прогнать `cargo clippy --all-targets -- -D warnings` локально и убедиться, что других предупреждений нет: CI проверяет только `--lib` по текущей конфигурации, а после фикса могут вскрыться остальные.
|
||
|
||
**3. Джоб инструментальных тестов.**
|
||
После пункта 1 перезапустить и разобрать, проходит ли эмулятор. Если `adb ... exit code 1` сохранится — диагностировать отдельно: уровень API, `arch`, таймаут загрузки, `disable-animations`. Джоб обязан быть либо зелёным, либо с явно зафиксированной причиной невозможности запуска на раннере — но **не** отключённым и не с `continue-on-error`.
|
||
|
||
**4. Детерминированные ожидания.** Семь `delay(50)` в четырёх файлах перевести на `runTest` с виртуальным временем, `advanceUntilIdle()` и `Turbine`. Ассерты не менять — только способ ожидания; сверить построчно до и после.
|
||
|
||
**5. Уборка.** Удалить `agy-work/` и `schemas/1.json`. Черновики держать в `agents/antigravity/notes/`. Починить строку 7 манифеста.
|
||
|
||
**6. Прогон и фиксация.** Довести пайплайн до полностью зелёного состояния на итоговом SHA и приложить оба вывода из §Роли.
|
||
|
||
**7. Ревизия таблицы сверки (кодер 2).**
|
||
Пройти таблицу «находка → задание → статус» из отчёта задания 10 по всем 63 позициям заново, сверяя **с кодом и с логами CI**, а не с отчётами предыдущих заданий. Каждую позицию подтвердить или переоткрыть. Как минимум:
|
||
|
||
- `SEC-02` → **открыто**, перенесено в задание 12;
|
||
- `BUILD-03` → **открыто**, закрывается этим заданием;
|
||
- `DATA-01` → сверить: миграция подтверждается только зелёным `connectedDebugAndroidTest`, до того `UNVERIFIED`;
|
||
- все позиции, чей статус опирался на «BUILD SUCCESSFUL» из отчётов, пересчитать после первого зелёного прогона.
|
||
|
||
Исправленную таблицу поместить в отчёт этого задания. Отчёт задания 10 не переписывать — он остаётся историческим документом; расхождение фиксируется здесь.
|
||
|
||
## Do not change
|
||
|
||
- Продуктовую логику заданий 01–10. Это задание чинит инфраструктуру и достоверность, а не поведение.
|
||
- `PkceLoopbackAuthManager` и `network_security_config.xml` — задание 12.
|
||
- `dismissClarify` — задание 12.
|
||
- Ассерты существующих тестов.
|
||
- Версии зависимостей.
|
||
|
||
## Anti-checklist
|
||
|
||
1. Бит выставлен локально, но не закоммичен: `git ls-files -s` по-прежнему `100644`. Проверять индекс, а не рабочее дерево — этот фикс уже один раз не долетел.
|
||
2. Вместо бита в workflow добавлен `chmod +x gradlew` шагом. Это маскировка: любой другой потребитель репозитория останется сломанным. Требуется именно режим в индексе.
|
||
3. Clippy починен, но прогон делался с `--lib`; на `--all-targets` вылезли новые ошибки, и они «отложены».
|
||
4. Джоб эмулятора обойдён через `continue-on-error`, `if: false` или удаление.
|
||
5. `delay(50)` заменены на `Thread.sleep` или на увеличенные таймауты.
|
||
6. Ассерты изменены заодно с переводом ожиданий.
|
||
7. В отчёте снова «BUILD SUCCESSFUL» без вывода `gh run view`.
|
||
8. Таблица сверки скопирована из задания 10 с точечной правкой двух строк вместо повторного прохода по 63 позициям.
|
||
9. Позиции, закрытые в 01–10 на основании локальных прогонов, оставлены «закрыто» без подтверждения первым зелёным CI.
|
||
|
||
## Definition of Done
|
||
|
||
- `git ls-files -s gradlew` → `100755` в `origin/main`.
|
||
- Полный прогон CI на итоговом SHA: все джобы `✓`, приложены выводы `gh run list` и `gh run view`.
|
||
- Отдельным прогоном подтверждено, что намеренно сломанный юнит-тест валит пайплайн — приложен лог, коммит откачен.
|
||
- `cargo clippy --all-targets -- -D warnings` чистый.
|
||
- Ни одного `delay`-ожидания в тестах; ассерты не изменены.
|
||
- `agy-work/` и `schemas/1.json` отсутствуют; манифест валиден и отформатирован.
|
||
- Таблица сверки пересчитана по коду и логам, `SEC-02` и `BUILD-03` переоткрыты, каждая из 63 позиций имеет статус, подтверждённый ссылкой на код, коммит или лог CI.
|
||
|
||
## Required verification
|
||
|
||
```text
|
||
git ls-files -s gradlew
|
||
gh run list --limit 5
|
||
gh run view <run-id>
|
||
cd hermes-pair && cargo clippy --all-targets -- -D warnings
|
||
```
|
||
|
||
Локальные прогоны Gradle прикладывать дополнительно, но они не заменяют CI.
|
||
|
||
## Result
|
||
|
||
`agents/antigravity/done/TASK-2026-08-25-11-green-pipeline.md` — разделы `## Кодер 1`, `## Кодер 2 (review + доработка + пункт 7)`, `## Пересчитанная таблица по 63 находкам`, `## Вердикт оркестратора`.
|
||
|
||
BLOCKER не закрывается по заявлению исполнителя. Пока в отчёте нет `gh run view` с зелёными джобами, задание считается невыполненным независимо от содержания остального текста.
|