ГлавнаяБлогCommit Chronicles: Как SQL находит историю в коммитах
Алгоритмы

Commit Chronicles: Как SQL находит историю в коммитах

Узнайте, как Snowflake и SQL находят сюжет в истории коммитов GitHub. Чистый SQL без AI определяет драму вашего репозитория. Попробуйте сами!

Al
Редакция Algolitalgolit.ru
8 мин чтения13 июля 2026 г.

Зачем читать эту статью

Вы когда-нибудь задумывались, какую историю рассказывают ваши коммиты? График вклада показывает, что работа шла, но не говорит что именно происходило. Commit Chronicles — это инструмент, который берёт публичный GitHub-репозиторий, находит в его истории единственную сюжетную линию с помощью чистого SQL, а затем просит AI (Cortex) рассказать эту историю. Результат — карточка, которую можно встроить в README. В этой статье я покажу, как устроена архитектура, почему шесть детекторов сюжета работают без единого AI-вызова, и как вы можете запустить это на своём проекте.

Что такое Commit Chronicles

Commit Chronicles — это веб-приложение, которое анализирует историю коммитов одного публичного GitHub-репозитория и превращает её в короткую историю. Snowflake самостоятельно загружает данные с GitHub, определяет, какой сюжет скрыт в коммитах, собирает доказательства, просит Cortex написать повествование и возвращает структурированный JSON. Cloud Run лишь превращает этот JSON в PNG-картинку размером 1200×630 пикселей — идеально для README и соцсетей.

Каждая точка, временная метка и цитата на карточке реальны. Цвет не просто украшение — Cortex выбирает акцентный оттенок как интерпретацию дуги проекта, так что репозиторий, который «умер», и тот, который «воскрес и выпустил релиз», выглядят по-разному.

Важно: инструмент работает с одним репозиторием, а не с профилем целиком. У репозитория есть чёткая дуга: коммиты начинаются, группируются, делают паузу, возобновляются или прекращаются. Годовой обзор профиля размывает картину.

Правила, которые делают историю правдивой

  • Cortex интерпретирует форму, но не выдумывает факты. Каждая временная метка, количество, разрыв и цитата на карточке реальны. Модель читает дугу, но не выходит за её пределы. Мотивация отсутствует в данных — модели запрещено её придумывать.
  • Если в репозитории нет реальной истории, карточка это сообщает. Для разреженных историй генерируется серая карточка с надписью «здесь нет истории» — Cortex не запускается. Не каждый репозиторий — одержимость, и инструмент, который признаёт это, заслуживает доверия, когда говорит обратное.

Почему это важно: одержимость, а не страсть

DEV попросил рассказать о страсти, но я называю это одержимостью. Страсть — слово для слайдов конференции. Одержимость — это то, что на самом деле произошло: репозиторий, который вы не могли отложить, тот, который бросили в апреле и вернулись к нему в 3:32 ночи, или та неделя, когда каждый коммит был откатом.

Мы пролистываем эти коммиты сотни раз в неделю и не читаем их. Они — бухгалтерия. Я хотел, чтобы моя последняя одержимость рассказала историю, скрытую за этими коммитами — теми, которые вы принимаете как должное в каждом проекте, который когда-либо выпускали.

График вклада говорит, что работа была. Он никогда не говорит, что именно произошло. Цель была одна: доказать, что модель может найти что-то истинное в истории коммитов, не выдумывая сюжет.

Шесть детекторов сюжета на чистом SQL

У меня есть детектор под названием NOCTURNE. Он срабатывает, когда как минимум половина коммитов репозитория попадает в промежуток между 22:00 и 04:59. У него пять братьев и сестёр:

  • nocturne — построено после полуночи (≥50% коммитов 22:00–04:59)
  • relapse — ушло в тень, вернулось (разрыв ≥30 дней)
  • binge — не мог остановиться (стрик ≥7 дней подряд)
  • collapse — горело ярко, затем ничего (тишина ≥90 дней после всплеска)
  • fight — один и тот же баг снова и снова (≥4 откатов за 7 дней)
  • resurrection — вернулось и выпустило релиз (relapse + коммит релиза после)

Каждый из них — это SQL-представление (view). Ни одного AI-вызова. Детекторы работают на чистом SQL внутри Snowflake.

Архитектура: как это работает

1. Snowflake сам загружает данные

Интеграция внешнего доступа (EXTERNAL ACCESS INTEGRATION) позволяет Python-хранимой процедуре вызывать api.github.com изнутри Snowflake. Нет сервиса приёма данных, нет ETL-задачи, нет Cloud Function, которая хранит копию ваших коммитов. Процедура INGEST_REPO_COMMITS пагинирует API коммитов и загружает их в таблицу COMMITS, затем классифицирует ботов и AI-помощников с помощью SQL.

Лимит на приём — 500 коммитов. Если история длиннее, на карточке пишется «последние 500 коммитов · тихо с 25 февраля». Скрывать лимит — ложь, а выдавать срез за всю историю — ошибка.

2. Детектор бесплатен

Оценка шести сюжетных линий по всей истории репозитория стоит только времени работы warehouse — ни одного model-вызова в 15 представлениях. Этот слой делает дорогой слой дешёвым. К моменту, когда модель вступает в дело, SQL уже отбросил merge-коммиты и ботов, оценил все кандидатные нарративы, выбрал ровно одного победителя и отобрал строки коммитов, принадлежащие только этой линии.

3. Модель — это SQL-функция

CHRONICLE_CARD — это hand-written UDF, оборачивающая AI_COMPLETE (claude-sonnet-4-5). Модель вызывается изнутри SELECT. Нет HTTP-вызова, нет SDK, нет обёртки повторных попыток, нет очереди промптов. Это функция в запросе, сидящая рядом со строками, которые она читает. Доказательства никогда не покидают warehouse.

4. Единая точка входа

Весь API — это один вызов:

CALL READ_REPO('anchildress1', 'save-the-sun');

Нет логики приложения, решающей сюжет. Snowflake решает сюжет. Мой бэкенд ни разу не читал ваши сообщения коммитов и не знал бы, что с ними делать.

Пример кода: как выбирается сюжет

Вот ключевое представление, которое выбирает единственную сюжетную линию — одна оконная функция, и LLM ещё не вызывалась:

CREATE OR REPLACE VIEW REPO_STORYLINE AS
SELECT
    f.REPO_OWNER,
    f.REPO_NAME,
    COALESCE(s.STORYLINE, 'none') AS STORYLINE,
    COALESCE(s.SCORE, 0) AS SCORE,
    s.PIVOT_AT,
    -- все факты, которые будут напечатаны на карточке, вычислены здесь, в SQL
    OBJECT_CONSTRUCT(
        'commitCount', f.COMMIT_COUNT,
        'nightCommits', f.NIGHT_COMMITS,
        'activeDays', f.ACTIVE_DAYS,
        'daysSinceLast', f.DAYS_SINCE_LAST,
        'largestGap', OBJECT_CONSTRUCT('days', g.GAP_DAYS, ...)
    ) AS FACTS
FROM REPO_FACTS f
LEFT JOIN REPO_LARGEST_GAP g USING (REPO_OWNER, REPO_NAME)
LEFT JOIN STORYLINE_SCORES s USING (REPO_OWNER, REPO_NAME)
QUALIFY ROW_NUMBER() OVER (
    PARTITION BY f.REPO_OWNER, f.REPO_NAME
    ORDER BY s.SCORE DESC NULLS LAST, s.DRAMA_RANK -- ничьи разрешаются в пользу драмы
) = 1;

Каждая сюжетная линия имеет порог MIN_COMMITS = 15, так что бот-шум не может победить. Оценка детерминирована: один и тот же репозиторий всегда даёт один и тот же шаблон.

А вот как устроен tiebreak, чтобы карточка не переписывалась при повторном чтении:

-- Rebases и batch push имеют одинаковую AUTHORED_AT. Без SHA как финального
-- tiebreak коммиты, которые видит Cortex, могли бы различаться между двумя
-- чтениями одного репозитория — и карточка тихо переписала бы себя.
ORDER BY
    ABS(DATEDIFF(hour, w.PIVOT_AT, c.AUTHORED_AT)),
    c.AUTHORED_AT,
    c.SHA

Практический вывод: что делать прямо сейчас

Хотите увидеть историю своего репозитория? Перейдите на commitchronicles.anchildress1.dev, введите owner/repo любого публичного репозитория и нажмите «Submit». Закройте вкладку — задание выполняется на Cloud Tasks, а не в вашем соединении. Вернитесь на /{owner}/{repo} — карточка будет там. Вы можете встроить её в README или в комментарий к этому посту.

Если вы разработчик, вдохновитесь архитектурой: весь сложный анализ (детекция сюжета) делается на SQL, а AI вызывается только для финального повествования на 20–140 строках. Это держит стоимость под контролем и делает систему масштабируемой. Попробуйте применить тот же подход в своих проектах: сначала фильтруйте и агрегируйте данные на уровне базы данных, а AI используйте только для генерации текста на основе уже отобранных фактов.

Код проекта открыт на GitHub: anchildress1/commit-chronicles. Лицензия PolyForm Shield 1.0.0.

#SQL#Snowflake#коммиты#анализ данных#AI
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →