Устранение неполадок (симптом → диагноз → исправление)
Каждая запись следует одной и той же структуре: симптом, который вы видите, как подтвердить, что это именно он, и исправление. Приведённые строки лога — это фактические строки движка, так что вы можете искать их через grep. Там, где существует более глубокий runbook, запись ссылается на соответствующую страницу, а не выводит его заново.
Первая загрузка и установка
Заголовок раздела «Первая загрузка и установка»Я пропустил токен установки
Заголовок раздела «Я пропустил токен установки»Перезапуск не выводит его повторно (хранится только хеш токена, в
setup.token в каталоге данных). Пока пользователей ещё нет, восстановление
безопасно: остановите движок, удалите setup.token, запустите его — генерируется
и выводится новый токен. Это работает только на установке без пользователей,
поэтому это не путь для захвата. Токен выводится только в stdout (journal под
systemd, лог контейнера в Docker/Kubernetes) — никогда в файлы логов.
=== FIRST-BOOT SETUP === так и не появился
Заголовок раздела «=== FIRST-BOOT SETUP === так и не появился»Пользователи уже существуют в этом каталоге данных — вы не на первой загрузке.
Либо войдите с существующим администратором, либо для действительно свежего
старта используйте свежий --data-dir.
Движок предупреждает о ключах при первой загрузке
Заголовок раздела «Движок предупреждает о ключах при первой загрузке»generated a new audit signing key; back it up path=/var/lib/olivares/audit-signing.keygenerated a local TLS certificate; clients must trust it, or pin it with --pin-sha256=<pin_sha256> (that value, verbatim) cert=/var/lib/olivares/tls.crt cert_fingerprint_sha256=d38567e8…378c4e7f pin_sha256=JsdrhrY77Me8miAmobJsqamE3NDWIOSBrDTwbHkyCD0Оба намеренны, и первый — это тот, который аукнется позже: принудительного
депонирования (escrow) нет — скопируйте audit-signing.key за пределы сервера
сейчас и закрепите публичный ключ (GET /v1/audit/pubkey) за пределами сервера,
иначе будущая компрометация хоста оставит вас неспособными доказать целостность
собственного ledger
(резервное копирование и восстановление).
Строка TLS печатает два хэша, и они не взаимозаменяемы:
cert_fingerprint_sha256 — это хэш сертификата, тот, что показывает браузер;
pin_sha256 — хэш SPKI конечного сертификата, и только его сравнивает
--pin-sha256. Скопируйте это значение дословно:
olivares status --server https://127.0.0.1:8443 \ --pin-sha256 JsdrhrY77Me8miAmobJsqamE3NDWIOSBrDTwbHkyCD0Если вместо этого закрепить отпечаток сертификата, ошибки неверного значения
флага не будет — это корректный 32-байтовый хэш, поэтому соединение будет
предпринято и отклонено с TLS SPKI pin mismatch, и эта ошибка сообщит
значение, которое следовало использовать. Для curl --pinnedpubkey sha256//…
добавьте завершающее дополнение =: движок намеренно печатает base64 без
дополнения, чтобы значение выводилось без кавычек и переживало копирование,
но curl требует дополненную форму.
Диагностика установки хоста
Заголовок раздела «Диагностика установки хоста»Сгенерированная справка CLI описывает olivares doctor так: diagnose this host
installation without printing secrets
(CLI). Флаги включают --data-dir, --mode (auto | user | system), --init (auto | systemd | openrc | launchd), --config, --unit, --binary, --server, --timeout, --ca-cert, --audit-tenant, --check-updates.
Не считайте эту таблицу дополнительным текстом справки; это эта сгенерированная
команда.
agentops-layout check
Заголовок раздела «agentops-layout check»olivares doctor сообщает проверку с именем agentops-layout
(CHANGELOG.md [26.9.0]; cmd/olivares/cmd_doctor.go doctorAgentOpsCheck).
Это не подкоманда. Она измеряет родную раскладку AgentOps, которую записывает
манифест владения: управляемый drop-in должен существовать со своим mode и
называть записанные claude HOME, каталог токенов и workspace; runtime env
должен существовать с mode конфигурации (значения никогда не читаются);
workspace должен быть каталогом (docs/RELEASE-INSTALLER.md).
Статусы, которые возвращает проверка:
| Status | When |
|---|---|
not_applicable |
no readable manifest; malformed manifest; or the manifest records no AgentOps files (dropin, runtime-env, workspace_dir all empty) |
fail |
drop-in does not reference a recorded token ($dataDir/claude-home, $dataDir/run, or workspace_dir); workspace path is absent or is not a directory |
unknown |
drop-in or workspace is not readable |
pass |
drop-in, runtime-env (values not read) and workspace directory agree with the record |
Required равно false, пока манифест не запишет хотя бы один файл AgentOps; затем
проверка required. Строки исправления, которые печатает движок, включают
rerun install-agentops.sh; the managed drop-in and the recorded layout disagree
и recreate the recorded workspace or rerun install-agentops.sh with OLIVARES_WORKSPACE_DIR.
И текст, и -o json содержат имена ключей и пути, но никогда значения
конфигурации (docs/RELEASE-INSTALLER.md).
Источники и access map
Заголовок раздела «Источники и access map»Карта пуста
Заголовок раздела «Карта пуста»Сначала проверьте, подключено ли вообще что-нибудь. Движок прямо сообщает об этом при загрузке:
ingest: no observation sources configured (OLIVARES_SOURCES_CONFIG.sources is empty); no connector will ingest — the estate runs on no live trafficДвижок не запускается с конфигурацией источников
Заголовок раздела «Движок не запускается с конфигурацией источников»Если OLIVARES_SOURCES_CONFIG указывает на отсутствующий, нечитаемый файл или файл с невалидным JSON, olivares serve завершается с кодом 1. Ищите ошибку запуска load sources operator config: OLIVARES_SOURCES_CONFIG, содержащую refusing to start instead of silently omitting operator configuration. Проверьте путь с точки зрения службы или контейнера, убедитесь, что их пользователь может прочитать файл, проверьте JSON и перезапустите движок. Эта ошибка файла препятствует запуску; движок не продолжает работать с пустой картой из-за неё.
После успешного запуска ищите ingest: wired source … kind=… для каждого источника. Источник, который не удалось создать, логирует ingest: failed to register in-process source; not wired с указанием причины.
pgAudit подключён, но рёбра не приходят
Заголовок раздела «pgAudit подключён, но рёбра не приходят»Три причины покрывают почти все случаи, все по замыслу (руководство по pgAudit):
- Сервер не логирует в UTC. Записи с аббревиатурой зоны, отличной от UTC,
пропускаются, а не получают неверную временную метку — задайте
log_timezone = 'UTC'. - csvlog — это пакет, а не хвост (tail).
followприменяется только кjsonlog; источник csvlog принимает данные на каждом проходе, а не непрерывно. - Аудируемые классы отключены — проверьте, что
pgaudit.logвключаетread, write.
Всё отображается как drift
Заголовок раздела «Всё отображается как drift»Ожидаемо на свежей установке: при отсутствии объявленных grant’ов каждый наблюдаемый доступ честно считается «неожиданным». Это начальное состояние, а не баг — разберите его, объявив grant’ы, которые вы намереваетесь предоставить.
Доступность
Заголовок раздела «Доступность»/readyz возвращает 503
Заголовок раздела «/readyz возвращает 503»Прочитайте тело. 503 — это не ready и не успех. То, что /livez остаётся 200,
означает только, что процесс жив; то, что /pod-readyz остаётся 200, означает
только здоровье пода (хранилище достижимо) без проверки лидерства и без зонда
возможности первой загрузки. Ни то ни другое не разблокирует стандартный Helm
chart или плоский манифест, которые подключают /readyz как контейнерный
readinessProbe.
{"status":"unavailable","store":"down"}— хранилище недоступно. На SQLite: переполнен диск, проблемы с PVC, права доступа к файлу. На Postgres: доступность и учётные данные. Liveness намеренно продолжает проходить (процесс жив), так что ничто не зацикливается на перезапуске при сбое хранилища; перезапустите pod/сервис вручную после исправления хранилища, если оно остаётся заклиненным.{"status":"standby","store":"up","leader":false}— резервный узел HA, отвечающий честно. Это не ошибка: Service маршрутизирует на лидера; резервные узлы дренируются по замыслу. Если все реплики сообщают standby, выбор лидера застрял — проверьте связность advisory-lock Postgres.{"status":"setup_blocked","store":"up","leader":true,"setup_required":true,"code":"cross_tenant_admin_pool_not_configured"}— первая загрузка PostgreSQL не может авторитетно перечислить организации. Создайте административную рольNOSUPERUSER BYPASSRLSи--admin-dsn(Postgres в Kubernetes). В теле — фиксированное указание. Пока это предварительное условие не исправлено, стандартный зонд readiness держит под Not Ready. Не переназначайте зонд, чтобы это скрыть.{"status":"setup_unavailable","store":"up","leader":true,"code":"setup_state_unavailable"}— этот узел не смог наблюдать, настроена ли установка.setup_requiredопущен, потому что его значение неизвестно. Это не известная пустая установка.{"status":"setup_unavailable","store":"up","leader":true,"setup_required":true,"code":"setup_probe_unavailable"}— установка заведомо не настроена, но зонд возможности первой загрузки отказал по причине, отличной от отказа административного пула. Таймаут — не доказательство пустого парка.
200 {"status":"ok",…,"setup_required":true} — другое наблюдение: первичную
настройку можно пытаться выполнить. POST /v1/setup по-прежнему повторяет
проверки власти. Этот 200 не расходует бюджет доступности; эти 503 — да.
Pod умер, и ничто его не подхватило
Заголовок раздела «Pod умер, и ничто его не подхватило»В топологии с одной репликой по умолчанию автоматического failover нет —
восстановление — это перепланирование StatefulSet плюс переподключение тома RWO
(следите за ошибками Multi-Attach; том привязывает восстановление к своей AZ).
Автоматический failover — это свойство HA-топологии
(Postgres + реплики + общий ключ подписи). Никогда не запускайте продакшен с
отключённым хранением: emptyDir теряет ключ подписи при каждом перепланировании.
Производительность
Заголовок раздела «Производительность»Латентность приёма p99 растёт (обратное давление)
Заголовок раздела «Латентность приёма p99 растёт (обратное давление)»Шина блокирует, а не отбрасывает — растущий p99
olivares_ingest_duration_seconds — это задуманный сигнал того, что подписчик
насыщен, а не потеря данных. Назовите виновника напрямую:
olivares_eventbus_queue_depth / olivares_eventbus_queue_capacity > 0.9Метки по подписчикам указывают на медленный модуль;
olivares_eventbus_publish_blocked_total подсчитывает события обратного давления.
Обычная коренная причина — пропускная способность записи в хранилище (потолок
единственного писателя SQLite) — это исправление через ёмкость (перейти на Postgres
или снизить амплификацию записи), а не ручка для тюнинга. Медленные выходные
коннекторы (webhook, SIEM) никогда не должны быть синхронными подписчиками.
С включённой распределённой шиной (OLIVARES_BUS_CONFIG) помните, что межузловой
мост работает не более одного раза (at-most-once): насыщенный мост заполняет
olivares_eventbus_bridge_pending_messages и затем отбрасывает удалённые
события, подсчитанные в olivares_eventbus_bridge_dropped_total — оповещайте о
любом росте и поднимайте по пейджеру, когда
olivares_eventbus_bridge_connected == 0.
Входы в систему не проходят с «locked out»
Заголовок раздела «Входы в систему не проходят с «locked out»»Рост olivares_auth_login_attempts_total{outcome="locked_out"} означает, что
ограничитель отклонил попытку: аккаунт заблокирован собственными повторными неудачами
либо его уже перебирал клиентский адрес с чередой неудач за ним. Аккаунт с чистой историей
никогда не блокируется из-за чужих неудач с того же адреса — вместо этого он ждёт секунду.
И то и другое снимается само; расследуйте источник неудач, а не повышайте лимиты.
Доказательства
Заголовок раздела «Доказательства»Ledger не проходит проверку
Заголовок раздела «Ledger не проходит проверку»Сначала разберитесь, что вы запустили: audit verify по умолчанию завершается с
кодом 0 даже при неудачной цепочке (результат находится в JSON-отчёте) —
автоматизация должна использовать --strict или разбирать отчёт:
olivares audit verify --tenant $TENANT --data-dir /var/lib/olivares --strict \ --pubkey <BASE64-PINNED-OFF-BOX>Закрепите внесерверный публичный ключ: без закреплений верификатор доверяет
ключам, прочитанным с (возможно скомпрометированного) хоста — приемлемо как
рекомендательная проверка, но не как доказательство нарушения целостности. Затем
классифицируйте по полю reason:
| Причина | Класс | Реакция |
|---|---|---|
hash-mismatch, prev-mismatch, head-mismatch, tail-truncated |
подделка или усечение | рассматривайте как SEV1: сохраните сервер, сверьте с внесерверной контрольной точкой |
checkpoint-sig-invalid, checkpoint-link-mismatch, event-sig-invalid |
подделка или неверный ключ | SEV1, если только вы не можете доказать путаницу с хранением ключей |
seq-gap |
удаление или несогласованность восстановления | сверьте с внесерверной контрольной точкой, прежде чем кричать о подделке |
event-sig-missing |
возможно, устаревшие записи до включения подписи | ограничьте это --from на границе включения; отсутствие до границы ожидаемо |
Восстановленная резервная копия, которая проходит наивный обход, но расходится с вашей закреплённой внесерверной контрольной точкой — это случай аномалии восстановления; именно ради этого сравнения и существует закрепление.
olivares_audit_checkpoint_age_seconds продолжает расти
Заголовок раздела «olivares_audit_checkpoint_age_seconds продолжает расти»Контрольные точки перестали записываться (каденция по умолчанию 1ч;
OlivaresAuditCheckpointStale срабатывает на 2ч). Проверьте лог движка на
наличие ошибок контрольных точек и записываемость хранилища — пока оно растёт,
ваш якорь доказательства нарушения целостности стареет.
Уведомления и приёмники (sinks)
Заголовок раздела «Уведомления и приёмники (sinks)»Назначение никогда ничего не получает
Заголовок раздела «Назначение никогда ничего не получает»Назначение с неизвестным kind пропускается и логируется
(notify: destination has unknown connector kind; skipped — проверьте написание
kind). Для приёмников событий POST …/subscriptions/{id}/test отправляет
доставку, за которой вы можете наблюдать, а конечные точки должны быть HTTPS
(отправка в SIEM).
Если симптома здесь нет, и собственное сообщение движка его не объясняет — это баг документации; пожалуйста, сообщите о нём, приложив строку лога.