Тема
Контракт автоматизации Android
Этот runbook — канонический контракт общей автоматизации workspace. Историческая Phase A определяла только документацию. Сейчас существуют также read-only средства Phase B в scripts/automation/; они проверяют контракты, а не собирают приложения. Пользовательская задача от 21 сентября 2026 года добавляет отдельный рабочий цикл APK для создания и последовательной проверки проекта. Он не превращает manifest Phase B в исполняемый CI/device pipeline.
Текущие исполняемые входы
| Средство | Результат и граница |
|---|---|
scripts/automation/evidence-check.sh --phase-b-contract | Статическая проверка контракта Phase B, без Android build/device. |
scripts/scaffold-native-compose.sh | Создание самостоятельного native-проекта с явно заданными именем и package ID. |
scripts/android-iterate.sh | Последовательная локальная проверка явно заданного проекта; device и публикация не считаются пройденными по успеху сборки. |
codex/plugins/android-development | Инструкции и хуки агента; активация и ограничения описаны в Android plugin. |
Приведённые ниже границы Phase A/B сохранены как контракт именно этих стадий. Они не требуют повторного разрешения на уже запрошенную подготовку рабочего цикла. SDK/AVD reset, удаление данных, signing и внешние действия продолжают подчиняться актуальным проектным правилам и точному scope пользователя.
Для общих environment-правил и owner gates используйте workspace promt.md, root AGENTS.md и Linux environment. Текущие факты приложения остаются только в его собственных документах: chess-android/docs/VERIFICATION.md и arcade-android/docs/UBUNTU_EMULATOR.md. Этот runbook и automation-ledger.md не заменяют эти источники.
Scope и границы Phase A
- В scope: contract для evidence, ledger, lanes, locks, классификаций, retention и безопасного resume.
- Вне scope: реализация runner, shell scripts,
.gitea/workflows/, CI runners, signing, Play, публикация, загрузка артефактов и любые environment/device мутации. - Единственный workspace ledger — automation-ledger.md. Он содержит краткие ссылки и digests, но не raw logs, screenshots, отчёты тестов, credentials или значения proxy.
- Единственный machine-readable contract будущего сценария — scenario-manifest.schema.json. Сценарий выбирается явно; runner не выводит lane, package или serial по имени приложения либо по первому подключённому устройству.
Канонические источники и lanes
| Lane | Допустимый app root | Контракт проверки | Особая граница |
|---|---|---|---|
native-compose | chess-android, templates/native-compose или новый самостоятельный native root | project Gradle Wrapper и его scripts/doctor.sh/scripts/verify.sh, когда они существуют | shared SDK/AVD/cache не смешивать с Arcade; connected test требует явный ANDROID_SERIAL. |
capacitor | arcade-android | package.json и project-local bootstrap/verify interface | Node/JDK/SDK/AVD/cache Arcade project-local; generic loop не вызывает destructive device scripts. |
network-data-device | Явно названный app root с принятым контрактом | дополняет одну из двух базовых lanes | Добавляет только подтверждённые contract, migration, offline, auth/permission и lifecycle scenarios. |
network-data-device не является третьим самостоятельным stack: manifest должен также назвать одну base lane. Нельзя переносить Arcade paths, Node/SDK, AVD или evidence в Chess/template и наоборот.
Evidence record
Каждая завершённая или остановленная стадия создаёт один компактный record в app-local canonical evidence и одну ссылочную строку в workspace ledger. Record обязан содержать:
| Поле | Требование |
|---|---|
outcome | Один app или environment outcome и строгая граница. |
timestamp | ISO 8601 с timezone. |
app_root, lane, stage | Явный app root, выбранная lane и одна стадия. |
tree_identity | Commit/tree identity либо явное Git absent/Git diff unavailable. |
owners | Writer для docs/evidence и все затронутые SDK, AVD, device, cache, Git index. |
locks | Требуемые resource locks и состояние acquire/release; незахваченный ресурс так и обозначается. |
contract_refs | Относительные пути к AGENTS/README/wrapper/manifest и проверяемым интерфейсам. |
command и exit_status | Точная выполненная команда и её exit status; для неисполненной стадии — not run, не предположение. |
evidence_ref | App-local output path или CI artifact reference; в ledger только path, digest и краткий result. |
classification | Одна классификация из следующего раздела либо not-applicable для успешной стадии. |
unknowns, risks, next_action | Непроверенные факты, остаточный риск и одна безопасная следующая команда или owner gate. |
Нельзя помещать в record .env, keystore/JKS, signing.properties, service-account/OAuth JSON, passwords, tokens, proxy values, raw stdout/stderr или персональные данные. Для безопасного diagnostic record достаточно типа ошибки и sanitised stable fingerprint.
Стадии, классификации и retries
Последовательность: discovery → spec-gate → implementation → static-audit → unit-build → device-smoke → evidence → triage → next-iteration. Пропущенная стадия не является pass. Static audit предшествует дорогой сборке; device smoke допускается только после зелёного build gate, когда он доказывает изменённый Android contract.
Допустимые классификации: CODE, TEST, ENVIRONMENT, BASELINE, TRANSIENT, POLICY, OWNER. Fingerprint имеет форму:
text
goal + failing gate + classification + stable signature + app/tree identity
+ environment/AVD/serial/cache state + attempted remedyПервое совпадение фиксирует evidence и меняет одну гипотезу. Второе совпадение с тем же fingerprint меняет метод либо сужает scope. Третье совпадение без нового evidence прекращает retry, сохраняет состояние и создаёт ровно одну корректирующую задачу или owner prompt. ENVIRONMENT не разрешает маскировать host failure изменением кода; POLICY и OWNER не угадываются.
Locks и safe resume
Будущая Phase B может реализовать эти имена через flock только в игнорируемом workspace-local .automation/locks/. Phase A их не создаёт и не удаляет.
| Ресурс | Lock | Единственный writer |
|---|---|---|
Shared docs, SDK, .gradle-user-home, AVD codex-api36 | workspace-environment.lock | Один environment run. |
| Gradle user home приложения | gradle-<app>.lock | Один build/test для этого cache. |
| AVD и resolved ADB serial | avd-<name>.lock, device-<serial>.lock | Один emulator/device scenario. |
| Project-local Arcade SDK/AVD/cache | arcade-environment.lock | Один Arcade environment run. |
| App evidence и workspace ledger | evidence-<app>.lock, automation-ledger.lock | Один documentation writer. |
| Emulator/local preview port | port-<number>.lock после проверки владельца | Один launcher/preview. |
Lock record в будущей реализации обязан содержать PID, start time, purpose, app root и expected cleanup. Stale lock не удаляется автоматически: resumed run сначала подтверждает, что PID не жив и ресурс не используется, затем записывает причину takeover в ledger. AVD, device и Gradle cache никогда не разделяются между parallel jobs.
Resume возможен только после сверки checkpoint, instruction chain, dirty/tree identity и locks. Если меняется любая из этих identity, run возвращается к discovery, а не переиспользует старый build/device result.
Manifest и пример контракта
Manifest валиден только против схемы, содержит явные app.root, base_lane, outcome, stages и evidence references. В нём нет command text, credentials, package guessing или неявного device selection.
json
{
"schema_version": "1.0",
"app": {"root": "chess-android", "base_lane": "native-compose"},
"outcome": "Verify a documented Stage 1 contract without device mutation",
"stages": [
{
"id": "static-audit",
"evidence_refs": ["chess-android/docs/VERIFICATION.md"]
},
{
"id": "unit-build",
"evidence_refs": ["chess-android/scripts/verify.sh"]
}
]
}Это пример данных контракта, а не разрешение выполнять verify.sh. Его app paths существуют на момент Phase A; отсутствие исполняемого файла при будущем run классифицируется как BASELINE или OWNER по факту, не исправляется автоматически.
Retention, rollback и переход фаз
- Project-local ignored output или CI artifacts хранят raw logs, screenshots и test reports по retention rules конкретного приложения/CI. Ledger хранит только reference, digest, timestamp и summary.
- Не удаляйте SDK, AVD, cache или evidence ради cleanup. Retention/deletion требует отдельного resolved target и разрешения владельца.
- Rollback Phase A — удалить только invocation будущего contract из runbook; он не предполагает удаление environment state. Так как Phase A не создаёт invocation или mutable resource, его безопасный откат — review/реверт только этих трёх contract files.
- Phase B требует отдельной задачи после review diff, детерминированной статической проверки и письменного residual-risk decision. Она может добавить только read-only orchestration, но не CI/device/SDK mutation.
Acceptance Phase A
Phase A завершена, когда существуют только этот runbook, ledger и JSON schema; они взаимно ссылаются, задают evidence fields, classifications, locks, lanes и retention; JSON синтаксически валиден; ссылки и пример проверены статически без build/device tool. Signing, Play, legal declarations, CI, SDK/AVD/device и Gradle cache остаются непроверенными owner/следующими gates.