Разбор Расхождения Ветки
Запуск Навыка
При явном вызове или однозначном смысловом совпадении применяйте навык сразу. Перед первым шагом покажите ровно одну короткую контекстную строку (не более 30 слов) и продолжайте работу в том же ответе, не ожидая реакции:
Применяю экспериментальный навык «Разбор расхождения ветки» (обратная связь — @kir-kopylov): <кратко назовите конкретную пользу для текущего запроса>; продолжаю без ожидания.
Не включайте в строку author_github, внутреннее имя папки или пересказ всего запроса. Не спрашивайте, применять ли навык.
Если одновременно подходят совместимые навыки, выберите минимальный набор и покажите одну общую строку. Если подходы ведут к несовместимым результатам и запрос не позволяет выбрать, спросите только о желаемом результате, не о разрешении применить навык.
Запуск навыка не расширяет полномочия. Выполните всю безопасную и уже разрешённую часть; запросите подтверждение только непосредственно перед ещё не разрешённым внешним или изменяющим действием. Не запрашивайте повторно уже данное разрешение и не дублируйте системное окно подтверждения.
Обзор
Ветка отстала от базы, и непонятно, что в ней ещё своё. Опасность здесь не в конфликтах, а в их отсутствии: одинаковые файлы система слияния схлопнет молча, а конфликты оставит ровно там, где ваша сторона устарела. Ответ «оставить нашу версию» выглядит там естественно и молча откатывает уже принятую чужую работу.
Навык строит пофайловое доказательство до выбора механизма переноса. Он ничего не меняет и заканчивается вердиктом.
Живой случай, из которого навык вырос: ветка отставала на пять коммитов, половина её работы уже была влита другим PR, 18 файлов из 33 оказались дословными дублями. Наивное сравнение с вершиной базы дало ложный результат — считать надо от точки слияния.
Естественные Входы
- «ветка отстала от main, что с ней делать»
- «можно ли тут просто сделать rebase»
- «что в этой ветке моё, а что уже влито»
- «как донести эту работу до main»
- «стоит ли эту ветку вообще спасать»
Процесс
1. Снять состояние без изменений
Ветка и база нужны как ревизии, а не как рабочее дерево. Незакоммиченную работу разбор не видит, поэтому при грязном дереве скрипт сам останавливается со статусом BLOCKED_DIRTY_TREE и вердикта не выносит. Зафиксируйте работу коммитом; флаг --allow-dirty применяйте, только если убедились, что незакоммиченное к разбираемой ветке не относится.
Свежий git fetch обязателен: база могла уехать за время работы.
2. Классифицировать пофайлово
python3 scripts/classify_divergence.py --repo <путь> --branch <ветка> --base origin/main
Скрипт считает от точки слияния и раскладывает файлы по четырём классам:
IDENTICAL— совпали и содержимое, и режим записи дерева; переносить нечего;STALE_ONLY— всё, что ветка добавила и удалила, база уже сделала сама;UNIQUE— ветка несёт изменение, которого в базе нет, а база файл не трогала;CONFLICTING— файл меняли обе стороны либо изменение нельзя развести автоматически.
Строки сравниваются с учётом кратности, а удаления учитываются наравне с добавлениями: ветка, которая только удаляет строки, несёт работу и в STALE_ONLY не попадёт.
Коды возврата: 0 разбор построен, 1 ошибка входа, 2 упал git или самотест мёртв, 3 вердикт требует решения человека.
3. Выдать вердикт
Скрипт выносит один из четырёх:
REBASE_SAFE— ветка только впереди базы, перенос механический;SUPERSEDED— уникального нет, ветку можно закрывать;MANUAL_ASSEMBLY— уникальное лежит в файлах, которых база не трогала: собрать ветку заново от свежей базы и перенести только их;NEEDS_REVIEW— естьCONFLICTING, решение за человеком.
Покажите пользователю короткую сводку простыми словами: сколько файлов переносить не нужно, сколько своих, что делать дальше. Полную таблицу приложите, а не пересказывайте.
Если запрошенное действие расходится с вердиктом, ответьте в формате:
Стоп.
Факт: <что наблюдаемо>.
Расхождение: <запрошено> vs <что показывает разбор>.
Шаг: <одно действие>.
Проверка: <ожидаемый результат>.
4. Передать исполнение
Навык на этом заканчивается со статусом DIVERGENCE_CLASSIFIED. Перенос, ветку, тесты, PR и уборку делает provedenie-vetki-do-uborki; вердикт задаёт ему состав. Если ветка найдена восстановлением сессии, стартовая точка — narabotki-sessii-v-vetku.
Границы
Не применяйте навык для разрешения конфликта внутри одного файла, для отладки CI и для обычного вопроса про git без намерения переносить работу. Не применяйте, когда ветка не отстаёт: там разбирать нечего.
Нельзя:
- называть файл дословным дублем по совпадению имени, размера или сводки изменений — нужен совпавший хэш blob;
- считать расхождение от вершины базы вместо точки слияния: между базой ветки и вершиной могли пройти чужие коммиты, и разбор соврёт;
- читать пути от git построчно: имена бывают с пробелами, кавычками и кириллицей, нужен разбор по нулевому байту;
- объявлять работу перенесённой по родству коммита — при squash-слиянии хэш другой, и проверка даёт ложное «нет»; доказывать содержимым в базе;
- считать пустой список добавленных строк доказательством того, что переносить нечего: ветка могла только удалять, менять порядок или права на файл;
- удалять, сливать, перемещать ветки и трогать рабочее дерево: навык только читает;
- выносить вердикт по незакоммиченной работе.
Предел метода назван честно: сравнение идёт по составу строк. Чистую перестановку строк без изменения состава скрипт распознаёт как изменение, но какое именно — не знает и отдаёт такой файл человеку.
Опрос После Использования
Опрос задаётся один раз — после выдачи вердикта или явного стопа, не посреди разбора. Если пользователь уже ответил «пропустить» в этой сессии, не переспрашивайте.
Опрос по навыку:
1. Что в работе этого навыка было полезно?
2. Что стоит доработать в процедуре или формате ответа?
Можно ответить коротко или написать "пропустить".
Если пользователь ответил, сохраните санированную карточку в ~/.codex/skill-runs/verdikt-po-otstavshey-vetke/usage-feedback.jsonl — лучше через bundled script:
python3 scripts/log_usage_feedback.py --liked "..." --improve "..." --outcome "..."
Script перед записью редактирует приватные пути, контакты и token-like строки и сохраняет в JSONL redaction_applied и redaction_types. Если запись невозможна из-за sandbox, прав или отсутствия tools, не делайте вид, что лог сохранён: скажите об этом и покажите короткую JSONL-карточку для ручного сохранения. Raw-ответы, контакты, пути и секреты не коммитить.
Логирование Сбоев
Перед выполнением прочитайте локальный known-exceptions.yaml как список уже известных случаев и применяйте подходящее do_next_time без нового поиска.
Если пользователь поправил skill, tool/API/browser упал, нарушен режим работы, пришлось искать workaround или skill сделал ложное предположение, запишите приватную карточку в ~/.codex/skill-runs/<skill-name>/exception-log.jsonl.
Пишите факты: что skill хотел сделать, что сделал, где сломался, какая предпосылка была ложной и что сделать в следующий раз. Если поле неизвестно, пишите unknown. Raw logs не коммитить.