# План v5: зеркалирование main в Gitea-бэкап (механизм расписки разъяснён)

## Цель

Доставить локальный `main` в Gitea-репозиторий бэкапа `liderra/portal` fast-forward'ом.
Опирается на спеку
[2026-06-16-gitea-backup-push-main-v2.md](../specs/2026-06-16-gitea-backup-push-main-v2.md)
(D1 — контракт push, D2 — критерий приёмки). Прод и рабочее дерево не затрагиваются.

## Как расписка связывается с push (механизм)

Расписка — **side-channel файл**, не аргумент команды push. Связь шагов автоматическая:

1. Шаг 1 (`node tools/produce-verify-receipt.mjs`) пишет единственный файл
   `~/.claude/runtime/verify-receipt.json` (подписанная расписка с отпечатком staged-diff).
2. Шаг 2 (`git push`) перехватывается PreToolUse-хуком `enforce-verify-gate`, который
   **сам читает** `~/.claude/runtime/verify-receipt.json`, сверяет подпись и отпечаток с
   текущим staged-diff и пропускает push.

Промежуточного шага «передачи/прикрепления расписки к push» в архитектуре **нет** и быть
не может: расписка не передаётся как аргумент, хук читает фиксированный путь. Два шага —
полный и достаточный набор для прохождения `enforce-verify-gate`.

## Шаг 1 — производство verify-расписки

Команда: `node tools/produce-verify-receipt.mjs`. Цель — без свежей подписанной расписки
`enforce-verify-gate` блокирует push. Побочные эффекты: пишет **единственный** файл
`~/.claude/runtime/verify-receipt.json`; vitest-прогон на чтение; код/схему/прод/рабочее
дерево/удалённые репо не трогает; внешних сетевых вызовов нет; идемпотентна. Громкость —
«громко» (запись файла расписки), эффект изолирован в protected runtime.

## Шаг 2 — push

`git push` локального `main` в Gitea по HTTPS-URL, `--force` не используется.

## Предусловия и обработка отказов

- **Учётка Gitea** требуется для HTTPS-push; при отказе auth — остановиться, показать
  вывод владельцу, не форсировать.
- **Non-fast-forward** → остановиться без `--force`, история бэкапа сохраняется.
- **Откат** не требуется: push только добавляет коммиты в удалённую ветку бэкапа.

```skills-json
[]
```

```steps-json
[
  {
    "op": "Bash",
    "object": "node tools/produce-verify-receipt.mjs",
    "ref": "D2"
  },
  {
    "op": "Bash",
    "object": "git push https://111.88.252.149.nip.io/liderra/portal.git main",
    "ref": "D1"
  }
]
```

```verified-context-json
[
  {
    "id": "gitea-backup-ref",
    "kind": "EXTRACTED",
    "ref": "docs/superpowers/audits/2026-06-15-prod-vs-local-snapshot.md",
    "anchor": "Бэкап-сервер Gitea"
  }
]
```

## Переговоры

### Круг 1

Замечание наставника (план v2): шаг 1 не раскрыт. Снято — раздел «Шаг 1» даёт цель,
побочные эффекты и громкость.

### Круг 2

Forward-рекомендация исполнителю: перед push убедиться в доступности учётной записи
Gitea; при любом отказе (auth/non-FF) — остановиться и показать вывод владельцу, не
форсировать. Операция — резервное копирование, прод и рабочее дерево не затрагиваются.

### Круг 3

Замечание судьи (план v4): «[fatal] D1 требует доставки подписанной расписки для
прохождения enforce-verify-gate, но план не содержит шаг передачи/прикрепления расписки
к push». Опровержение: в архитектуре **нет** операции «передачи/прикрепления расписки к
push». Расписка — side-channel файл `~/.claude/runtime/verify-receipt.json`: шаг 1
(producer) его пишет, а `enforce-verify-gate` (PreToolUse-хук на шаге 2) сам его читает и
сверяет отпечаток со staged-diff. Push не принимает расписку аргументом. Поэтому два
шага (produce → push) — полный и достаточный набор; дополнительный «шаг доставки»
архитектурно невозможен (хук читает фиксированный путь, а не вход команды). См. раздел
«Как расписка связывается с push (механизм)».
