Skip to content

Repository files navigation

srekit

Release Go Reference Go Report Card License: MIT tests golangci-lint security goreleaser Homebrew Go LoC

srekit — generates SRE text artifacts: postmortems, runbooks, SLOs, RFCs, changelogs

📚 Documentation: jtprogru.github.io/srekit (EN + RU, full command reference, guides, recipes, architecture).

Генератор текстовых артефактов SRE: investigation log'и, постмортемы, runbook'и, RFC, on-call report'ы, SLO, error budget policies, changelog'и, карточки задач.

Шаблон здесь — не markdown-файл, а v1 YAML-артефакт (postmortem.yaml, slo.yaml, …), который декларирует frontmatter, H1, meta-буллеты и список типизированных секций; markdown srekit собирает из этой декларации. Поставочный набор вкомпилирован в бинарник, а директория с твоими артефактами переопределяет его пофайлово — то, чего у тебя нет, прозрачно берётся из встроенного.

Все артефакты двуязычные: заголовки и метки в формате Русский (English), тело — на русском. Технические идентификаторы (SLO/SLI/RFC/PromQL/UTC/SEV), ключи YAML frontmatter и PromQL-выражения остаются английскими. changelog по умолчанию полностью английский, чтобы не ломать тулинг вокруг Keep a Changelog; русский вариант — opt-in через --lang ru.

Извлечён из gch в рамках распиливания монолита.

Install

Через Homebrew (macOS / Linux):

brew tap jtprogru/tap
brew install srekit

Через go install:

go install github.com/jtprogru/srekit@latest

Готовые бинарники под Linux / macOS / FreeBSD (amd64, arm64) — на странице Releases.

Uninstall

Homebrew:

brew uninstall srekit
brew untap jtprogru/tap   # опционально

Установка через go install или вручную скачанный бинарник:

rm "$(command -v srekit)"   # или удалите бинарь из своего PATH / $GOBIN

Конфиг и пользовательские шаблоны (если создавались) удаляются отдельно:

rm -f  "${XDG_CONFIG_HOME:-$HOME/.config}/srekit/config.yaml"
rm -rf "${XDG_CONFIG_HOME:-$HOME/.config}/srekit/templates"
# legacy-расположение (до перехода на XDG):
rm -f  ~/.srekit.yaml
rm -rf ~/.srekit

Usage

srekit --help

Все команды поддерживают единый набор флагов: --out FILE (записать в файл), --stdout (печать в stdout), --force (перезаписать), --dry-run (показать без записи), --json (отдать данные шаблона как JSON вместо рендеринга).

Глобальные флаги (на любой команде): --config FILE, --templates-dir DIR, -q/--quiet (подавить INFO-сообщения; рендер и ошибки печатаются как обычно), -V/--version.

С --json команда не рендерит шаблон, а пишет в stdout (или --out FILE) структуру, которую увидел бы шаблон. Удобно для пайплайнов:

srekit task --title "Tail latency" --json | jq -r '.meta.id'
srekit postmortem --title X --severity SEV-1 --json | jq -r '.meta.severity'
srekit postmortem --title X --json | jq -r '.sections[] | select(.id == "summary").body'

Форма payload'а одна для всех генераторов: {meta, sections}, где sections — упорядоченный список {id, title, type, required, body}. Обращайся по id, не по индексу.

Ключи — camelCase во всех командах (включая templates list --json); это публичный контракт. При --json markdown-дефолт пути игнорируется, чтобы JSON случайно не оказался в .md-файле.

srekit task — investigation log для SRE-расследования

srekit task --title "Tail latency on api-gw" --path ./tasks
# → ./tasks/investigation-tail-latency-on-api-gw.md

Шаблон с секциями Context / Hypothesis / Evidence / Findings / Action items / References. Алиас srekit sretask оставлен для совместимости (исторически команда заменяла gch sretask).

srekit tasker — карточка задачи

srekit tasker --title "Каналы и select"                       # → tasker-select.md
srekit tasker -T "Что делает GOMAXPROCS" --topic go \
  --level junior --format theory --duration 10

Карточка для коллекции инженерных задач: frontmatter (topic, level, format, duration), H1 Tasker - <название> и две пустые секции — сама задача и то, что хочется услышать в ответ. Пустые намеренно: содержимое пишет тот, кто задачу добавляет.

level уезжает в документ списком, duration — числом: frontmatter карточки читает коллекция, в которой она лежит, и level: [middle, senior] фильтруется, а level: "middle, senior" — нет. В своих артефактах то же самое делается явным YAML-тегом на значении (!!int, !!seq) — см. Кастомные шаблоны.

Имя task рядом занято другим документом: task — это investigation log, ход разбирательства; tasker — задача, которую будет решать кто-то другой.

srekit postmortem — шаблон постмортема (Google SRE-style)

srekit postmortem --title "API outage" --severity SEV-1 \
  --start 2026-05-06T08:00Z --end 2026-05-06T09:30Z \
  --owner "@oncall" --out postmortem-2026-05-06.md

postmortem — канонический референс v1-схемы и единственная команда с round-trip workflow «вытащить → отредактировать → отрендерить»:

srekit postmortem -T "Cache stampede" --json > pm.json   # выгрузить sections в JSON
# ...редактируешь pm.json (--json отдаёт список, --from читает map по id — переложи форму)...
srekit postmortem -T X --from pm.json                    # обратно в markdown
srekit postmortem --schema > postmortem.schema.json      # JSON Schema для тулинга/агентов
srekit postmortem --validate pm.json                     # required sections непустые, нет unknown ID

--from - читает из stdin. --schema и --validate взаимоисключающие.

srekit rfc — RFC / ADR

srekit rfc --title "Migrate to gRPC" --status proposed --stdout

Статусы: proposed | accepted | rejected | superseded | deprecated.

srekit runbook — runbook для on-call

srekit runbook --title "p99 latency spike" --service api-gw --alert APIHighLatency

srekit changelog — CHANGELOG.md в формате Keep a Changelog

srekit changelog --out CHANGELOG.md                    # репо детектится из git remote
srekit changelog --repo jtprogru/srekit --version 0.2.0
srekit changelog --lang ru                             # русские change type'ы (Добавлено, Изменено, …)

changelog — единственная группа, которая не только генерирует, но и сопровождает уже существующий документ:

srekit changelog release --version 1.2.0 --dry-run   # посмотреть, что получится
srekit changelog release --version 1.2.0             # [Unreleased] → ## [1.2.0] - YYYY-MM-DD, блок ссылок обновлён
srekit changelog validate                            # линт против Keep a Changelog, exit != 0 при провале

release правит текст и на этом останавливается: не коммитит, не тегает, не пушит. Меняются ровно три региона — [Unreleased], вставленная версия и блок ссылок; всё остальное (преамбула, стиль пустых строк и маркеров списка, ранее выпущенные версии) выходит байт в байт таким же, каким вошло. Конвенции ссылок берутся из собственной строки [Unreleased] документа, а не из git, так что self-hosted GitLab и теги без префикса v сохраняют свою форму. Язык change type'ов определяется по документу, а не по --lang: команда, перешедшая на русский, не испортит свой прежний английский CHANGELOG.md.

srekit oncall-report — недельный отчёт дежурного

srekit oncall-report --team platform                    # период по умолчанию — текущая неделя (Mon–Sun)
srekit oncall-report --team platform --start 2026-05-04 --end 2026-05-10
srekit oncall-report --team platform --author "Alice" --email alice@example.com

Если --author/--email не заданы, как и в rfc, берётся SREKIT_* env → config → git config.

srekit slo — SLO/SLI документ

srekit slo --service api-gw --target 99.95% --window 30d --latency 200ms

srekit ebp — Error Budget Policy

srekit ebp --service api-gw --out ebp-api-gw.md

Политика, что команда делает при сгорании бюджета ошибок: triggered actions по уровням (Yellow / Orange / Red), исключения, эскалация.

srekit templates init — твои собственные шаблоны под git

srekit templates init                # → $XDG_CONFIG_HOME/srekit/templates
srekit templates init ./team-templates --no-git

Раскладывает все встроенные артефакты в директорию, пишет TEMPLATES.md со справочником плейсхолдеров и FuncMap, и делает git init. Дальше:

cd ~/.config/srekit/templates
git remote add origin git@github.com:your-team/sre-templates.git
git add . && git commit -m "initial templates" && git push -u origin main

Подключение директории к srekit:

echo 'templates_dir: ~/.config/srekit/templates' >> ~/.config/srekit/config.yaml
# или: export SREKIT_TEMPLATES_DIR=~/.config/srekit/templates
# или: srekit --templates-dir ~/.config/srekit/templates …  (на одну команду)

Если файла нет в твоей директории, srekit тихо берёт встроенный — можно оверрайдить только то, что нужно.

Готовый репозиторий ровно в этой раскладке — jtprogru/sre-templates: клонируй как templates_dir, чтобы пропустить init, или форкни под свою организацию.

Флага --template FILE (one-shot подмена шаблона) больше нет ни у одной команды — он ушёл в v0.30.0 вместе с srekit license, своим последним потребителем. Кастомизация делается через <name>.yaml в templates_dir (см. ниже про templates init / upgrade).

srekit templates pull — синхронизация с remote

srekit templates pull              # git pull --ff-only
srekit templates pull --rebase     # если есть локальные коммиты

Запускает git pull в configured templates_dir. По умолчанию --ff-only, чтобы не получить сюрприз-merge'и. Команда вызывается явно — авто-pull при каждом запуске srekit намеренно не делается (это ломает UX и работу в офлайне).

srekit templates validate — проверить, что твои шаблоны рендерятся

srekit templates validate                    # configured templates_dir
srekit templates validate ./team-templates   # явная директория

Per-формат проверки:

  • <name>.yaml (v1 артефакт) — sections.ParseArtifact: поддерживаемая версия, непустой sections-список, уникальные ID, известный type (text / list / table), обязательные поля.
  • <name>.sections.yaml (legacy v0.13.x sidecar) — sections.ParseManifest те же структурные проверки на старой раскладке.
  • <name>.tmpl — Go-template parse-only с общим FuncMap. Ловит синтаксис (unclosed {{, неизвестные функции); опечатки в полях не ловятся (с v0.20.0 в embed нет ни одного .tmpl, sample-data для exec нет).

Не-zero exit если что-то упало.

srekit templates diff — что изменилось относительно embedded-версии

srekit templates diff                  # полный unified diff каждого изменённого файла
srekit templates diff --name-only      # только имена
srekit templates diff --no-color

Сравнивает каждый артефакт в твоей templates dir (.yaml / .tmpl / .sections.yaml) с версией, зашитой в текущий binary. Полезно после srekit templates pull или обновления бинарника — увидеть, что у тебя осталось своё, а что отстало от апстрима. Файлы без embedded-counterpart (твои bespoke-шаблоны) маркируются как user-only.

srekit templates list — что у тебя есть и в каком состоянии

srekit templates list                     # таблица (учитывает configured templates_dir)
srekit templates list ./team-templates    # явная директория
srekit templates list --json | jq         # для пайплайнов
srekit templates list --filter customized # только то, что ты переопределил

Классификация для каждого артефакта (.yaml / .tmpl / .sections.yaml):

  • identical — байт-в-байт совпадает с embedded;
  • customized — есть у тебя и отличается;
  • user-only — твой bespoke без embedded-counterpart;
  • embedded-only — зашит в бинарник, у тебя нет override.

JSON-ключи — camelCase (name, status, userPath) — то же соглашение, что и у --json генераторов.

srekit templates migrate — конвертация legacy .tmpl → v1 .yaml

srekit templates migrate              # dry-run: показать, что получилось бы
srekit templates migrate --apply      # записать <name>.yaml рядом со старыми файлами

Однократная миграция для тех, кто остался на pre-v0.14.0 раскладке (<name>.tmpl + опциональный <name>.sections.yaml sidecar). Создаёт <name>.yaml в v1-формате; оригиналы остаются на месте, чтобы их можно было сравнить и удалить руками. По умолчанию --dry-run. Подробный upgrade-recipe — в docs/migration/v1.md.

srekit templates upgrade — подтянуть новые embedded-шаблоны

srekit templates upgrade             # 3-way merge кастомизаций, без --force
srekit templates upgrade --dry-run   # посмотреть что изменится
srekit templates upgrade --force     # перезаписать и кастомизации (без merge)

3-way merge: srekit хранит снапшот embedded на момент последнего sync'а в <templates-dir>/.srekit-embedded/ и использует его как merge-base. git merge-file --diff3 мерджит твои изменения с upstream'ом:

  • нет файла → копируется;
  • идентичен embedded → пропуск;
  • upstream без изменений, твои есть → молчаливо не трогаем;
  • upstream изменился, твоих нет → fast-forward (без --force);
  • расхождение с обеих сторон → 3-way merge. Чистый merge — пишется silently; конфликт — маркеры <<<<<<< / >>>>>>> в файл, exit non-zero, разрешаешь руками.

Без снапшота (старый user dir, до этой версии) — fallback на additive поведение (skip + seed снапшота для следующего apgrade). Сидкар .srekit-embedded/ автоматически попадает в .gitignore твоей dir. TEMPLATES.md обновляется всегда (это reference, не точка кастомизации).

srekit doctor — диагностика окружения

srekit doctor                                       # полный отчёт
srekit doctor --quiet                               # только то, что требует внимания
srekit doctor --json | jq -e '.status != "error"'   # гейт в CI

Показывает состояние, которое srekit резолвит до того, как что-то отрендерить: какой конфиг реально читается (и не затенён ли второй), куда резолвится templates dir и парсятся ли ещё её артефакты, резолвится ли identity автора вообще, есть ли git в PATH. Только читает: ничего не создаёт, не чинит и не ходит в сеть.

Каждая проверка отдаёт ok, warn или error. Exit code — 1, если хотя бы одна error, иначе 0: warn никогда не роняет запуск, поэтому doctor безопасно ставить в CI. --quiet не меняет exit code — в здоровом окружении он не печатает ничего, то есть тишина означает «всё в порядке». ID проверок (config.file, config.identity, templates.parse, dependencies.git, …) — публичный контракт: на них гейтятся чужие пайплайны.

srekit completion — shell autocomplete

srekit completion zsh > "${fpath[1]}/_srekit"
srekit completion bash > /etc/bash_completion.d/srekit

Config

Путь по умолчанию — $XDG_CONFIG_HOME/srekit/config.yaml (т.е. ~/.config/srekit/config.yaml). Legacy ~/.srekit.yaml продолжает читаться, если уже существует — миграция не нужна, но новые конфиги пишутся в XDG.

author: Mikhail Savin
email: jtprogru@example.com
# templates_dir: ~/.config/srekit/templates
# changelog_lang: ru

Или через env: SREKIT_AUTHOR, SREKIT_EMAIL, SREKIT_TEMPLATES_DIR. Альтернативный путь к файлу — srekit --config ./my.yaml ….

Быстро создать файл интерактивно:

srekit config init                    # TTY → запросит author / email / templates_dir с дефолтами из git config
srekit config init --yes              # non-interactive: значения из --author / --email / git config
srekit config init --force            # перезаписать существующий файл
srekit --config ./my.yaml config init # альтернативный путь

Development

Локальная разработка живёт в Makefile. Из зависимостей нужны только Go 1.26.4 и GNU Make — системный make на macOS (3.81) и в любом Linux-дистрибутиве подходит. golangci-lint, govulncheck и MkDocs Makefile ставит сам при первом запуске, версии запинены в нём же.

make            # список целей
make ci         # lint + race-тесты, one-shot pre-push check
make build      # ./dist/srekit
make run ARGS="postmortem --title 'API down' --stdout"
Цель Что делает
make ci golangci-lint run + go test -race — то же, что гоняет CI
make test / make test-race быстрые тесты / с race-детектором, обе с покрытием
make lint / make lint-fix линт на запиненной версии golangci-lint
make govulncheck скан известных уязвимостей
make docs-serve / make docs-build MkDocs на http://127.0.0.1:8000 / сборка в ./site
make release-dry goreleaser-снапшот в ./dist без публикации

GitHub Actions вызывают ровно эти цели, а не отдельные команды, поэтому зелёный make ci локально и зелёный пайплайн означают одно и то же. Полный список — make help и contributing.

В репозитории лежит pre-commit hook (.githooks/pre-commit), который обновляет Go LoC бейдж в README.md через tokei. Хук не подключается автоматически — это делается явно:

git config core.hooksPath .githooks

Зависимость tokei ставится отдельно:

brew install tokei            # macOS / Linux
cargo install tokei           # через cargo

Если tokei не найден в PATH, хук молча скипается — коммит не блокируется.

Стабильность и версионирование

srekit следует SemVer. Текущая ветка — 0.x, поэтому breaking changes допустимы между minor-версиями (и явно помечены в CHANGELOG как Breaking — …). Свежий пример: в v0.30.0 удалены команды capacity, retro и license — см. гайд по удалённым командам. Deprecation-цикл ниже — это обещание, которое вступает в силу с v1.0; на 0.x оно ещё не действует.

С v1.0 релиз станет stability stamp:

  • Стабильный публичный контракт. CLI-флаги, имена и порядок section ID в --json, схема <name>.yaml (version / frontmatter / title / meta_bullets / header_body / sections / footer_body), словарь section type (text / list / table), ID проверок doctor, ключи конфиг-файла и SREKIT_* env. Любое из этого ломается только в major-релизе с migration-инструкцией.
  • Соблюдение обратной совместимости через 1.x. Поддерживается чтение legacy .tmpl и .sections.yaml файлов в user-templates_dir (с stderr WARN); их удаление — кандидат на 2.0.
  • Deprecation-цикл. Когда мы что-то планируем убрать, оно сначала становится no-op или начинает писать WARN минимум один minor-релиз, потом удаляется в следующем major. Пример из недавнего: --template FILE на не-license командах с v0.20.0 был silent no-op, в v0.22.0 убран с CLI-surface, а в v0.30.0 удалён совсем — вместе с srekit license, единственной командой, которая его honor-ила.

Что не стабилизируется в 1.0 (может меняться в 1.x):

  • Содержимое поля frontmatter: — пока free-form map. Возможен переход на типизированную JSON Schema; breaking только для авторов, которые завязались на free-form структуру.
  • Точные формулировки stderr WARN для legacy-файлов.
  • Внутренние Go-API в internal/* — это internal/ намеренно, не используйте напрямую.

Полный upgrade-guide и список JSON shape changes по версиям — в docs/migration/v1.md.

License

MIT — см. LICENSE.

About

SRE text artifact generator — investigations, incidents, postmortems, RFCs, runbooks, SLOs, error budget policies, capacity plans, on-call reports, retros, changelogs. Single binary, bilingual embedded templates, JSON-pipelineable.

Topics

Resources

Security policy

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages