Ченджлог релізів
Що змінилося в задеплоєному стані, реліз за релізом. Збирається з репо на білді: зовнішній CHANGELOG.md (зміни для вчителів і методистів) + внутрішні specs_concept/changelog/*.md (ноди, міграції, PR). Оновлення — node scripts/changelog_json.mjs разом із релізом.
v2026-09-07 — AI-ментор для учня, бібліотека навичок і надійніші класи
- Що змінилося:
- В учня з’явився AI-ментор. Тепер учень може відкрити пояснення теми — короткий розбір із його підручника — і поставити уточнювальні запитання в діалозі; історія розмов зберігається.
- Бібліотека навичок доопрацьована — її наповнено за методичним ТЗ: навички мають статус рев'ю й налаштування по курсу, методисту видно прогрес заповнення.
- Рубрики стали повнішими — таб рубрик розширено за ТЗ (поля типу рубрики, критерії).
- Класи надійніші: клас більше не створиться двічі дабл-кліком, а дві однакових назви в межах одного навчального року й рівня — заблокується.
- Учень може редагувати свій профіль (імʼя, контакти) у налаштуваннях; налаштування класу/рівня зберігаються.
- Конструктор: менше зайвого. Прибрано неіснуючі розділи (медіа-центр), статичні підказки AI-хрому на стартових сторінках, показ мок-блоків тепер керується персистентним тумблером (якщо сховалі — не повернуться). Клік на модуль в outline уроку прокручує канвас до блока; лічильник рекомендації про «розбиття уроку» рахує кроки-картки, а не службові рядки.
- Вчитель: підручник у PDF тепер можна завантажити в конструктор із розпізнаванням текстового шару (легше перевикористовувати матеріали).
- Після генерації індикаторів у результаті видно посилання на журнал запиту й метрики (час, токени, ціна) — простіше зрозуміти й перевірити результат генерації.
- Приватність: додано екран згід на обробку даних і дельта-бриф платформи.
Пакетний реліз (перший за 07.09): **168 комітів** за діапазон `origin/main..origin/stage` (після v2026-09-02). Код-хвилі W1–W3 конструктора: admin/класи (401–403), профіль учня (415/416/419), AI-ментор студента (389/390/391), приватність (379), моки-гігін (426–428), конструктор (420/407/1/2/3/25), KG-підручник з text-layer (424), бібліотека навичок за ТЗ (429), рубрики за ТЗ (430), метрики генерації індикаторів (404), performance-базлайн (441) + аудит схеми методиста (440) та bookkeeping/док-пачка (включно #968 docs/442-design). **Міграції: 5, з них одна data-guard** (див. §Міграції; `alembic heads` = 1 — `6c9d0e1f2a3b`, ланцюг лінійний). CI: код-PR із лейблом `build` (#938 #940 #941 #946 #947 #948 #952 #953 #954 #961 #962 #963 #964) — локальні прогони на W1–W3: pytest на PG per-lane (xdist), sqlite-fallback, frontend `pnpm typecheck` + `next build` (worktree-typecheck/verify); bookkeeping/docs/scripts-мерджі — без лейбла (політика CI-бюджету, paths-filter), зокрема docs #968. CI реліз-PR — фінальний доказ стану.
- ноди
- 430 `rubrics-tab-populate` (#964) · 429 `skills-library-populate` (#963) · 404 `indicator-gen-result-metrics` (#954) · 441 `test-performance-baseline` (#953) · 401 `class-create-duplicates-unique-name` (#938) · 402 `lesson-picker-cross-class-subjects` (#938) · 403 `roster-main-class-admin-only` (#938) · 390 `student-ai-mentor-explain` (#961) · 391 `student-ai-mentor-chat` (#962) · 415 `student-profile-edit-save` (#940) · 416 `student-grade-model` (#940) · 419 `student-account-menu-empty-items` (#940) · 379 `privacy-platform-delta-brief` (#947) · 426 `media-center-page-remove` (#946) · 427 `hidden-ui-mocks-cookie-regression` (#946) · 428 `mentor-hint-chrome-remove` (#946) · 420 `lesson-block-count-steps-vs-rows` (#941) · 407 `lesson-builder-outline-scroll` (#941) · 425 `mentor-topbar-profile-button-inert` (#947) · 1 `kg-slug-fallback` (—) · 3 `dead-ctas-publish` (—) · 2 `constructor-clean-run` (—) · 25 `ai-generation-g` (—) · 5 `pnpm-lint` (—) · 4 `requirements-pins` (—) · 19 `teacher-training` (#935) · 440 `methodist-schema-audit` (#932/#957/#965/#936)
- міграції
- `backend/alembic/versions/d2e3f4a5b6c7_node401_classes_unique_name.py` (нода 401) — data-guard + schema: перед створенням `UNIQUE(name, academic_year, grade)` (PG: `UNIQUE NULLS NOT DISTINCT`) — read-only пре-чек дублікатів; знайдено групу-дублікат → abort зі списком id (патерн data-guard). Прод-клінс виконаний до релізу (метод-рішення користувача; видалено тестові рядки «Тест дублювання 9А» — жива перевірка read-only: 0 груп-дублікатів, total classes=8). `alembic heads` = 1. `backend/alembic/versions/6c9d0e1f2a3b_node430_rubric_tab_fields.py` (нода 430) — schema-only: розширення `rubrics`/`rubric_criteria` (таб-поля типу рубрики); downgrade — зворотне видалення. `backend/alembic/versions/b8c9d0e2f3a4_node429_course_skills_settings.py` (нода 429) — schema-only: нова таблиця `course_skills` (семейте-skills настройки курсу); downgrade — drop. `backend/alembic/versions/e4f5a6b7c8d9_node391_mentor_chat.py` (нода 391) — schema-only: нові таблиці `mentor_conversations` + `mentor_messages` + індекси (ADD TABLE). `backend/alembic/versions/f7a8b9c0d1e2_node429_skill_review_status.py` (нода 429) — schema-only: `review_status` у `skills`.
- PR
- #968 #936 #967 #964 #961 #966 #965 #962 #963 #960 #959 #958 #957 #956 #955 #954 #953 #952 #951 #950 #948 #946 #947 #941 #945 #938 #940 #939 #943 #944 #942 #937 #935 #934 #933 #932 #931 #930 #929 #928 #927 #925 #926 #924 #922 #923 #921 #920 (непродуктивні: #956 docs/meta-orchestrator-extended, #968 #933 #932 #930 #929 #928 #927 #926 #924 #923 #921 #920 #959 — доки/бекфіли/інтейки без коду; багато хвиль.)
- ризики
- Міграція 401 data-guard — прод був заблокований наявністю двох тестових дублікатів «Тест дублювання 9А »; клінс виконано до релізу (метод-рішення). Якщо в майбутньому з'являться дублі — міграція чесно абортить (патерн 21.08), потрібен чистий backfill.
- AI-ментор (391): MVP без SSE (відповідь відразу повна), moderation вводу — обов'язкова тема наступних кроків; на проді чат з реальним LLM не провертий (hermetic-reasoning + ручний preview). live-смоук — follow-up.
- Паралельні компоненти AI-генерації (390): нові `explain`-річя вигляд на LLM-квоту (повний `llm_request_log` після 392 — моніторинг розміру таблиці залишається не закритий (інтейк 02.09, нода 405).
- Perf-базлайн (441): цифровий протокол заміри, документовано, але xdist-флейки — follow-up ізоляційний фікс.
- Поза релізом (open, наступні): нода 442 `kg-artifact-source-of-truth-fix` (data-bearing, requires_confirmation — гейт користувача), нода 406 (learning-architecture-scheme), 396/397; дизайн-пачка 440-сусідів (PR #936 — дизайн-черга).
джерела: specs_concept/changelog/2026-09-07.md CHANGELOG.md
v2026-09-03 — Прозоріший журнал AI-запитів і швидша генерація індикаторів
- Що змінилося для вчителів і методистів:
- Журнал запитів до штучного інтелекту став прозорішим. Раніше в налаштуваннях AI було видно лише службову інформацію про запит; тепер видно повний текст промпта, який отримала модель, і її відповідь — легше зрозуміти, чому згенеровано саме такий контент, і розбирати проблеми генерації.
- Генерація індикаторів стала швидшою — поняття теми тепер обробляються паралельно, а не одне за одним. Для тем із багатьма поняттями очікування скорочується.
- Виправлення дрібних незручностей інтерфейсу: вікно стану генерації тепер має помітну кнопку закриття «×»; форма створення класу не «колапсує» поле назви на вузьких екранах.
Перший реліз за 03.09: **56 комітів** за діапазон main..stage — код-хвилі після v2026-09-02: ноди 388 (паралелізм генерації індикаторів), 392 (вміст промптів у журналі LLM), 393/394 (UI-фікси), 395 (детермінізм batch-status), 398 (атомарний облік квоти LLM), 399 (hermetic reasoning-тести), 400 (ретеншн журналу LLM) + дизайн-доки 368/375 (рішення для інтерактивних сесій), формування графа нод 401–405 (інтейк 02.09, дублі класів, lesson-picker, roster main_class, метрики) та bookkeeping (104 done, 406 — 4c пауза). **Міграції: 1, schema-only** (див. §Міграції; `alembic heads` = 1 — `e0d1c2b3a4f5`, ланцюг лінійний). CI: на діапазоні код-PR з лейблом `build` (#905, #907, #908, #912, #913, #914, #899) — фінальні рани `success` (backend: pytest на PG per-lane; frontend: vitest + tsc + next build); bookkeeping/docs/scripts/інтеїк-PR (#900/#901/#902/#904/#903/#909/#910/#911/#915/#916/#917/#873/#874/#898) — без лейбла (політика CI-бюджету, paths-filter; #904/#903 — суто css-зміни). Доказ фінального стану дасть CI реліз-PR.
- ноди
- 398 `llm-usage-lost-update-fix` (#914) · 399 `reasoning-effort-tests-fix` (#912) · 400 `llm-request-log-retention` (#913) · 395 `batch-status-deterministic-order` (#907) · 388 `indicator-gen-parallelism` (#905 (+#899 roadmap)) · 392 `llm-prompt-content` (#908) · 393 `mock-overlay-close-btn` (#904) · 394 `class-create-form-small-screen` (#903) · 104 `nmt-diagnostics` (#910) · 373 `theme-indicators-batch-status-slow` (—)
- міграції
- `backend/alembic/versions/e0d1c2b3a4f5_llm_request_log_content.py` (нода 392) — schema-only: три nullable TEXT-колонки (`prompt_system`, `prompt_user`, `response_content`) у `llm_request_log`. Дані не конвертуються і не чіпаються (старі рядки → NULL, без бекфілу); downgrade — звичайне видалення колонок. `alembic heads` = 1.
- PR
- #917 #916 #915 #914 #913 #912 #911 #910 #909 #908 #905 #904 #903 #902 #907 #901 #900 #873 #874 #899 #898 (+ коміт `8db5bfc4` «switch to other provider» — конфіг `.pi/agents` checker/roadmap-bot, у реліз-PR входить як частина stage-head; провайдер агентів змінено в контейнері, на прод нічого не впливає.)
- ризики
- Зростання llm_request_log після ноди 392: у журнал пишуться повні тексти промптів і відповідей — обсяг рядків зростає; кап `LLM_LOG_CONTENT_MAX_CHARS` (нода 400) ставиться цим же релізом, але моніторинг розміру таблиці на проді — follow-up (інтейк 02.09, нода 405).
- Паралелізм LLM (нода 388): per-поняттєві bursts викликів на OpenRouter — потенційні rate-limit/квотні відповіді при великих темах; тести hermetic, «живий» навантажувальний смоук генерації не ганявся.
- Нода 373 (перф «Відхилити всі») не закрита — 92 послідовні PATCH лишаються (ніт 02.09: потрібен batch-endpoint); флейк-частину знято нодою 395.
- Поза релізом: ноди 396/397 (UI-diagnostic-КТ, контент методистом), 401–405 (інтейк 02.09), 406 (learning-architecture-scheme, 4c пауза) — open, наступні хвилі; дизайн 368/375 — decisions.md готові, інтерактивні сесії з користувачем попереду.
джерела: specs_concept/changelog/2026-09-03.md CHANGELOG.md
v2026-09-02 — Технічний реліз: гнучкіша робота з моделями штучного інтелекту
- поліпшення «під капотом»:
- Генерація контенту надійніша з різними моделями штучного інтелекту. Раніше системі підходила лише одна родина моделей; тепер запити коректно налаштовуються і для моделей, які не дозволяють вимикати «міркування» — генерація не падає з помилкою, коли адміністратор обирає іншу модель.
- Конвеєр графа знань тепер конфігурується змінними оточення (модель, адреса сервісу, ключ) — зміна провайдера штучного інтелекту для обробки підручників більше не потребує зміни коду.
Перший реліз за 02.09: **7 комітів** за діапазон main..stage — два кодових PR (#893 fix, #894) і docs-PR #895 (довіз розділу MILESTONES + verify-запису попереднього релізу в stage — контент уже був у main через #891/#892, доїжджає до stage канонічним потоком #895). **Міграції: немає** (alembic heads = 1 — `b7c8d9e0f1a2`, ланцюг не чіпався).
- ноди
- 72 `kg-pipeline-key` (#894 закриває залишковий ніт: декоративний env `DEEPSEEK_MODEL` вилучено з обігу, хардкод моделі в `design/*.py` замінено на конфігуровані змінні (запис у `launch_2026-09-01.md`, рядок 72)) · — (#893: DeepSeek — `thinking:disabled` + `reasoning_effort:none`; GLM (`z-ai/glm-5.3-flash`, обов'язкове міркування) — `reasoning_effort:minimal` БЕЗ ключа `thinking` (ендпоінт відхиляє вимкнення 400 «Reasoning is mandatory...»); запити з явним `reasoning_effort` (уроки `low`) — `thinking:enabled` + рівень, підтримують обидві родини)
- міграції
- —
- PR
- - **#893** `fix(ai-gen)`: model-aware reasoning payload — GLM-сумісність (`feat/ai-model-glm-5-3-flash`, merge `acc3d9c2`). Лейбл `build`. - **#894** `feat(kg-pipeline)`: конфігуровані модель/ендпоінт/ключ конвеєра графа — `KVANT_LLM_KG_MODEL`/`KVANT_LLM_KG_BASE_URL`/`KVANT_LLM_KG_API_KEY` (фолбек `DEEPSEEK_API_KEY`), дефолти = поточні значення (`feat/kg-llm-env-config`, merge `6ddd4121`). Лейбл `build`. - **#895** `docs(milestones)`: розділ релізу v2026-09-01-3 + verify-запис — у stage (cherry-pick `726dca63`/`5db7d121` з main; реліз-гейт `--milestone-gate v2026-09-01-3`). Без лейбла (docs, paths-skip — канон).
- ризики
- GLM-шлях перевірено лише живим смоуком на `z-ai/glm-5.3-flash` — «Reasoning is mandatory» — це поведінка ендпоінта OpenRouter, не код: інша модель родини GLM може поводитись інакше. Дефолт коду — як і раніше `deepseek/deepseek-v4-pro-0813`; прод перемикається через `OPENROUTER_MODEL` (доки не виставлено — поведінка не змінюється).
- Дата «09.09» у коментарях/тесті #893 (перевірка живим викликом `z-ai/glm-5.3-flash`) — імовірно друкарська помилка (коміт 01.09); косметика, на код не впливає. Кандидат у дрібний docs-фікс наступної хвилі.
- `design/*.py` без тестів — зміни конфігурації LLM-клієнта графа перевіряються наступним реальним прогоном інтейка (offscreen-батч).
- Поза релізом: відкриті #873/#874 (docs-аналізи нод 368/375, рішення користувача — ігноруються); черга ланок наступних хвиль (editor P0, class-mechanics) — див. актуальний хендовер.
- Контент #895 уже був у main (через #891/#892 напряму) — при мерджі реліз-PR конфліктів не очікується: файли збігаються дослівно (cherry-pick).
джерела: specs_concept/changelog/2026-09-02.md CHANGELOG.md
v2026-09-01-3 — Конструктор: швидша робота з індикаторами, журнал запитів і черга генерації
- Що змінилося для вчителів:
- **Кнопка «Почати» на головній сторінці тепер веде до реальної реєстрації** — раніше вона показувала демо-форму, з якої нічого не відправлялось.
- Автокомпліт у полі «Призначити урок»: замість довгого випадаючого списку тепер можна почати вводити назву — система сама підказує відповідні уроки.
- Виправлено падіння сторінки уроку в учня — блоки з некоректними адресами зображень більше не ламають урок; вони просто не показують зіпсований медіа-елемент.
- Виправлено помилку «subject not in class» при призначенні уроку класу: список уроків тепер показує лише предмети, які викладаються в цьому класі.
- Тип завдання «Підписи на зображенні» тепер працює — раніше він не відображався коректно у конструкторі.
- «Відхилити всі» в індикаторах працює одним кліком — раніше система надсилала запит на кожен індикатор окремо (при десятках індикаторів це могло «підвисати»).
- Можна вставити кілька HTML-блоків за одну операцію в конструкторі (наприклад, цілий фрагмент підручника з кількома абзацами/картинками).
- Сторінка-інструкція для вчителя — операційна довідка, як працювати з платформою.
- Що змінилося для методистів:
- Журнал запитів до ШІ: тепер видно всі виклики генераторів — який генератор, який промпт, скільки часу зайняло і чи була помилка. Зручно для перевірки якості генерації.
- Робота з каталогом понять стала швидшою: повторювані (майже однакові) поняття в базі знань злиті в одне, що прискорює генерацію та зменшує плутанину в графі.
- Що змінилося всередині (технічне):
- **Генерація уроків/завдань більше не «падає» з помилкою 502 на повних темах**: довгі генерації тепер стають у чергу та завершуються у фоні (кнопки показують статус).
- Моніторинг помилок у браузері — помилки фронтенду тепер теж потрапляють у систему спостереження (раніше — лише серверні).
- Захист робочого середовища розробки від випадкових автоматичних правок коду (внутрішнє).
Третій реліз за 01.09, після v2026-09-01-2: **53 коміти** за діапазон main..stage — хвилі 1–3 нативного прогону (ноди 87, 16, 380, 360, 373, 278, 346, 290, 383, 381, 382, 348, 384), lens-guard спільного дерева (нода 387), рефлексії w1–w3 і сесій 01.09, агент-таймаут, verify-запис і розділ MILESTONES попереднього релізу (#870, їхав у stage ще не в main). **Міграції: 2, обидві schema-only** (дані не конвертуються і не чіпаються): - `c9b0d1e2f3a4` `node360_llm_request_log` — нова таблиця `llm_request_log` (журнал викликів LLM: generator, prompt_version, model, status, токени, тривалість). Data-guard N/A — нова таблиця. - `b7c8d9e0f1a2` `ai_gen_task_payload` — розслаблення схеми `ai_gen_tasks`: додається nullable `payload` (JSONB на PG, канон S9) + `theme_id` → nullable (subject-рівневі задачі структурою курсу теми не мають). Non-data-bearing; downgrade вимагає чистих даних (коментар у файлі). CI: на stage-мерджах діапазону важкі гейти ганялись на кодових PR з лейблом `build` (#871/#872/#876/#877/#878/#880 — backend: pytest на PG per-lane, frontend: vitest + tsc + next build; усі фінальні рани `success`); bookkeeping/docs/scripts PR (#870/#875/#879/#881/#882/#883/#884/#885/#886/#887/#888) — без лейбла (політика CI-бюджету, paths-filter). Доказ фінального стану дасть CI реліз-PR.
- ноди
- 87 `llm-generation-queue` (#880) · 16 `teacher-instruction` (#871) · 380 `landing-start-cta-mock-registration` (#871) · 387 `lens-guard-workspace` (#886/#887/#888) · 360 `llm-requests-navigator` (#877) · 278 `bulk-html-blocks` (#877) · 290 `kg-catalog-dedup` (#877) · 382 `mentor-assign-lesson-autocomplete` (#878) · 346 `image-labeling` (#876) · 373 `indicators-batch-status` (#877) · 383 `student-lesson-server-render-crash` (#876) · 381 `mentor-assign-lesson-subject-not-in-class` (#876) · 348 `cross-grade-requires` (#872) · 384 `sentry-hardening` (#872)
- міграції
- `c9b0d1e2f3a4` — schema-only (нова таблиця `llm_request_log`, дані не конвертуються). `b7c8d9e0f1a2` — schema-only (nullable `payload` JSONB + `theme_id` → nullable у `ai_gen_tasks`; розслаблення, дані не чіпає).
- PR
- - #870 docs: verify-запис релізу v2026-09-01-2 + розділ MILESTONES (без лейбла) - #871 w1-fe-frontend: CTA «Почати» → /sign-up (нода 380) + /mentor/instruction (нода 16) — `build` - #872 w1-backend-ops: sentry-hardening client-side (384) + cross-grade REQUIRES (348) — `build` - #875 bookkeeping(w1): 6 нод done (PR #871/#872) + MILESTONES W1 - #876 w1-bugs: 381 scope lessons, 346 image_labeling, 383 safe-media-url — `build` - #877 w1-features: 360 журнал LLM, 373 батч-статус, 278 bulk HTML, 290 дедуп KG — `build` - #878 w2-lesson-autocomplete: 382 автокомпліт призначення уроку — `build` - #879 bookkeeping(w2+3): 382, 87 → done + MILESTONES - #880 w3-llm-queue: 87 генеральний контракт черги + 5 генераторів ?async=true — `build` - #881 bookkeeping(reflection): 95 → done + рефлексія w1–w3 - #882 fix(agents): timeoutMs 90 хв (P0-1 рефлексії w1–w3) - #883 docs(reflection): рефлексія релізу v2026-09-01-2 + фікси промпта/README - #884 docs(reflection): сесія інтейку 01.09 + фікс парсера reflection_registry - #885 fix(scripts): wiring_registry --help/-h (P1-2) - #886 roadmap(node 387): lens-guard-workspace - #887 feat(node 387): tracked .pi-lens.json спільного дерева - #888 bookkeeping(node 387): 387 → done + реген registry
- ризики
- AI-черга (нода 87) — перша ітерація: у черзі 5 довгих генераторів, резюм і пріоритизація задач, моніторинг (журнал 360 дає видимість); поглиблення (blackboard-статуси, worker-пул, dead-letter) — наступні хвилі.
- Дедуп KG (нода 290) — алгоритмічний (стемінг) він не є: злиття near-duplicate пар виконано разово в джерелі; повторні дублікати ловить той самий пайплайн при наступних інтейках; guard retarget не створює циклів REQUIRES (перевірено тестом).
- `llm_request_log` росте з кожним генеративним викликом — чистильника (TTL/архів) поки немає; навантаження мало (методист-навігатор), але враховувати на інтенсивах.
- Нода 384 (sentry-hardening) закрита, але JS-DSN на Vercel підтверджувався як «найімовірніше відсутній» у попередньому релізі — client-side capture у цьому релізі працює лише якщо DSN реально виставлено (перевірено в коді: capture з пустого DSN — no-op).
- Відкриті PR #873/#874 (ноди 368/375, docs-аналізи design-сесій) — рішення користувача: не входять у реліз, ігноруються (документи рефлексії).
- Поза релізом: нода 375 (канон shell-форматування), 368 (AI-ментор учня), інтейк-ноди 384–386 закриті, але черга ланок наступних хвиль (editor P0, class-mechanics) — див. актуальний хендовер.
джерела: specs_concept/changelog/2026-09-01-3.md CHANGELOG.md
v2026-09-01-2 — Моніторинг стабільності: розділення середовищ і новий інтейк
- Що змінилося для вчителів:
- Зовнішніх змін у продукті немає — цей реліз технічний (моніторинг стабільності та внутрішня документація).
- Що змінилося всередині (технічне):
- Помилки тестового середовища більше не плутаються з продом: система моніторингу тепер розрізняє staging і продакшен, тож сплеск помилок на staging більше не виглядає як інцидент у бойовому середовищі.
- Зафіксовано новий інтейк багів і побажань (01.09): 4 нові задачі в роадмапі; найкритичніша — кнопка «Почати» на головній сторінці веде до мок-реєстрації (в опрацюванні).
- Покращено доступ команди до логів Vercel і Railway — задокументовано токени й read-only перевірки, додано ноди на доступ до логів.
Другий реліз за 01.09, після v2026-09-01: **12 комітів** за діапазон main..stage (6 PR: #863–#868) — Sentry environment-розділення (`SENTRY_ENVIRONMENT`, реалізована частина ноди 384 `sentry-hardening`), інтейк 01.09 (ноди 380–383 додано в роадмап, усі `status open`), ноди-доки 384–386, інфра-доки (доступ до Sentry, логів Vercel/Railway), правила процесу (worktree-режим релізу, fresh body-file), розділ MILESTONES v2026-09-01. **Міграцій у релізі немає** — schema-only і data-bearing відсутні (перевірено `git diff origin/main...origin/stage -- backend/alembic/versions/`). Єдина backend-зміна — `_init_sentry()` у `backend/app/main.py`: пріоритет `SENTRY_ENVIRONMENT` над `RAILWAY_ENVIRONMENT` (обидва Railway-сервіси лежать в одному env `production`, тож без явної змінної staging-спайк виглядав би як прод-інцидент; на Railway виставлено: `ont` → `production`, `ont_preview` → `preview`). Прод-дані не зачіпаються. CI: на stage-мерджах діапазону важкі гейти не ганялись (docs/ops PR без лейбла `build` — політика CI-бюджету, канон #650/#654; `wiring-registry.json` регенеровано в PR #866, зміна — лише лічильники 386→393 нод). Доказ фінального стану дасть CI реліз-PR.
- ноди
- 384 `sentry-hardening` (#867) · 385 `vercel-logs-access` (#867) · 386 `railway-logs-access` (#867) · 380 `landing-start-cta-mock-registration` (#866) · 381 `mentor-assign-lesson-subject-not-in-class` (#866) · 382 `mentor-assign-lesson-autocomplete` (#866) · 383 `student-lesson-server-render-crash` (#866)
- міграції
- —
- PR
- - #863 docs/milestones-v2026-09-01 — розділ релізу v2026-09-01 у MILESTONES - #864 docs/body-file-fresh-rule — правило «fresh body-file» (інцидент 01.09, PR #860) - #865 docs/release-worktree-mode — опційний worktree-режим релізу (крок 0) - #867 ops/sentry-logs-nodes — Sentry env-розділення + ноди 384–386 + infra-доки - #866 intake-2026-09-01-bugs — інтейк нод 380–383 (demo_feedback + graph.json + wiring-registry) Усі — docs/ops, без лейбла `build`.
- ризики
- Нода 384 лишається open: env-розділення — лише перший крок; client-side capture, алерти, шум LLM і source maps — наступні (статус: Sentry бачить тільки `environment=production` до 01.09 — виправлено цим релізом).
- `SENTRY_ENVIRONMENT` — ручний env: якщо на новому сервісі не виставити (`production`/`preview`), фолбек — `RAILWAY_ENVIRONMENT` (в обох сервісів `production`), тобто staging знову виглядатиме як прод.
- JS-DSN на Vercel, найімовірніше, відсутній (жодної події `platform=javascript` за 10 днів) — пункт чекліста ноди 15 неперевірений.
- Інтейк 380–383 — відкриті задачі (найкритичніша 380 «Почати» → мок-реєстрація, критична Б) — черга наступних хвиль, див. актуальний хендовер.
- Поза релізом: нода 375 (канон shell-форматування) — status open; черга ланок наступних хвиль (class-mechanics wave1, editor P0, інтейк 01.09).
джерела: specs_concept/changelog/2026-09-01-2.md CHANGELOG.md
v2026-09-01 — Конструктор уроків: генерація за один клік і реальні дані
- Що змінилося для вчителів:
- «Згенерувати урок» прямо в конструкторі: замість окремого екрана кнопка доступна в самому конструкторі — можна обрати, за якими індикаторами генерувати урок.
- Шапка конструктора показує справжню ціль теми: раніше в ній був текст-заглушка, тепер видно реальну мету, і її можна редагувати.
- Кабінет учителя вітається реальним ім'ям: раніше всі вчителі бачили привітання «Олено» — тепер — своє ім'я.
- Створення предмета в графі знань доступне вчителю й методисту, а не лише адміністратору.
- Поняття графа теми можна редагувати завжди: видаляти зайві або додавати пошуком — раніше редагування відкривалося лише коли список понять був порожній.
- Сторінка курсу перестала час від часу «падати»: запити до сервісів тепер повторюються при тимчасових збоях, тож сторінка рідше показує помилку.
- Що змінилося для всіх користувачів:
- Справжні юридичні документи: сторінки «Політика конфіденційності» та «Оферта» містять копії реальних документів і реквізити ТОВ (раніше — заглушки), а версія політики, з якою користувач погоджується, фіксується в системі.
- Що змінилося для методистів:
- Генерація індикаторів теми не виходить за межі теми: виправлено помилку, коли замість 4 індикаторів могло згенеруватися 16 (захоплення індикаторів сусідніх модулів).
- Що змінилося всередині (технічне):
- Швидша збірка інтерфейсу завдяки теплому кешу збірки (заміри показали прискорення, рішення прийнято).
- Розширені автоматичні перевірки генерації: захист від помилок «неочікуваний формат» в оцінці якості генерації.
- Пілотна оцінка якості вилучення понять із хрестоматій літератури (внутрішній процес, для методистів з'явиться окремо).
Перший реліз за вересень, після v2026-08-31: **88 комітів** за діапазон main..stage — хвиля 1a/1b (ноди 370–378, баги + побажання інтейку 31.08), пілот хрестоматії (нода 241), бенчмарк next build (нода 369, adopt теплого кешу), юніт-тести batch переприв'язки kg_concepts (нода 289), фікс інтермітентного падіння сторінки курсу (нода 365, retry у @kvant/api), тест scope генерації індикаторів (нода 362), юр-документи в продукті (нода 377, критична Б), consent-version-pin (нода 378), плюс bookkeeping/docs/рефлексії. **Міграцій у релізі немає** — schema-only і data-bearing відсутні (перевірено `git diff origin/main...origin/stage -- backend/alembic/versions/`); `backend/**` чіпається лише тестами (ноди 289/362/376) і `eval_scorer.py`/`auth.py` (нода 376) — прод-дані не зачіпаються. CI: на stage-мерджах діапазону важкі гейти ганялись на кодових PR (лейбл `build` у #841–#846/#849–#854 — backend: pytest на PG per-lane, frontend: vitest + tsc + next build); bookkeeping/docs PR — без лейбла (політика CI-бюджету). Доказ фінального стану дасть CI реліз-PR.
- ноди
- 377 `legal-docs-in-product` (#853) · 241 `kg-literature-chrestomathy-pilot` (#856) · 369 `next-build-speed-benchmark` (#854) · 289 `batch-rebind-kg-concepts-all-themes` (#852) · 376 `guard-expect-value-or-502` (#844) · 345 `lesson-builder-gen-lesson-indicators` (#851) · 362 `theme-indicator-gen-module-scope` (#850) · 365 `course-page-intermittent-crash` (#849) · 370 `kg-subject-create-editor-role` (#842) · 371 `lesson-builder-goal-static-mock` (#843) · 372 `mentor-dashboard-greeting-static-name` (#845) · 374 `theme-kg-binding-always-editable` (#841) · 378 `consent-version-pin` (#846)
- міграції
- —
- PR
- - Кодові (лейбл `build`): #841 · #842 · #843 · #844 · #845 · #846 (хвиля 1a), #849 · #850 · #851 · #852 · #853 · #854 (хвиля 1b) - Доки/інфра: #826 · #827 · #828 · #829 · #830 · #832 · #833 · #834 · #835 · #836 · #837 · #838 · #839 · #840 - Bookkeeping: #847 · #848 · #855 · #856 · #857 · #858 · #859
- ризики
- Юр-документи (нода 377, критична Б): /privacy і /terms тепер містять копії реальних документів + реквізити ТОВ; контент — статичний у фронта.
- Прод-дані не зачіпаються (міграцій немає; backend-зміни — тести + eval_scorer/auth guard-и ноди 376).
- Реліз широкий за складом (13 нод + bookkeeping): кодові частини підтверджені CI на власних PR; фінальний доказ — CI реліз-PR + deploy-smoke.
- Поза релізом: нода 375 (канон shell-форматування) — status open; черга ланок наступних хвиль (class-mechanics wave1, editor P0, …) — див. `roadmap_status` / актуальний хендовер.
джерела: specs_concept/changelog/2026-09-01.md CHANGELOG.md
v2026-08-31 — Технічний реліз: надійніший процес випуску оновлень
- Що змінилося всередині:
- Випуск оновлень тепер перевіряється автоматично: перед випуском і після нього реліз проходить машинну перевірку (відповідність гілок, звіт змін, статуси збірок, наявність тега версії). Це захищає від ситуацій, коли оновлення виходить «мовчки» — без запущених перевірок або без запису у звіті змін.
- Сторінка «Історія релізів» (для команди) показує всі випущені оновлення: раніше в списку могли бути відсутні останні два релізи — тепер сторінка оновлюється разом із кожним випуском.
- Впорядковано внутрішній реєстр рішень: відновлено відсутні оцінки запропонованих рішень у машинному реєстрі рефлексій.
Третій реліз за дві доби, після v2026-08-30: **22 коміти** за діапазон main..stage — повністю docs/scripts/bookkeeping, **без коду backend і без коду frontend** (крім згенерованих файлів `changelog.json` / `wiring-registry.json`): bookkeeping R2 (ноди 353/358 → done у графі; PR #817), рефлексія серії L2 30.08 (аналіз 353+358), реген `generated/changelog.json` з релізами v2026-08-29/30 (інцидент 30.08: `/dev/changelog` на проді не показував останні два релізи; нода 352), fix `reflection_registry.mjs` (`--update` зберігає `score_ai` + `--restore-scores`; відновлено 66 `score_ai` з verdicts.json, інцидент стирання 30.08), новий машинний гейт релізів `scripts/release_checklist.sh` (аудит 30.08, P1-4/P1-5), консолідація спільної рефлексії 29.08 (#802: digest + inventory), MILESTONES-розділи релізів 24–29 (аудит 30.08: були пропущені), доки реліз-процесу (#819/#820: частота = готовий код, verify-запис, hotfix-шлях). **Міграцій у релізі немає** — schema-only і data-bearing відсутні; `backend/**` не чіпається, прод-дані не зачіпаються. CI: на stage-мерджах діапазону важкі гейти не ганялись (docs/scripts PR без лейбла `build` — політика CI-бюджету; перевірено: CI-ранів на head stage немає). Реліз-PR stage→main отримує лейбл `build` → frontend-воркфлоу запуститься реально (диф чіпає `frontend_next/**` і `scripts/**`: wiring_registry --check, roadmap_graph_check, i18n_keys, typecheck, vitest, next build, route_drift); backend-воркфлоу пропустить за paths-фільтром (`backend/**` не чіпається — допустимо за release_checklist.sh).
- ноди
- 352 `dev-changelog-page` (#821) · 353 `course-tree-scanner-debt` (#814 (evidence), #817 (bookkeeping R2)) · 358 `course-structure-edit-version` (#815 (evidence), #817 (bookkeeping R2))
- міграції
- —
- PR
- - #817 (bookkeeping R2) - #819 · #820 · #821 (docs / changelog-json) - #822 (reflection-registry fix) - #802 (консолідація рефлексії 29.08) - evidence: #814/#815 (ланки 353/358; код релізнуто у v2026-08-30)
- ризики
- Єдиний доказ stage-мерджів діапазону — локальна верифікація: важкі гейти не ганялись (docs/scripts без лейбла `build` — CI-бюджет). Реліз-PR отримає лейбл `build` → frontend-гейт на фінальній голові; стан прода після мержу доведе лише `deploy-smoke`.
- `reflections.json` — реген із відновленням 66 `score_ai` (дані реєстру в репо, не прод-БД); відновлення звірено з verdicts.json.
- Прод-дані не зачіпаються (міграцій і backend-коду немає).
- Поза релізом: черга ланок 30.08 (нода 320 Ступінь 2 — 99 моків, course-structure-llm #722, verdicts рефлексії чекають рев'ю); відкритих PR у stage на момент написання немає (перевірено 31.08).
джерела: specs_concept/changelog/2026-08-31.md CHANGELOG.md
v2026-08-30 — Аналітика класу для вчителя та серія виправлень за інтейком
- Що змінилося для вчителів:
- Аналітика класу: зі списку класів можна перейти в «Аналітику класу» — 4 розділи на реальних даних: карта навичок класу, відсоток помилок, індикатори без доказів та ефективність ремедіацій. Можна перемикатися між класами.
- Підключення предмета до класу: у блоці «Вчителі предметів» з'явилась форма «Підключити предмет».
- Конструктор уроків: ручно створений блок одразу називається «Крок N» (раніше — без назви).
- Згенерована структура курсу: модулі та теми, згенеровані планом курсу, можна перейменувати або видалити прямо в структурі (раніше — лише перегенерація).
- Плеєр учня: у завдань з короткою, довгою чи числовою відповіддю з'явилось поле вводу відповіді (раніше його не було).
- Перегляд завдань: згенероване завдання можна переглянути одразу з екрана теми; повернуто кнопку «Подивитися на контрольну точку».
- Адмін-розклад: порожній стан тепер підказує, що робити далі.
- Що змінилося для батьків:
- Реєстрація: форма реєстрації пропонує роль «Батько/мати».
- Що змінилося для методистів:
- Перевірка генератора структури курсу: course-structure більше не показує бейдж «не перевірено» — додано смоук-перевірку реальної генерації; механіку Gap-Report задокументовано.
Другий реліз за дві доби: **53 коміти** за діапазон main..stage (з v2026-08-29). Шість робочих ланок 30.08: **intake30-fe-bugs** (355/357/363/364), **intake28-fe-bugs** (347/351/356), **course-structure-service** (359/361; 350 — already-done), **class-analytics** (174, tier full), **course-tree-scanner-debt** (353, рефакторинг), **course-structure-edit-version** (358, редгування згенерованої структури) — плюс bookkeeping R1 (рефлексія-реєстр, пакет роадмап-рев'ю 30.08, інтейк 30.08 у графі, IMPORT_STAMP-фікс, планувальні ноди 366–368 у граф (PR #805)). **Міграцій у релізі немає** — schema-only і data-bearing відсутні. CI: важкі гейти на lane-мерджах НЕ ганялись (рішення 30.08 — без лейбла `build` для FE-багів без міграцій; економія CI-бюджету). Єдиний доказ — локальна верифікація в worktree-ланках: pytest на per-lane PG (174: 1096 passed, 2 skipped, `test_class_analytics.py`), vitest (174: 26; 355/357/363/364: class-roster SubjectTeachers 13 + admin-cab-classes 11 + auth 16 + course-tree 15; 347/351/356: 54 файли / 379 тестів), `tsc --noEmit` + `next build` (Node 24). PR #809 (359/361) мав лейбл `build` (диф чіпає backend) — важкий гейт на його голові green. Реліз-PR stage→main отримує лейбл `build` → важкі гейти на фінальному голові.
- ноди
- 174 `class-analytics` (#810) · 355 `class-subject-link-ui` (#807) · 356 `schedule-empty-state-pointer` (#808) · 357 `parent-self-signup` (#807) · 359 `course-structure-generator-smoke` (#809) · 361 `gap-report-explanation` (#809) · 363 `view-generated-task-from-theme` (#807) · 364 `checkpoint-view-button` (#807) · 353 `course-tree-scanner-debt` (lane-мердж `85e8e056`) · 358 `course-structure-edit-version` (lane-мердж `c6bc36a1`)
- міграції
- —
- PR
- #807 #808 #809 #810 (lane-мерджі хвилі R1) · lane-мерджі #353 (`85e8e056`) і #358 (`c6bc36a1`) · #806 #805 #804 #803 #801 #800 #799 #798 #795 (рефлексія-реєстр, роадмап-рев'ю, інтейки, планувальні ноди 366–368, хендовер-консолідації, mock-routes reinventory 29.08)
- ризики
- Єдиний доказ lane-мерджів — локальна верифікація (без `build`-лейбла важкі гейти не ганялись). Реліз-PR отримає лейбл `build`; стан прода після мержу доведе лише `deploy-smoke`.
- Bookkeeping 353/358 (graph.json → done) не завершено — мерджі ланок є, статуси нод оновляться bookkeeping-комітом R2 (evidence = lane-мерджі).
- Поза релізом — відкриті PR у stage: #802 (спільна рефлексія 29.08, консолідація 6 сесій), #796 (milestones-розділ релізу v2026-08-29). Підуть наступним релізом. (PR #805 змерджено — планувальні ноди 366–368 presence-audit / mock-routes-cleanup / student-ai-mentor увійшли в граф, статуси open, релізного коду не несуть.)
- Чекає рішень користувача: нода 320 Ступінь 2 — 99 моків (remove 24 · implement 2 · deactivate 73); черга ланок: #722 course-structure-llm; verdicts рефлексія-реєстру чекають рев'ю.
- Прод-дані не зачіпались (міграцій немає); class-analytics читає існуючі таблиці (attempts/learner_progress) — синтаксис перевірено тестами на PG.
джерела: specs_concept/changelog/2026-08-30.md CHANGELOG.md
v2026-08-29 — Батьківський кабінет, адмін-кабінет і корзина предметів
- Що змінилося для вчителів:
- Корзина предметів: предмет можна архівувати замість остаточного видалення — він зникає зі списків, але зберігається разом з уроками і даними учнів. Архів можна переглянути, відновити предмет або очистити корзину повністю.
- Захист від втрати даних при видаленні: якщо у предмета є активність учнів (спроби, прогрес), видалити його не вийде — система попередить. Кнопка видалення також прихована для похідних редакторів курсу (той, хто не автор, курс не видаляє).
- Переведення учня між класами: у списку учнів з'явилась дія «Перевести» — учень переноситься з одного класу в інший без втрати історії.
- Вибір уроку з курсів класу: при створенні призначень можна обрати урок з уже опублікованих курсів класу, а не тільки створювати новий.
- Підказки для вчителів: у полі вибору вчителя-предметника з'явилась підказка «оберіть учителя зі списку».
- Дрібні виправлення: таб-бар у профілі учня більше не затіняє кнопку «Вийти», коректна валідація класу навчання, попередній перегляд завдань з відкритою відповіддю.
- Що змінилося для батьків:
- Новий батьківський кабінет: головна сторінка з оглядом, сімейний профіль зі списком дітей і перемикачем між ними.
- Розклад і зустрічі дитини: живі live-зустрічі дитини з деталями кожної зустрічі.
- Домашні завдання дитини: всі домашні завдання класів дитини в одному місці.
- Аналітика і звіти: прогрес дитини за 30 днів (майстерність, динаміка), звіти з детальною сторінкою кожного звіту.
- Онбординг: реальні кроки запрошення дитини (інвайт → прив'язка → про дитину → план навчання) замість демо-екранів.
- Що змінилося для адміністраторів:
- Запрошення вчителів і методистів: форма запрошення з вибором ролі (учитель / методист / адміністратор) замість ручного створення.
- Налаштування і ролі: сторінка налаштувань з матрицею ролей — 5 мок-фіч переведено на реальні дані.
- Аналітика: реальні дашборд, сторінка деталей і експорт замість статичних заглушок.
- Деталі каталогів: учні, зараховані, ментори, ємність, батьки, родини — з реальними даними.
- Огляд конструктора курсів: read-only огляд курсів, структури, уроків і програм.
- Розклад призначень: список призначень з тижневою сіткою.
- Роль-каталоги: списки учнів/менторів/батьків через один екран користувачів з роль-пресетами.
- Чистіший інтерфейс: з меню прибрано розділи, яких ще немає (пошук, сповіщення, оголошення, білінг, підтримка).
- Що змінилося для методистів:
- Трасування версії промпта: на згенерованому контенті записується, яка саме ефективна версія промпта реально пішла в генерацію — можна простежити, чим згенеровано кожен результат.
- Вимір типу завдання в golden-наборі: кейси оцінки можуть задавати тип завдання (всі 13 типів), а не лише single_choice.
- Порівняння версій промпта: side-by-side диф-панель двох версій у промпт-лаб.
- План курсу через LLM: course-structure будується у два ходи (чернетка + фіналізація) з кроком майстра дір.
- Технічне:
- Сторінка /dev/changelog: реліз-ченджлоги задеплоєного стану доступні на сайті для команди.
Найбільший реліз сезону: **322 коміти, ~78 мерджів** за діапазон main..stage (з v2026-08-28). Три великі серії: **admin-cabinet** (8 нод, хвиля 29.08), **parent-cabinet** (ноди 335/336/337/338/342/344 + віха 41), **механіка класу і предметів** (269 trash-bin, 322/323 delete-guards, 312/317/316 UI) — плюс промпт-лаб продовження (300/305/307/319/321), фікси ai-gen (287/272/267), оркестратор-тулзи (324/325), інвентаризація моків (320/326) і 352 dev-changelog. CI: важкі гейти `success` на змерджених PR-головах (785/789/783/ 790 — frontend і/або backend за paths); verify на ont_preview зелений (логін обох ролей + реальні GET, у т.ч. нові parent-ендпойнти; FE /dev/changelog 200). Міграцій — 2, обидві schema-only; data-bearing у релізі немає (296/297 уже в main з минулого релізу).
- ноди
- 269 `subject-trash-bin` (#785) · 322 `subject-delete-student-data-guard` (#781) · 323 `subject-delete-fe-hide-button` (#781) · 336 `parent-analytics-reports` (#783) · 337 `parent-schedule-homework` (#782) · 338 `parent-family-profile` (#771) · 335 `parent-dashboard-home` (#775) · 342 `parent-onboarding` (#790) · 344 `parent-hide-extra` (#760) · 41 `parent-cabinet` (#791) · 330 `admin-analytics-real` (#769) · 333 `admin-settings-roles` (#773) · 334 `admin-invite-form` (#776) · 329 `admin-catalog-details` (#763) · 332 `admin-courses-overview` (#759) · 331 `admin-schedule-list` (#758) · 327 `admin-hide-domains` (#749) · 328 `admin-catalogs-role-views` (#747) · 312 `student-transfer-fe-ui` (#751) · 317 `base-course-fe-lesson-picker` (#751) · 316 `teacher-assignments-fe-ui-ux-hint` (#751) · 309/311/284/285 (#746) · 286/310/252 (#742) · 300 `course-structure-llm` (#722) · 305 `prompt-version-trace` (#770) · 319 `task-type-eval-dimension` (#764) · 307/321 `prompt-lab-side-by-side` + `course-structure-finalize-persist-plan` (#772) · 315 `base-course-derived-delete-governance` (#713) · 287/272/267 (#756) · 324/325 `orchestrator-tools` (#774, #733) · 320/326 `mock-routes-reinventory` + `mock-routes-visual-overlay` (#728, #737, #786) · 352 `dev-changelog-page` (#789)
- міграції
- `b8a9c0d1e2f3_node305_effective_prompt_version.py` — schema-only: nullable `ai_gen_tasks.effective_prompt_version_id`; data-guard N/A (ADD COLUMN, наявні рядки лишаються NULL). `d9e0f1a2b3c4_eval_cases_task_type.py` — schema-only: nullable `eval_cases.task_type` без server_default/CHECK (валідує API); backfill не потрібен. Решта 57 файлів міграцій у діапазоні — косметичний ruff-формат (revision-IDs і ланцюг незмінні; #733 канонізація). `alembic heads` = 1 (`b8a9c0d1e2f3`), ланцюг лінійний, розгалужень немає.
- PR
- Мерджі у діапазоні (#720–#792, 73 PR): `#720` `#721` `#722` `#723` `#724` `#725` `#726` `#727` `#728` `#729` `#730` `#731` `#732` `#733` `#734` `#735` `#736` `#737` `#738` `#739` `#740` `#741` `#742` `#743` `#744` `#745` `#746` `#747` `#748` `#749` `#750` `#751` `#752` `#753` `#754` `#755` `#756` `#757` `#758` `#759` `#760` `#761` `#762` `#763` `#764` `#765` `#766` `#767` `#768` `#769` `#770` `#771` `#772` `#773` `#774` `#775` `#776` `#777` `#778` `#779` `#780` `#781` `#782` `#783` `#784` `#785` `#786` `#787` `#788` `#789` `#790` `#791` `#792`. Кодові (лейбл `build`): #785 #781 #782 #776 #773 #769 #774 #775 #772 #771 #770 #763 #764 #760 #756 #759 #758 #751 #749 #747 #746 #742 #733 #732 #731 #729 #727 #722 #724 #713 #783 #790 #789. Доки/рефлексії/bookkeeping: #720 #721 #723 #725 #726 #728 #730 #734 #735 #736 #737 #738 #739 #740 #741 #743 #744 #745 #748 #750 #752 #753 #754 #755 #757 #761 #762 #765 #766 #767 #768 #777 #778 #779 #780 #784 #786 #787 #788 #791 #792.
- ризики
- CI-доказ по змерджених PR: важкі гейти `success` на головах #785 (backend+frontend), #789 (frontend), #783 (backend+frontend), #790 (frontend; backend — paths-filter, зміна FE-only). Ранів на сам merge-коміт stage немає (тригер `pull_request`) — це норма канону, не деградація.
- Preview-verify: логін teacher+parent, реальні GET (lessons/modules/classes з type/grade/students-assignments/subjects, parent children/schedule/homework/analytics/reports — 404 на неіснуючого child = роутинг ок), FE /dev/changelog 200 з реальними версіями. Parent-акаунт без прив'язаних дітей — дитя-скоупні дані піксельно не перевірялись на preview (покрито vision-чеком #783 і pytest).
- 357/322: найбільший діапазон сезону — більшість PR docs/design/bookkeeping; кодові — перелічені вище. Серійний ризик — деплой 1 релізом замість 3; деградація непомічена — мінімізована schema-only міграціями і verify по нових ендпойнтах.
- #783 vision-блокери: в-скоуповий (заливка progress-барів) виправлено до мержу (e6895e56); позаскоуповий (сирі ключі ai.roles.parent на 4 екранах, AiAssistant whitelist) — відкритий дефект батьківського кабінету, потребує окремої ноди; у релізі видно як нелокалізовані чипи в AI-rail.
- #789 (352): PR перебазовано під час рев'ю (стара гілка тягнула дублі 269 — виправлено rebase --onto, диф 7 файлів, checker підтвердив); ніт N1 (коментар про механізм даних) виправлено в #792.
- 315: delete лише автору — поведінкова зміна для похідних редакторів; 403 залишається fallback на BE (FE ховає кнопку).
- 322: 409 на delete предмета зі student-активністю — це by design, але вчитель не має UI-підказки «чому не можна видалити» (лише кількість записів у відповіді).
джерела: specs_concept/changelog/2026-08-29.md CHANGELOG.md
v2026-08-28 — Промпт-лаб: список промптів і окрема сторінка промпта
- Що змінилося для методистів:
- Промпт-лаб стала наочнішою: замість однієї довгої сторінки зі всіма промптами тепер список — один рядок на промпт (генератор · тип · стан · кількість версій). Клік по рядку відкриває сторінку самого промпта з усіма його версіями та налаштуваннями.
- Пошук по промптах: над списком є автопошук — можна знайти потрібний промпт за текстом (генератор, тип, стан) без прокрутки довгої сторінки.
- Золотий набір — на сторінці промпта: кейси оцінки для генератора завдань тепер живуть на сторінці самого промпта, там же, де його версії.
Промпт-лаб: index→detail — список промптів з автопошуком + окрема сторінка промпта (UX-рев'ю користувача 27.08 після релізу v2026-08-27-2). Діапазон 37 комітів; міграцій немає (alembic heads = 1: `a297b4c5d6e7`, з релізу 27.08-1; `backend/` у діапазоні не змінювався взагалі). CI: frontend success на PR-голові #711 (fb860906); backend-PR-ів у діапазоні немає — `backend/**` не чіпається жодним кодовим комітом. Verify на ont_preview: BE login + `/api/auth/me`, `/api/lessons`, `/api/modules` = 200; FE version sha = 1705d5e8 (останній кодовий коміт stage; наступні #714–#717 — Dockerfile + docs, Vercel ignored-build відфільтрував).
- ноди
- `mentor-ai-settings-index-detail` (#711)
- міграції
- —
- PR
- #690 (мета-оркестратор аудит), #693 (рефлексія golden-set), #706 (milestones 27.08-2), #707 (рефлексія релізу 27.08-2), #709 (нода index-detail doc), #711 (index-detail), #712 (рефлексія аудиту 28.08), #714 (dev-container python/ruff), #715 (bookkeeping index-detail), #716 (методисту: промпт-лаб guide), #717 (рефлексія index-detail)
- ризики
- FE-only зміна: список/деталь обирають стан з наявних `listPrompts()`/`getGeneratorContract()`; бекенд БЕЗ ЗМІН — серіалізаційні ризики відсутні за побудовою.
- Golden-набір переїхав зі списку на деталь `task_generator` — логіка D5 без змін, але звиклий методист знайде його на сторінці промпта (є інструкція від #716).
- Новий динамічний роут `/mentor/ai-settings/[generator]/[prompt_type]` зареєстрований у wiring-registry (`--check` зелений; 296→297 роутів).
джерела: specs_concept/changelog/2026-08-28.md CHANGELOG.md
v2026-08-27-2 — Золотий набір методиста і надійніша генерація завдань
- Що змінилося для методистів:
- Золотий набір у промпт-лаб: тепер можна створювати кейси оцінки (вхід, очікуваний результат, критерії) і проганяти версію промпта по всіх кейсах — результат по кожному кейсу видно окремо (✓/✕ із поясненням), тож якість промпта перевіряється до активації, а не «на живих класах».
- Конструктор кейсів замість JSON: кейс оцінки заповнюється через форму з готовими критеріями — вручну описувати структуру більше не треба.
- Збереження промпта без активації: нова кнопка «Зберегти (без активації)» — можна відкласти чернетку версії, порівняти прогоном і активувати, коли впевнені.
- Захист від «кривого» виходу промпта: перед активацією версія автоматично перевіряється — якщо модель повернула не той формат (наприклад, масив замість одного завдання), активація заблокується з чіткою причиною.
- Що змінилося для вчителів:
- Рідше «LLM не дав валідного завдання»: генерація завдань стала терпимішою до збоків ШІ-провайдера (повторна спроба при збої), а коли помилка справді провайдерна — повідомлення чесно показує причину, замість звинувачення промпта.
Golden-набір методиста (308+318) + надійність AI-генерації (304, 306) — промпт-лаб. Діапазон 43 коміти після релізу v2026-08-27 (PR #688); міграцій немає. CI: backend success на PR-головах #695/#698 (останній backend-код у діапазоні), frontend success на PR #694; коміти після #694 у stage — docs-only.
- ноди
- 308 `prompt-save-without-activate` (#694) · 318 `golden-set-methodist-ui` (#694) · 306 `prompt-contract-arity-gate` (#698) · 304 `task-gen-502-provider-masked` (#695)
- міграції
- —
- PR
- # 689 (roadmap 318/319) #691 (handover) #692 (рефлексія хв.3-4) #694 (golden-set 308+318) #695 (304 task-gen hardening) #697 (нода 300 design) #698 (306 arity-gate) #699 (bookkeeping хв.9) #700 (bookkeeping golden-set) #701 (рефлексія golden-set) #702 (нода 315 design) #703 (нода 300 glm-верифікація)
- ризики
- 304: tolerant parser зменшує частку 502, але retry з cache_bust додає latency при інтермітенті провайдера; чесні провайдерні помилки (статус + текст) тепер видно методисту — це зміна повідомлень, не контракту API.
- 306: arity-gate блокує активацію (409) для версій, чий вихід не нормативний; покрито тестами на 7 генераторах (звірені з фактичними парсерами). Усі діючі активні версії пройшли гейт при деплої (кейс активного прод-стану не змінювався — гейт лише на activate).
- 318/308: golden-набір — FE-only зміна (mentor-ai-settings); diverged-стан скидається при новому прогоні; людський fallback у harvest-списку (без UUID).
- 297 delete-governance — follow-up: рішення не ухвалене, нода 315 підготовлена як інфобаза (design.md, дельти варіантів) — код не чіпається.
- 300 course-structure-llm — імплементація попереду (post-plan), у релізі лише затверджений дизайн.
джерела: specs_concept/changelog/2026-08-27-2.md CHANGELOG.md
v2026-08-27 — Призначення вчителів і базові курси класу
- Що змінилося для адміністраторів:
- Призначення вчителя на клас/групу з адмінки: у картці класу з'явився блок «Вчителі предметів» — видно, хто веде кожен предмет у класі, і можна призначити або замінити вчителя. Історія призначень зберігається, оцінки учнів не зачіпаються.
- Базові курси: можна створити базовий курс (наприклад, «Математика 7») і призначити його класу чи групі.
- Що змінилося для вчителів:
- Уроки базового курсу класу: вчитель, якому клас призначений, отримує доступ до матеріалів призначеного курсу і може призначати звідти уроки учням. Вчитель без призначення до класу курс не бачить.
- Заміна вчителя не ламає роботу класу: тепер, хто веде предмет у класі, визначається окремим призначенням (раніше — лише тим, хто створив предмет); призначення можна змінити, не передаючи «власність» на матеріали.
Механіка класу, хвилі 3–4 (296/297/313/314) + bookkeeping/процес. CI: обидва воркфлоу (backend + frontend) — pass на release-PR (`stage → main`); реліз покриває CI-заборгованість 293 (застряглий queued-ран #658 закрито зеленим прогоном на змердженому стані, аналогічно релізу 26.08-3).
- ноди
- 296 `teacher-assignments` (#676) · 297 `base-course` (#679) · 313 `teacher-assignments-fe-ui` (#678 + #680 (фікс нітів 1-2: lazy teacherSearch, єдиний фетч)) · 314 `teacher-assignments-phantom-validation` (#682)
- міграції
- backend/alembic/versions/a296b4c5d6e7_node296_teacher_assignments.py — data-bearing: таблиця `teacher_assignments` + partial unique (class_id, subject_id) WHERE ended_at IS NULL + backfill із class_subjects.teacher_id (1:1, id=class_subjects.id); data-guard abort для NULL teacher_id. Прод: no-op (аудит 26.08: class_subjects = 0 рядків; abort-список порожній). backend/alembic/versions/a297b4c5d6e7_node297_base_course.py — data-bearing: таблиці `base_courses` + `class_courses` + колонка `subjects.base_course_id` (nullable FK); backfill-класифікація Subject за title-ключем (`^[A-Za-z]{2,}[\s-]*\d{1,2}$`), data-guard abort на grade-неузгодженості (ключ ≠ subjects.grade), owner_id НЕ затирається. Прод: no-op (аудит 26.08: 30 subject без кандидатів у базові курси; abort-список порожній).
- PR
- # 674 (bookkeeping хв.2: 293/294 done, рефлексія, ноди 309–312) #675 (milestones) #676 (296) #677 (296 done + ноди 313/314) #678 (313) #679 (297) #680 (фікс 313) #681 (297/313 done + ноди 315/316) #682 (314) #683 (314 done + хендовер) #684 (ox-alpha → glm-5.3-flash) #685 (implementer → glm-5.3-flash) #686 (handover)
- ризики
- 296: `class_subjects.teacher_id` лишається deprecated (читання переключено; «не рвати схему»). Ніти checker'а (застарілі коментарі ClassSubject.teacher_id у models.py/FE; `started_at String(32)` vs `ended_at DateTime`; повторний POST не ідемпотентний) — задокументовані, нод нема (косметика/відкладено).
- 297: delete-семантика похідного редактора — вчитель класу C отримує edit+delete на ВСІ Subject базових курсів, призначених C (class-scoped, by design Q2 «основний редактор»), з каскадом delete-orphan modules/tasks → follow-up нода 315 (рішення PO: обмежити delete або підтвердити намір).
- 313: ніт 3 (UX-підказка вільного email у SubjectTeachers) → нода 316.
- FE-вибір уроку з курсів класу (base-course lesson-picker): не в релізі — нода 317 (провал 297→313; частково покрито 295 через похідний доступ).
- Провайдери субагентів: `stealth/ox-alpha` закрито (модель sunset, була ZAI GLM-5.3 Flash) → `openrouter/z-ai/glm-5.3-flash` (та сама модель) для другого checker'а і implementer'а (рішення користувача 27.08; процес, не код).
- 298 individual-assignments — свідомо deferred (П/beyond); 283 розклад-сутність — аналіз done.
джерела: specs_concept/changelog/2026-08-27.md CHANGELOG.md
v2026-08-26-3 — Переведення учнів і навчальні групи
- Що змінилося для вчителів:
- Переведення учня між класами працює: вчитель обирає учня і переводить його в інший клас або групу — учень зникає зі старого списку й одразу з'являється в новому, а переведення фіксується в журналі дій.
- Створення навчальних груп учителем: тепер можна створити групу (предметну, корекційну чи для НМТ), обрати предмет і клас навчання (1–12) і додати учнів — з автопідказкою при вводі імені учня.
- Типи класів: клас тепер має тип (основний клас / група) і клас навчання (наприклад, 7) — видно, для якого року навчання створена група.
- Що змінилося для методистів:
- З'явилася промпт-лабораторія: можна перевірити якість генерації завдань AI на контрольному наборі прикладів, порівняти версії промптів і повідомити про проблему з генерацією прямо з форми завдання.
Механіка класу (293/294) + промпт-лабораторія (299–303). CI: обидва воркфлоу (backend + frontend) — pass на release-PR (`stage → main`). Реліз з недоказаним CI на проміжному head #658 (queued-ран, інфра-збій Actions) — доведено свіжим прогоном на змердженому стані.
- ноди
- 293 `student-transfer` (#658) · 294 `teacher-groups` (#659) · 299 `ai-prompt-lab-evals-backend` (#661) · 301 `ai-prompt-lab-smoke-gate` (#661) · 302 `ai-prompt-lab-ui` (#661) · 303 `ai-prompt-lab-seed-verify` (#661)
- міграції
- backend/alembic/versions/abcd1234ef56_node293_audit_detail.py — schema-only: nullable `audit_log.detail` (512) для JSON-деталі transfer (target_class_id + обидва class_id). Data-guard непотрібен (ADD nullable-колонки). backend/alembic/versions/b3c4d5e6f7a8_node299_eval_cases.py — schema-only: таблиця `eval_cases` (+meta-approved `task_id` provenance) + індекси (task_id, created_by, generator_enabled). backend/alembic/versions/d7e8f9a0b1c2_node301_prompt_smoke_gate.py — schema-only: nullable `last_smoke_*` на `prompts` (verdict/at/detail). Data-bearing міграцій (296/297) у релізі НЕМАЄ — вони не змерджені.
- PR
- # 671 (trigger-run, docs — hello.txt) #669 #670 #668 #666 #667 #658 #665 #664 #661 #659 #663
- ризики
- CI-блокер на проміжному head: PR #658 змерджено з CI-раном `queued` (ніколи не стартував, 15:27→19:2x, `conclusion: null`; попередній head — `startup_failure` інфра-збій Actions). Скасувати не вдалось (PAT без `actions:write`, UI теж). Доказ змердженого стану — свіжий прогон release-PR (#672): обидва воркфлоу `pass` на head `80c46667`.
- Зомбі-ран `32985191383` (backend, queued) висить у черзі Actions — не блокує нові рани (concurrency за `github.ref`).
- 293: transfer не валідує target_class_id на належність учителю в межах атомарного апдейту — 404 на неіснуючий клас, 403/422 на чужий (перевірено тестами PG).
- 294: gate «учень — мій» через ClassSubject-видимість; subject_id обов'язковий (предмет учителя, `Subject.owner_id`).
- Промпт-лаб: YAML-снапшот golden-набору закомічений, але не авто-комітиться з UI; harvest-candidates — read-only SELECT по прод-БД (13 кейсів).
джерела: specs_concept/changelog/2026-08-26-3.md CHANGELOG.md
v2026-08-26-2 — Полагоджено генерацію завдань
- Що змінилося для вчителів:
- Генерація завдань за допомогою AI знову працює: помилка «Не згенерувалося: LLM не дав валідного завдання» виникала через зіпсований системний промпт — тепер завдання (у тому числі «Кілька виборів» і «Один варіант») генеруються з варіантами відповідей, фідбеком і підказками.
- Текст помилки при збої генерації став інформативнішим: видно конкретну причину, а не загальне повідомлення.
Інтейк 26.08: прод-баг генерації завдань (нода 304). Корінь знайдено відтворенням на копії прод-БД: override-промпт task_generator вимагав JSON-масив із ~10 завдань, тоді як парсер приймає РІВНО один об'єкт → 502 «LLM не дав валідного завдання» щоразу. CI: backend success; `deploy-smoke` — після реліз-мержу.
- ноди
- 304 `task-gen-502-provider-masked` (#651 #652 #653 #655 (roadmap) + #657 (код))
- міграції
- —
- PR
- Код: #657 · Доки/roadmap/репрод: #651 #652 #653 #654 #655 #656.
- ризики
- Інтермітент LLM (~1/8 у замірі): невалідний draft для choice-типів досі дає 502 з одного разу — ретраї не реалізовані (залишок ноди 304).
- Провайдерні помилки (400/402/429 після ретраїв) маскуються під «невалідний вихід» — чесна поверхня помилок ще не реалізована (залишок ноди 304).
- Пріекзистинг-флейк `test_task_preview_check::test_check_correct_and_incorrect` («no such table: attempts») на чистому stage — не пов'язаний із цим релізом.
джерела: specs_concept/changelog/2026-08-26-2.md CHANGELOG.md
v2026-08-26 — Призначення уроків і «Мої завдання»
- Що змінилося для вчителів:
- У класі з'явилось призначення уроків: вчитель обирає урок і призначає його класу/групі; видно, кому й що призначено.
- Що змінилося для учнів:
- У кабінеті учня з'явився розділ «Мої завдання» — призначені вчителем уроки видно одразу, зі статусом виконання.
- Що змінилося для адміністраторів:
- У класах тепер є тип (основний клас / група) і клас навчання (напр. 7).
- Якість матеріалів:
- Теми курсів тепер прив'язані лише до релевантних понять графа знань — виправлено помилку, через яку AI-генерація могла давати індикатори по темах сусідніх розділів.
Інтейк 25–26.08: механіка класу (хвиля 1) + завершення ноди 288. CI: backend success; `deploy-smoke` — після реліз-мержу.
- ноди
- 295 `assignment-loop-fe` (#645, #646-суміжні) · 292 `class-type-grade` (#646) · 288 `kg-concepts-slice-bug` (завершення) (#633, #634, #637) · 299–303 `prompt-lab` (планувальні) (#642, #644)
- міграції
- `a92b7c3d5e1f` — schema-only: `classes.type` (NOT NULL, `server_default='main_class'` — ADD COLUMN із дефолтом, data-guard не потрібен) + `classes.grade` (nullable INTEGER).
- PR
- Код: #645 #646 #637 #634 #633 · Rescue: #638 · Доки/рефлексія: #635 #636 #639 #640 #641 #642 #643 #644 #619.
- ризики
- no-seed хвіст ~36 тем (переважно math/геометрія, фізика-9кл): прив'язки лишились старі до overrides — при перегенерації індикаторів можливий off-topic по них.
- Довідник: subject «Астрономія» досі `kg_slug='ukrmova'`; slug `geometry`; тестові subject-и — потрібне PO-рішення (ноди 289–291).
- Міграція `a92b7c3d5e1f` додає колонки без бекфілу — ризик низький; alembic head на проді має стати `a92b7c3d5e1f` після деплою (до цього був `e2d3c4b5a6f7`).
джерела: specs_concept/changelog/2026-08-26.md CHANGELOG.md
v2026-08-24-2 — Підручники: обробка переживає перезапуск сервісу
- Що змінилося для вчителів:
- Завантажений підручник тепер автоматично продовжує обробку після перезапуску сервісу (деплой/рестарт). Раніше обробка лишалась у стані «обробку перервано», і підручник не потрапляв у граф знань, доки вчитель не запускав її заново вручну.
Другий реліз 24.08: фікс бага «підручник не додається до графа» (нода 270) + процесні зміни (ченджлог-механізм, рефлексії, chromium-фікс). CI: backend success (не skipped); deploy-smoke — після мержу реліз-PR.
- ноди
- 270 `book-ingest-job-interrupted` (#602)
- міграції
- —
- PR
- Код: #602 · Bookkeeping: #601 #603 · Процес/інфра: #597 #598 #599 #600.
- ризики
- `interrupted` лишається термінальним для РУЧНОГО переривання (`interrupt_pipeline`) і runtime-смерті підпроцесу (`_cleanup_stale_jobs`); auto-resume покриває лише рестарт бекенда. Якщо конвеєр падає сам (OOM) при живому веб-процесі — книжка й далі потребує ручного «Обробити».
- Друге повідомлення інтейку («сьогодні не можу завантажити») — імовірно 409 «книжка вже завантажена» від двох попередніх спроб; окремим дефектом не підтверджено.
- Фікс діє з НАСТУПНОГО деплою бекенда (resume виконується в lifespan при старті).
джерела: specs_concept/changelog/2026-08-24-2.md CHANGELOG.md
v2026-08-24 — Конструктор: завдання, практика, видалення курсу
- Що змінилося для вчителів:
- Завдання тепер можна прив'язувати до кількох індикаторів однієї теми (раніше — лише до одного); вибрані при AI-генерації індикатори зберігаються в завданні.
- AI-генерація завдань підтримує всі 13 типів — додано класифікацію, послідовності, пропуски, відповідність та інші.
- У перегляді «очима учня» завдання тепер можна розв'язати — є поле відповіді та перевірка (раніше — лише картка для перегляду).
- Видалення курсу працює — після підтвердження курс справді видаляється разом із модулями, темами, уроками та завданнями.
- Ручну тему можна прив'язати до понять графа знань прямо в панелі теми — після цього для неї працює генерація індикаторів.
- У чернетках видно тип уроку (концептуальний / тренувальний / практичний).
Хвилі 1+2 інтейку 24.08. CI: backend+frontend success (не skipped); `deploy-smoke` green.
- ноди
- 261 `task-form-indicator-preselect-scope` (#591) · 262 `task-ai-gen-type-coverage` (#591) · 263 `training-lesson-practice-non-interactive` (#590) · 264 `subject-delete-noop` (#595) · 265 `manual-theme-indicator-gen-fails` (#594) · 266 `theme-task-list-indicator-filter` (#591) · 268 `drafts-show-lesson-type` (#594)
- міграції
- `a9b8c7d6e5f4` — data-bearing: `tasks.indicator_ids` (JSON-список, NOT NULL `DEFAULT '[]'`), тотальний бекфіл `[indicator_id]`, без abort-шляху (dangling-tolerant). `e2d3c4b5a6f7` — schema-only: FK `ON DELETE CASCADE` ×6 (modules/tasks/error_catalog/rubrics/enrollments `.subject_id` + транзитивна `rubric_criteria.rubric_id`).
- PR
- Код: #590 #591 #594 #595 · Bookkeeping: #592 #596 · Інтейк/доки: #585–#589 · Реліз: #593.
- ризики
- `attempts.task_id/lesson_id`, `learner_progress.lesson_id`, `learner_mastery.indicator_id` — FK без `ondelete` → видалення опублікованого курсу зі студентською активністю досі дає FK-помилку. Зафіксовано в описі ноди 269 (purge має каскадити й ці таблиці).
- Інтерлок #564 (prompt-lab) — відкритий, чіпає `task_generator.py`; НЕ в цьому релізі, потребує rebase на новий stage.
джерела: specs_concept/changelog/2026-08-24.md CHANGELOG.md