---
name: weekly-progress
description: "Generate narrative weekly chronicle entry for svaib project. Use ONLY when user invokes /weekly-progress."
disable-model-invocation: true
---

# Генератор недельной летописи

Генерация нарративной недельной записи из трёх источников: посты Telegram, session-log, трекер.

## Главное правило

**НИКОГДА не выдумывать контент.** Каждый факт должен быть из одного из трёх источников (Telegram, session-log, трекер). Если по направлению ничего не было — пропустить целиком. НЕ писать "ничего не было".

## ВЫПОЛНЯЙ СЕЙЧАС

1. Прочитать YAML-шапку `meta/management/04_weekly_progress.md`
2. Извлечь `last_recorded_week` и `last_recorded_post_id`
3. Следующая неделя = `last_recorded_week + 1`
4. Вычислить даты по формуле ниже
5. Подтвердить с пользователем: "Делаю weekly progress за неделю N (DD.MM — DD.MM). Верно?"
6. После подтверждения — выполнять фазы последовательно

**НАЧИНАЙ.**

## Вычисление дат

Старт проекта: 16 сентября 2025 (вторник). 5-недельный перерыв после недели 15 (29 дек 2025). Неделя 16 возобновлена 9 февраля 2026 (понедельник).

**Недели 1-15:** start = 2025-09-16 + (N-1) * 7 дней
**Недели 16+:** start = 2026-02-09 + (N-16) * 7 дней
**Конец недели** = start + 6 дней

Примеры:
- Неделя 1: 16.09 — 22.09.2025
- Неделя 15: 23.12 — 29.12.2025
- Неделя 16: 09.02 — 15.02.2026
- Неделя 20: 09.03 — 15.03.2026

---

## Фаза 1: Посты Telegram @svaib_lab

Прочитать `last_recorded_post_id` из YAML (напр., 141). Начать с ID + 1.

**Запрашивать пачками по 10 URL:**

```bash
uv run .claude/skills/reader-telegram/scripts/fetch_post.py \
  "https://t.me/svaib_lab/142" "https://t.me/svaib_lab/143" ... "https://t.me/svaib_lab/151"
```

**Обработка каждой пачки:**
- Каждый пост содержит поле **Date** в ответе
- Дата поста в рамках недели (start <= date <= end): **оставить**
- Пост вернул ошибку или пустой: считать в серию пустых
- **5 пустых подряд: конец канала. Стоп.**

**Сбор по датам.**
Собирать все посты с датой в рамках недели (start <= date <= end). Стоп-условия:
- Дата поста > end → стоп загрузки. `last_recorded_post_id` = последний пост с датой <= end
- 5 пустых ответов подряд → конец канала. Стоп

**После всех пачек:**
- Собрать все посты от start до end
- Посчитать общее количество постов для секции Маркетинг

**Важно:** Пропуски в ID постов — нормально (удалённые посты, медиагруппы, сервисные сообщения). Пустой ответ — НЕ ошибка.

## Фаза 2: Session log

Грепнуть `meta/management/session-log.md` по датам недели.

Вычислить все 7 дат (понедельник — воскресенье) в формате YYYY-MM-DD. Искать заголовки секций через Grep: `## YYYY-MM-DD`.

Читать ТОЛЬКО совпавшие секции (от `## date` до следующего `## ` или конца файла). НЕ читать весь session-log.

Извлечь теги направлений и содержание из записей формата `**HH:MM | direction**`.

## Фаза 3: Данные трекера

Спросить пользователя:

> Данные из трекера за неделю N? (или "пропустить")

Дождаться ответа. Если "пропустить" или аналогично — продолжить без данных трекера.

## Фаза 4: Контекст миссии

Прочитать для понимания миссии и текущих целей:
- `meta/management/01_vision.md`
- `meta/management/02_goal.md`

Это стратегический контекст — не данные для летописи.

---

## Фаза 5: Генерация записи

Перед генерацией прочитать последнюю запись из `meta/management/04_weekly_progress.md` как пример формата и тона.

**Формат:**

```markdown
## Неделя N (DD.MM — DD.MM) — XX ч

{2-3 предложения — главная тема недели, задающая тон всей записи}

### Лаборатория — Xч
{мини-история направления}

### Продукт (Second Brain) — Xч
{мини-история направления}

### Клиенты — Xч
{мини-история направления}

### Маркетинг — Xч
{мини-история, ОБЯЗАТЕЛЬНО указать кол-во постов}

### Сайт — Xч
{мини-история направления}

### Knowledge — Xч
{мини-история направления}
```

**Часы из трекера:**
- Общее количество часов — в заголовке недели, округлять до целых
- Часы по направлениям — в заголовках секций, округлять до целых
- Маппинг тегов трекера → направления летописи:
  - `svaib - framework` → Продукт (Second Brain)
  - `svaib - lab` → Лаборатория
  - `svaib - clients` → Клиенты
  - `svaib - public` → Маркетинг
  - `svaib - ai-learn` → Knowledge
  - `svaib - context` → не выделять отдельно, распределять по смыслу или указать в подходящей секции
- Если трекер не предоставлен — часы не указывать, формат заголовков без ` — Xч`
- Направления без часов в трекере: не указывать часы в заголовке секции

**Анонимизация клиентов:**
- Летопись публична (GitHub) → имена и фамилии клиентов НЕ указывать
- Писать по сути: "появился второй клиент", "пост-обработка клиентской встречи", "первая встреча с новым клиентом"
- Количество клиентов и характер работы — указывать, конкретные имена — нет
- Детали по клиентам живут в `clients/` (gitignored)

**Стиль:**
- Нарративная проза, НЕ буллеты — связные предложения, рассказывающие историю
- Каждая секция — мини-история: что хотели → что делали → что получилось (или не получилось). Читатель должен чувствовать драматургию недели, а не читать отчёт
- Главное событие недели раскрывать подробнее (5-8 предложений), второстепенные — компактнее (2-4)
- Пустые направления пропускать целиком — не включать секции без данных
- Тон из постов Виктора в Telegram: лёгкий, с самоиронией, честный. Фиаско называть фиаско, победы — победами
- Конкретные факты и результаты, не расплывчатые описания
- Маркетинг ОБЯЗАТЕЛЬНО указывает количество опубликованных постов
- Русский язык

**Чеклист перед показом драфта:**
- [ ] Каждый факт привязан к источнику (пост Telegram, запись session-log, трекер)
- [ ] В секции Маркетинг указано кол-во постов
- [ ] Ни одно направление не содержит выдуманного контента
- [ ] Пустые направления опущены, а не упомянуты
- [ ] Общий объём: 200-500 слов (больше нарратива, меньше сухих сводок)
- [ ] Главное событие недели раскрыто как история, а не как перечисление
- [ ] Если трекер предоставлен: часы в заголовке недели и в заголовках секций

## Фаза 6: Ревью и запись

1. Показать драфт пользователю
2. Дождаться одобрения или правок
3. После одобрения:
   a. Вставить запись В НАЧАЛО `meta/management/04_weekly_progress.md` (после YAML-разделителя `---`, перед первым `## Неделя`)
   b. Обновить YAML: `last_recorded_week: N`
   c. Обновить YAML: `last_recorded_post_id: {ID recap-поста, или последнего поста с датой <= конец недели если recap не было}`
   d. Если постов Telegram не найдено: НЕ менять `last_recorded_post_id`
4. Подтвердить: "Записал неделю N. Post ID обновлён до {X}."

---

## Нештатные ситуации

| Ситуация | Действие |
|----------|----------|
| Нет постов Telegram за неделю | Сообщить пользователю, продолжить с session-log + трекер. НЕ обновлять `last_recorded_post_id` |
| Посты выходят за end | Нормально. Стоп по дате, `last_recorded_post_id` = последний пост с датой <= end |
| fetch_post.py не работает (сеть) | Сообщить пользователю, предложить продолжить без Telegram |
| Пользователь пропустил трекер | Нормально — генерировать из Telegram + session-log |
| Нет данных ни из одного источника | НЕ создавать пустую запись. Сказать: "За неделю N данных нет" |
| В session-log нет записей за неделю | Нормально — генерировать из остальных источников |
| Пропуски в ID постов (удалённые) | Нормально. Считать в серию пустых, не ошибка |
| 5+ пустых ответов подряд | Конец канала. Прекратить загрузку, работать с тем что собрано |
| YAML-шапка отсутствует или повреждена | СТОП. Сказать: "YAML в 04_weekly_progress.md повреждён, проверьте вручную" |

## Связанные скиллы

- **reader-telegram** — единая точка правды для парсинга постов Telegram. Этот скилл вызывает `fetch_post.py` из reader-telegram пачками; reader-telegram — для чтения одиночных постов по запросу
- **close-session** — пишет записи в `session-log.md`, который этот скилл читает как источник данных
