192 lines
9.8 KiB
Markdown
192 lines
9.8 KiB
Markdown
# Hermes — git-репозиторий конфига и агента
|
||
|
||
**Дата:** 2026-09-15
|
||
**Статус:** актуально
|
||
|
||
## Структура (важно!)
|
||
|
||
Git-репозиторий лежит **в `~/.hermes/`**, а НЕ в `~/.hermes/hermes-whale/`.
|
||
Это главный подвох: `git status` из `hermes-whale/` показывает пути вида `../config.yaml`,
|
||
`../skills/` — потому что корень на уровень выше.
|
||
|
||
```
|
||
~/.hermes/ ← git repo root (branch: main, origin/main)
|
||
├── .gitignore
|
||
├── .gitmodules
|
||
├── config.yaml ← глобальный конфиг
|
||
├── SOUL.md
|
||
├── channel_directory.json ← в .gitignore, но УЖЕ ЗАКОММИЧЕН (см. долги)
|
||
├── thread_ownership.json ← состояние whale-thread-guard плагина
|
||
├── webhook_subscriptions.json ← секреты! в .gitignore (не коммитить)
|
||
├── hermes-agent/ ← SUBMODULE: исходники Hermes Agent (Python)
|
||
├── hermes-whale/ ← профиль Whale (конфиг + память + промпты)
|
||
│ ├── config.yaml ← конфиг профиля Whale
|
||
│ ├── SOUL.md ← идентичность Кита
|
||
│ ├── review/ ← prompt_overrides: 7 .md блоков + memory/skill prompt
|
||
│ ├── memories/
|
||
│ │ ├── MEMORY.md, USER.md ← глобальные
|
||
│ │ └── threads/<key>/MEMORY.md ← thread-scoped память
|
||
│ ├── cron/jobs.json
|
||
│ └── lsp/ ← ⚠️ 39M бинарников закоммичено (долг)
|
||
├── memories/ ← глобальные (не профиля)
|
||
├── plugins/whale-thread-guard/ ← роутинг ботов в Zulip
|
||
├── scripts/refresh-claude-token.sh
|
||
└── skills/ ← курируемые скиллы
|
||
```
|
||
|
||
## Два репозитория
|
||
|
||
| Репо | Что | Ветка |
|
||
|------|-----|-------|
|
||
| `~/.hermes/` | Конфиг Whale, скиллы, память, плагины, пин сабмодуля | main |
|
||
| `~/.hermes/hermes-agent/` | Исходники Hermes Agent (Python) — сабмодуль | main |
|
||
|
||
Правки Python-кода Hermes (`agent/*.py`) коммитятся **в сабмодуле**,
|
||
затем в родительском репо обновляется пин: `git add hermes-agent`.
|
||
Если пин не обновить — в родительском `git status` видно
|
||
`hermes-agent (new commits, modified content)`, а сам сабмодуль чист.
|
||
|
||
**Как проверить, всё ли закоммичено:**
|
||
```bash
|
||
cd ~/.hermes && git status --porcelain | head
|
||
cd ~/.hermes/hermes-agent && git status --porcelain # должно быть пусто
|
||
```
|
||
|
||
## Правила .gitignore (обновлено 2026-09-15)
|
||
|
||
До 2026-09-15 игнорировался только `.env` — вариант `**`.env.bak`/`.env.new` НЕ покрывался,
|
||
хотя в них лежали живые токены. Один `git add .` затащил бы их в историю.
|
||
|
||
Добавлены секции:
|
||
|
||
```gitignore
|
||
# Secrets
|
||
.env / .env.bak / .env.new / .env.local / .env.*.bak
|
||
**/.env / **/.env.bak / **/.env.new
|
||
|
||
# Webhook subscriptions (содержат per-endpoint secret, 16 символов)
|
||
webhook_subscriptions.json
|
||
**/webhook_subscriptions.json
|
||
|
||
# Config/state бэкапы (могут содержать секреты)
|
||
config.yaml.bak* / config.yaml.*.bak / config.yaml.whale-bak*
|
||
config.yaml.work / config.yaml.transitional / config.yaml.corrupt*
|
||
**/config.yaml.bak* / **/config.yaml.*.bak / **/config.yaml.whale-bak*
|
||
*.tmp
|
||
|
||
# Node
|
||
node_modules/ / **/node_modules/
|
||
```
|
||
|
||
### Проверка игнора (обязательно после правки .gitignore)
|
||
|
||
```bash
|
||
cd ~/.hermes && git check-ignore -v .env.bak .env.new \
|
||
hermes-whale/.env.bak hermes-whale/.env.new \
|
||
webhook_subscriptions.json config.yaml.bak
|
||
```
|
||
|
||
Каждый файл должен вывести строку `.gitignore:<N>:<pattern>\t<file>`.
|
||
|
||
**Pitfall:** `.gitignore` НЕ влияет на уже отслеживаемые файлы.
|
||
`hermes-whale/lsp/node_modules/` оставался в репо несмотря на правило
|
||
`node_modules/` (закрыто коммитом `9b111fc` через `git rm -r --cached`).
|
||
Вывод — применять `git add` по именам файлов, а не `git add .`, иначе новое правило
|
||
может дать ложное чувство защиты.
|
||
|
||
**Второй pitfall — `git add -f`:** после добавления правила `node_modules/`
|
||
попытка `git add` файла внутри него (например `lsp/node_modules/.package-lock.json`)
|
||
падает с «paths are ignored by one of your .gitignore files». Уже отслеживаемые
|
||
файлы коммитятся нормально без `-f` — правило на них не действует.
|
||
|
||
## Что коммитить / что не коммитить
|
||
|
||
**Коммитим:**
|
||
- `config.yaml`, `hermes-whale/config.yaml` — конфиги
|
||
- `hermes-whale/review/*.md` — prompt_overrides (без них подмены промпта теряются!)
|
||
- `hermes-whale/memories/`, `memories/` — память
|
||
- `plugins/`, `skills/`, `scripts/`
|
||
- `hermes-agent` (пин сабмодуля)
|
||
|
||
**Не коммитим (в .gitignore):**
|
||
- `.env*` любые варианты
|
||
- `webhook_subscriptions.json` — секреты
|
||
- `config.yaml*.bak*` — 10+ бэкапов могут содержать секреты
|
||
- `node_modules/`, `.restart_last_processed.json`, `config.yaml.zulip-router`
|
||
- `lsp/`, `review/` в корне — дубликаты `hermes-whale/lsp/` и `hermes-whale/review/`
|
||
|
||
## Долги (не исправлено, требуют решения Alex)
|
||
|
||
1. **`channel_directory.json` в .gitignore, но отслеживается** — правило добавлено после коммита.
|
||
В коммите `7fd200c` из него удалено 869 строк (файл в основном генерируемый).
|
||
Также живёт как ` M` в статусе постоянно — это рантайм-запись текущей сессии,
|
||
коммитить бессмысленно. Решение: `git rm --cached channel_directory.json`.
|
||
2. **История git не похудела.** 43M node_modules убраны из трекинга, но остаются
|
||
в истории. Для реальной экономии — `filter-repo` + force push (ломает клоны).
|
||
|
||
### Закрыто 2026-09-15
|
||
|
||
- ~~`hermes-whale/lsp/node_modules/` в git~~ — **убрано из трекинга** коммитом
|
||
`9b111fc`: 1957 файлов / 43M. Файлы **остались на диске** (108 каталогов),
|
||
`git rm -r --cached` индекс не удаляет. Проверка:
|
||
`git ls-files | grep -c node_modules` → 0.
|
||
|
||
## Коммиты и push (2026-09-15)
|
||
|
||
| Коммит | Что |
|
||
|--------|-----|
|
||
| `207a1de16` (submodule) | load stable system-prompt blocks from config prompt_overrides |
|
||
| `7fd200c` | wire prompt_overrides + whale-thread-guard multi-bot routing |
|
||
| `7893c35` | sync skills — curator consolidation (516 удалений, 55 новых) |
|
||
| `bdf84da` | add vue/dockerfile/pyright/yaml language servers |
|
||
| `176ce9c` | thread-scoped memory store + claude token refresh script |
|
||
| `9b111fc` | untrack lsp/node_modules (1957 files, 43M) |
|
||
|
||
**Запушено:**
|
||
- `hermes-agent` → `github.com:mallexxx/hermes-agent` — 20 коммитов
|
||
- `~/.hermes` → `git.mallexxx.duckdns.org/git_admin/eagle-hermes` — 9 коммитов
|
||
|
||
Оба репо: `main...origin/main` синхронно, секретов в истории нет.
|
||
|
||
## Утечка секретов (закрыта 2026-09-15)
|
||
|
||
`.env.bak` и `.env.new` (в `~/.hermes/` и `~/.hermes/hermes-whale/`) содержали
|
||
**живые токены**: `TELEGRAM_BOT_TOKEN`, `OPENROUTER_API_KEY`, `DISCORD_BOT_TOKEN`,
|
||
`ZULIP_API_KEY`, `DEEPSEEK_API_KEY`. Игнорился только `.env` — варианты
|
||
`.bak`/`.new` НЕ покрывались. Один `git add .` затащил бы их в публичную историю.
|
||
|
||
Также `webhook_subscriptions.json` (16-символьные per-endpoint секреты) —
|
||
не был игнорирован. Проверено фактически: `jq -r '.whale.secret | length'` → 16.
|
||
|
||
Проверка, что секреты не попали в историю:
|
||
```bash
|
||
cd ~/.hermes && git log --all --diff-filter=A --name-only --pretty=format: | grep '\.env'
|
||
# пусто = чисто
|
||
```
|
||
|
||
`scripts/refresh-claude-token.sh` — **не секрет**: refresh token читается
|
||
из `~/.claude/.credentials.json` в рантайме, `CLIENT_ID` — публичный OAuth
|
||
идентификатор.
|
||
|
||
## Команды
|
||
|
||
```bash
|
||
# Статус обоих репо
|
||
cd ~/.hermes && git status -sb
|
||
cd ~/.hermes/hermes-agent && git status -sb
|
||
|
||
# Закоммитить Python-правки Hermes
|
||
cd ~/.hermes/hermes-agent && git add agent/*.py && git commit -m "..."
|
||
cd ~/.hermes && git add hermes-agent && git commit -m "chore: bump submodule"
|
||
|
||
# Проверить, что секреты не в истории
|
||
cd ~/.hermes && git log --all --diff-filter=A --name-only --pretty=format: | grep '\.env'
|
||
```
|
||
|
||
## Связанное
|
||
|
||
- [[hermes-whale-system-prompt]] — состав system prompt, prompt_overrides
|
||
- [[hermes-agent-improvements]] — вынос хардкода промптов в файлы (механизм + коммиты)
|
||
- [[hermes-memory-architecture]] — thread-scoped память
|
||
- [[hermes-fork-vs-upstream]] — расхождение с апстримом (24k коммитов)
|