# Athena Update

> athena-update — обновить живую систему безопасно

- Skill: `zarubinvibe/athena-update` (Agent Skill)
- Install (CLI): `npx skillmds@latest add zarubinvibe/athena-update`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zarubinvibe/athena-update/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: zarubinvibe (https://skillmd.com/u/zarubinvibe)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zarubinvibe/athena-update

---


# athena-update — обновить живую систему безопасно

> Антипод `setup-os` (ставит с нуля). Здесь система УЖЕ есть — задача подтянуть новую версию каркаса, **не затерев личное**. Дирижируешь ТЫ; `bootstrap.sh` остается тупым идемпотентным движком.

## Принцип
Четыре фазы, **без пропусков**: **Анализ → План → Согласование → Действие**. Каждое изменение живой системы — за подтверждением попапом. Бэкап ДО, smoke ПОСЛЕ, откат всегда под рукой. Caveman+humanizer. Структура ответа: что сделано · что нужно · следующий шаг.

**Правила НИКОГДА здесь:** не `chezmoi apply` вслепую (всегда `diff`+согласие — E7) · не auto-merge чужих локальных правок репо (только `--ff-only`) · не трогать секреты (`athena.config.sh`, `~/.secrets` — gitignored, мимо апдейта) · не обновлять без бэкапа `~/.claude`.

---

## Фаза 1 — Анализ (молча, до вопросов)

База сравнения = `~/.claude/.athena-version` (SHA, на котором стоит система) ИЛИ `git -C ~/athena rev-parse HEAD`, если стампа нет.

```bash
cd "$HOME/athena" || { echo "нет ~/athena — это setup-os, не update"; exit 1; }
git fetch origin main 2>&1
BASE="$(cat "$HOME/.claude/.athena-version" 2>/dev/null || git rev-parse HEAD)"
git log --oneline "$BASE..origin/main"          # что нового
git diff --stat "$BASE" origin/main             # какие файлы тронуты
git status -s                                    # локальные правки репо (форк/ручные)
# chezmoi sourceDir ДОЛЖЕН резолвить merged-source (athena-merged-source), не дефолт ~/.local/share/chezmoi.
# Иначе diff ложно-пуст → «нет дрейфа», а apply бьет в пустой source. Чинит bootstrap (config), но проверь:
if command -v chezmoi >/dev/null; then
  SP="$(chezmoi source-path 2>/dev/null)"
  case "$SP" in *athena-merged-source) chezmoi diff 2>/dev/null | head -100 ;;
    *) echo "⚠ chezmoi source-path='$SP' ≠ merged-source — конфиг не запечен, перезапусти bootstrap --only=1 ПЕРЕД apply" ;;
  esac
fi
```

Классифицируй изменения по областям (что меняется → что делать):

| Область | Признак в diff | Действие апдейта | Риск |
|---|---|---|---|
| **Движок/слои** | `bootstrap.sh`, `Brewfile`, `*.manifest` | пере-прогон затронутых слоев (идемпотент) | новые `brew install`, новые клоны |
| **Сознание/дотфайлы** | `chezmoi/**` | `chezmoi diff` → apply с согласия | **перезатереть живые правки settings.json** |
| **Skills/правила** | `skills/**`, `rules/**` | копия в `~/.claude/` если оттуда читается | низкий |
| **Smoke/CI** | `smoke/**`, `.github/**` | просто прогнать после | нет |
| **Фиксы безопасности** | commit `fix:`/`security:` | приоритет — применить первым | — |

Засеки два флага риска:
- **Локальные правки репо** (`git status` непусто / ветка разошлась) → `--ff-only` упадет. НЕ форсить — вынести в План как блокер, дать выбор (stash/ветка/отмена).
- **Дрейф живого Сознания** (`chezmoi diff` непусто) → у юзера есть ручные правки `~/.claude`, которые apply сотрет. Показать их в Плане пофайлово.

---

## Фаза 2 — План (показать, не делать)

Собери таблицу изменений человеку: область · что нового (1 строка из commit) · действие · риск. Явно подсветь:
- сколько коммитов позади, есть ли среди них `fix:`/`security:`;
- что перезапишется в живом `~/.claude` (из `chezmoi diff`) — пофайлово;
- блокеры (разошедшийся репо, untracked-правки).

Если позади 0 коммитов И `chezmoi diff` пуст → «все актуально», стоп.

---

## Фаза 3 — Согласование (попапы, никаких тихих дыр)

1. **Бэкап (всегда, без вопроса делаешь молча в Фазе 4).** Сообщи что будет: `~/.claude` → `~/.claude.bak-<дата>`.
2. AskUserQuestion **multiSelect**: «Что обновляем? (что не выберешь — пропустим)» → области из Плана где есть изменения.
3. Если есть дрейф Сознания — отдельный попап: «Живые правки `~/.claude/X` будут перезаписаны новой версией. Как быть?» → [Перезаписать (apply)] [Сохранить мои (skip файла)] [Показать diff целиком].
4. Если репо разошелся — попап: [Stash мои правки → обновить → вернуть] [Отдельная ветка] [Отмена].

**Gate полноты:** каждая область = обновлена ИЛИ явный skip-с-причиной. Без молчаливых пропусков.

---

## Фаза 4 — Действие (безопасно, идемпотентно)

```bash
cd "$HOME/athena"
# 1. Бэкап живого Сознания (откат = вернуть папку)
cp -a "$HOME/.claude" "$HOME/.claude.bak-$(date +%Y%m%d-%H%M%S)"
# 2. Подтянуть репо — ТОЛЬКО ff (без auto-merge чужих правок)
git pull --ff-only origin main    # упало → вернись к Фазе 3 блокеру (stash/ветка)
# 3. Прогон затронутых слоев: сперва dry-run (покажи), потом реально
./bootstrap.sh --only=<слой> --dry-run     # показать
./bootstrap.sh --only=<слой>               # применить (по согласию)
# 4. Сознание: diff → apply (НЕ вслепую)
chezmoi diff                                # показать
chezmoi apply                               # по согласию; per-file: chezmoi apply ~/.claude/<file>
# 5. Smoke-гейт
smoke/smoke.sh
# 6. Стамп новой версии
git rev-parse HEAD > "$HOME/.claude/.athena-version"
```

**Порядок:** фиксы безопасности → движок (слои) → Сознание (chezmoi) → skills/rules → smoke. После каждого шага — короткий статус.

**Откат (если smoke упал или что-то не так):**
```bash
rm -rf "$HOME/.claude" && mv "$HOME/.claude.bak-<дата>" "$HOME/.claude"   # вернуть Сознание
git -C "$HOME/athena" reset --hard "$BASE"                                # вернуть репо
```
Сообщи человеку обе команды ДО действия (чтобы знал выход).

---

## Финал
- Покажи: было SHA → стало SHA, какие области обновлены, какие пропущены-с-причиной.
- Smoke OK? Бэкап где лежит (можно удалить через N дней).
- Применил `fix:`/`security:` — назови их явно.
- Предложи удалить старые `~/.claude.bak-*` если их >2.

