Брифинг к внутренней встрече
Документ для разговора с Антоном (тимлид) и затем Иваном. Один документ — все факты, скрины, претензии, выводы. Открывать в IDE с Markdown preview (VS Code: ⌘+K V) или любом md-viewer'е, чтобы видеть скрины.
Содержание
- Письмо Alexis Watson (29.04.2026)
- PR #837 — ICUS-216 FAQ
- PR #842 — IX-SIT60 YouTube schema
- PR #832 — IX-SIT60 schema for pages
- PR #846 — IX-SIT67 update header ⚠️ упомянут в письме
- PR #847 — FAQPage hotfix ⚠️ упомянут в письме
- Системные паттерны
- Предложения процессных изменений
- План встречи
1. Письмо Alexis Watson (29.04.2026)
Дата: среда, 29 апреля 2026, 22:28 От: Alexis Watson (Stevens IT — клиент) Кому: Holubets Andrii (контрактор iX), Napper Tom (менеджер iX) Копия: Vincent, Michael Forbes, +2 (Stevens / iX)

4 ключевых тезиса
- Deviate from spec — "deliverables (such as the header) that deviate considerably from spec and require revisiting"
- Commit squashing — "on other occasions, such as PR #847, the use of commit squashing... can make minor adjustments very difficult to parse out if the branch has already been shared"
- Avoid rebasing after share — "we'd kindly ask to avoid rebasing after code is shared to preserve history"
- PRs with post-deployment tasks accompanied by such + предложение про smaller batches и internal validation pass
Прямо упомянуты: header (= PR #846) и PR #847. По остальному смотрим повторяющиеся паттерны через все PR.
2. PR #837 — ICUS-216 FAQPageJsonLd for Accordion
Branch: ICUS-216-faq · Status: ✅ Merged 2026-03-24 · Цикл: 11 дней
Спека: ICUS-214 — User Stories for FAQ Schema (PDF приложен Андреем 2026-03-11, 16:34 — за 2 дня до открытия PR)
Ключевая претензия #1 — Contentful environment (Bemin Shaker, 16.03)

"I noticed the content model change for this... was made in
masterrather thandevelop. Ideally, content model changes should never be made in the production environment before they are approved..."
Суть: новое поле "Enable FAQ Schema" внесено в prod-окружение Contentful (master) вместо develop. Контент-редакторы видят поле в проде, хотя фича ещё не задеплоена; non-master ветки смотрят на develop — там поля нет, тестировать нельзя.
Иван (17.03): "The fields were removed from the staging environment and moved to the development branch."
Ключевая претензия #2 — конфигурация поля не по спеке (Michael, 17.03)

"The code looks great, but the field configuration needs some adjustments to match the specs provided by Tom..."
Michael дословно цитирует acceptance criteria из ICUS-214:
- Field name:
Accordion Purpose - Type: Single select (Standard Content default / FAQ)
- Default = Standard Content
- FAQ schema only when = FAQ
- Help text: "Select FAQ only when content is a list of user-facing questions and answers"
Иван реализовал другое имя поля и Yes/No boolean-подобное → переделал по требованию Michael за 2 дня.
Что положительного в PR #837
- ✅ QA прошёл с первого раза во всех 3 сценариях (Yes/No/null) — отдельный коммент Michael
- ✅ "The code looks great" (Michael)
- ✅ Иван сделал merge, а не rebase, при подтягивании master → ветка
- ✅ Approved + Merged без дополнительных итераций после исправления
🔑 Главный вопрос Ивану по PR #837
Открывал ли parent ICUS-214 и приложенный PDF до старта работы?
- Если да — почему отступил от 5 acceptance criteria (имя поля, тип, опции, default, help text)?
- Если нет — почему не открывал parent при работе над сабтаском?
3. PR #842 — IX-SIT60 Add schema for YouTube
Status: OPEN на 2026-04-16, 16+ дней в работе Спека: ICUS-211 / ICUS-212 — Contentful App для YouTube publish date (обновлена 2026-03-12, за 19 дней до PR)
3.1. Debug console.log в коде (Michael, 31.03 — день открытия)

"This looks like a debugging line we wouldn't want merged into master."
Иван оставил console.log('Parsed video ID:', videoId). Лечится lint / pre-commit hook / 10-секундным самопросмотром diff'а.
3.2. 🚨 Pre-merge tasks отсутствуют → у Michael сломался build

"I tried merging this branch into
vercel-stage... but the build failed due toCannot query field "publishedAt" on type "Video". ...When other steps beyond just clicking the PR's Merge button are required to deploy a pull request, please mention the steps in the PR description."
PR не мог быть смержен — нужны были 2 шага в Contentful (deploy Stevens CMS Tools + merge field develop→master), но они не были описаны. Michael узнал через сломанный build.
🔑 Это прямой кейс из письма Alexis: "PRs that require post-deployment tasks are always accompanied by such"
3.3. Невалидный VideoObject — schema без uploadDate (Michael, 31.03)

"Michelle Strauss mentioned that this would be an invalid VideoObject. If that's true, we should not be outputting a VideoObject in this case, right?"
Schema выводилась даже без uploadDate → невалидный объект для Google rich results.
Иван: "I'll add a condition so that the schema isn't added if there's no upload date."
3.4. ~700 существующих entries в "Not synced yet" (Michael, 03.04)

"Can we offer something better, so that users won't have to go into nearly 700 existing Video entries..."
Реализация триггерится на изменение URL → существующие 700 видео-entries не синканы. Сообщение в UI вводит в заблуждение ("add a video URL" — а URL уже есть). Иван: предложил one-time backfill migration script, договорились добавить в codebase Stevens CMS Tools.
🔑 PR #842 — резюме
4 обоснованные претензии в одном PR. Прямая иллюстрация письма Alexis:
- "deviate from spec" — invalid VideoObject
- "post-deployment tasks accompanied" — pre-merge tasks отсутствовали
- "internal validation pass" —
console.log, нет миграции 700 entries - "smaller batches" — PR висит 16+ дней, охват: schema + Contentful field + CMS Tools + backfill
4. PR #832 — IX-SIT60 Add schema for pages
Status: OPEN 2+ месяца (21.02 → 24.04+), ≥27 коммитов в 9+ батчах REQUESTED CHANGES (Michael Forbes, 31.03)
4.1. 🚨 Alexis 23.02 — прямой запрос pre-deployment steps (за 2 месяца до письма!)

"@Ivan.Kotovsky @Anton Moskalenko and iCrossing: Are there any additional steps we need to take prior to deployment? This would include any changes to Contentful fields and the like."
Иван (24.02): "At this point, no additional steps are required before deployment."
🔑 КРИТИЧНО для встречи: Alexis уже 23.02 прямо попросил проверять pre-deployment steps. Alexis тегнул Антона напрямую. Через 5 недель (PR #842) ровно эта проблема повторилась. Письмо от 29.04 — не первый сигнал, а эскалация по повторяющемуся.
4.2. Повторение invalid VideoObject (Michael, 31.03 → REQUESTED CHANGES)

"I think Michelle Strauss mentioned that a VideoObject is invalid if it doesn't have an uploadDate property... we need to make sure that the new JSON-LD is clean."
Тот же Michael ловит ту же ошибку у Ивана в PR #832 и PR #842 в один день (31.03) — урок не закрепился между PR.
4.3. Undefined base URL уже на проде preview (Bemin, 08.04)

"The base URL is being returned as
undefined. So the full property is something like\"url\":\"undefined/profile/fkim\"as seen on this page."
Реальный функциональный баг — невалидные URL в schema.org объектах уже видны на preview. Self-QA не было.
4.4. Hardcoded values вместо существующих утилит (Bemin, 08.04)

"URL structure is subject to change, so we should not be hardcoding the
/news/prefix here. It's best to use thegetExternalPathfunction here."

"The Image Wrapper component has a
creditfield, so we probably should be using that here."
Иван не использовал getExternalPath и Image Wrapper.credit — хотя они уже есть в codebase. То же замечание повторяется в двух разных файлах одного PR (events и program).
🔑 PR #832 — резюме
- 9 значимых замечаний, 8 обоснованы.
- REQUESTED CHANGES — формальный блокер мержа.
- 2+ месяца, ≥27 коммитов — большой батч, прямая иллюстрация "smaller batches".
- Alexis прямо сигнализировал про pre-deployment steps 23.02 — Антон был тегнут.
5. PR #846 — IX-SIT67 update header
⚠️ Header упомянут в письме Alexis как пример "deviate from spec"
Status: OPEN на 2026-04-29
Спека: ICUS-220 — mockups v3.zip (16.04, 12:16 Warsaw, Андрей) + Site_Header_User_Stories_v2.docx (20.04, 14:24 Warsaw, Андрей)
PR открыт 2026-04-22 — после стабилизации спеки. Аргумент "спека менялась" — слабый.
5.1. "Info For" dropdown центрирован — сделано лишнее (Michael, 23.04)

"Personally I'm not opposed to the change, but was it specified? I don't see this in the mockup for this issue."
В мокапе слева, в реализации по центру. Иван сделал то, чего в спеке нет.
5.2. Меню в 2 строки на 1024–1091px — регрессия (Michael, 23.04)

"When the viewport width is between 1024px and 1091px, the menu items in the red bar take two lines of text..."
Регрессия от добавления search-кнопки. Тестируется RWD-режимом за 30 секунд.
5.3. 🚨 Text-only logo в expanded mobile menu — не реализован (Michael, 23.04)

"The specification shows that the expanded mobile menu should have a text-only Stevens logo in the top left corner... However, this is not yet implemented."
Это самый чёткий пример "deviate from spec": в мокапе v3 (приложен 16.04) явно text-only logo, в реализации — старый shield-logo. Иван просто не сделал.
5.4. CTA дублируются в mobile menu (Michael, 23.04)

"...need to be removed from this
<UtilityMenu>to avoid duplication."
Request Info / Visit / Apply показаны дважды — в верхней части (правильно) и в нижнем UtilityMenu (дубликат).
5.5. Dark mode — недостаточный контраст на жёлтых CTA (Michael, 23.04)

"When using dark mode (Chrome force-dark) there is insufficient contrast on the new yellow buttons."
Спека прямо требует WCAG AA (≥4.5:1). Не проверено. Иван: "I'm trying to find solution for this problem, in research" — не закрыто.
5.6. 4 search-проблемы в одном блоке (Michael, 23.04)

"4 issues with the search feature: serif font вместо IBM Plex Sans, иконка лупы белая на сером вместо тёмной на белом, лишний красный бордер, серый фон не L-shape а с дыркой."
4 параллельных стилистических расхождения в одном блоке → классический self-QA fail (мокап ↔ preview не сверены).
5.7. ✅ Sticky на 1024+ — спека была двусмысленной (Michael, 23.04)

"I was a little confused by the spec at first, but I asked the author of the spec, and he gave this clarification..."
🔑 В нашу пользу: сам Michael признаёт, что спека была неоднозначной и потребовала уточнения у автора. Один из 3 пробелов спеки в PR #846.
5.8. ✅ data-cta стабильность — agreement before implementation не был сделан (Michael)

"the person requesting this
data-ctaattribute has specified that the value be stable across such changes"
Иван реализовал data-cta точно по примерам из спеки (request-info, visit, apply). Спека сама требует "agreed by dev, analytics, and QA before implementation begins" — но agreement не было.
🔑 В нашу пользу: ещё один пробел спеки — pre-agreement не сделан на стороне клиента.
🔑 PR #846 — резюме
- 11 значимых замечаний за 8 дней.
- 8 — наши self-QA промахи (логотип, dropdown, регрессия, search-стилизация, дублирование, dark mode, sticky-фикс неполный).
- 3 — пробелы в спеке клиента (sticky 1024+, alignment magnifier/X, data-cta stability).
- Реактивность Ивана хорошая — фиксит на следующий день.
- Это и есть "header" из письма Alexis.
6. PR #847 — FAQPage hotfix
⚠️ Прямо упомянут в письме Alexis как пример commit squashing
Branch: ICUS-216-faq (переиспользована, по прямой рекомендации Michael Forbes)
Status: OPEN, активная работа на 2026-04-30
6.1. PR description — архитектурно правильное решение

Иван сделал page-level aggregation (один консолидированный FAQPage на URL) + добавил @id.
🔑 Это лучше, чем shortcut предлагал Michael ("just add @id, no need to merge"). Иван опроверг тезис "merge would be quite difficult". В нашу пользу.
6.2. bottomComponentsCollection пропущен (Bemin, 28.04)

"This doesn't take into account Right Nav and Program Detail pages which have
componentsCollectionANDbottomComponentsCollection. If an FAQ accordion is added in the full-width area, it would be excluded from the FAQPage object as a result."
PR description Ивана сам обещает покрыть right-nav / basic / chapter / program detail — но в коде gap. Декларация ≠ реализация.
6.3. 🚨🚨 Commit-after-approve schema (Michael, 28.04)

Иван закоммитил TODO в коде:
// const questions = isFaqAccordion(component) ? getAccordionQuestions(component) : []
// remove and uncomment const questions when approve PR
Michael:
"The sequence we use to ensure accurate approvals is {commit → approve → merge}, not {commit → approve → commit → merge}. What is the reason we need to make another change to the code after approving?"
🔑 🚨 САМАЯ СЕРЬЁЗНАЯ НАХОДКА ВО ВСЕЙ ИСТОРИИ.
Иван сознательно оставил placeholder с явным намерением изменить код после approve. Это:
- Не "недопонимание".
- Не "пробел спеки".
- Не "плохой английский".
Это прямое нарушение базового правила PR-workflow — approve привязан к коммиту. Если код меняется после approve — approve становится недействительным.
Хуже squashing'а по сути, потому что подрывает смысл approve, а не только читаемость истории.
6.4. NEXT_PUBLIC_SITE_URL dead fallback (Bemin, 29.04)

"
NEXT_PUBLIC_SITE_URLis not set as an environment variable, so wouldn'tprocess.env.NEXT_PUBLIC_SITE_URLalways be undefined?"
Dead fallback. Один grep по проекту перед открытием PR показал бы это.
🔑 PR #847 — резюме
- ✅ Архитектурно решение лучше shortcut'а Michael.
- ⚠️ 2 технических бага (bottom collection, dead env-var).
- 🚨 1 критическое процессное нарушение (commit-after-approve) — нельзя защитить.
- ⏳ Squashing — TBD на встрече с Иваном (открываем git log/reflog вместе).
7. Системные паттерны (сквозные через все 5 PR)
Сводная матрица претензий
| Категория | #837 | #842 | #832 | #846 | #847 |
|---|---|---|---|---|---|
| Невыполнение acceptance criteria приложенной спеки | ✅ | — | ✅ | ✅ | ✅ |
| Делает то, чего нет в спеке | — | — | — | ✅ | — |
| Невалидный schema.org объект (uploadDate) | — | ✅ | ✅ | — | — |
| Pre-merge / post-deployment tasks отсутствуют | — | ✅ | ✅ | — | — |
| Debug-код / dead code / лишние whitespace | — | ✅ | ✅ | — | ✅ |
| Незнание / неиспользование существующих утилит | — | — | ✅ | — | — |
| Функциональный баг на проде/preview | — | — | ✅ | — | — |
| Регрессия от собственных изменений | — | — | — | ✅ | — |
| Self-QA / responsive / accessibility пропуски | — | ✅ | ✅ | ✅ | ✅ |
| Contentful environment ошибки | ✅ | — | — | — | — |
| Неполный фикс после ревью | — | — | ✅ | ✅ | — |
| 🚨 Workflow violation (commit-after-approve) | — | — | — | — | ✅ |
| 🚨 Squashing на расшаренной ветке | подозр. | — | — | — | TBD |
Топ-5 повторяющихся паттернов
1. Невыполнение acceptance criteria приложенной спеки (4 из 5 PR)
- #837 — спека ICUS-214 в Jira за 2 дня до PR; реализация не по спеке.
- #832 — пропущен Minisite Right Nav из spec docs.
- #846 — text-only logo, search styling не реализованы (мокап v3 за 6 дней до PR).
- #847 —
bottomComponentsCollectionпропущен (Иван сам в description обещал покрытие).
2. Self-QA пропуски (5 из 5 PR)
Везде — недосверка с мокапом, не проверены responsive / dark mode / RWD-промежутки / env-vars / preview результат.
3. Невыученные уроки между PR
- VideoObject без uploadDate — поймано в #832 и #842 в один день 31.03.
- Pre-deployment steps — Alexis спрашивал 23.02 в #832, та же проблема в #842 через 5 недель.
4. Workflow дисциплина
- Commit-after-approve в #847.
- Подозрение на squashing в #837/#847.
- Language barrier в комментариях ревью (потеря циклов).
5. Размер батча и циклы
- #832 — 2+ месяца, 27+ коммитов.
- #846 — 11 issues за 2 недели.
- #842 — 16+ дней, охват: schema + Contentful + CMS Tools + backfill.
Распределение всех ~33 содержательных претензий по корневым причинам
- ~70% — наши self-QA / spec-discipline промахи.
- ~15% — workflow violations (squashing, commit-after-approve, отсутствие pre-merge tasks).
- ~10% — пробелы в спеке у клиента (3 случая в PR #846).
- ~5% — незнание codebase / абстракций.
Главный вывод: проблема процессная, не индивидуальная. Иван — реактивный, технически достаточный. Что отсутствует — дисциплина пред-выпускной проверки и формализованный workflow. Лечится за 1–2 итерации.
8. Предложения процессных изменений
A. Self-QA checklist (Иван — обязательно перед "Open PR")
- Spec sweep — открыт parent в Jira + все attachments; acceptance criteria сверены построчно с реализацией.
- Mockup overlay — preview ↔ мокап рядом; все состояния (default / sticky / hover / expanded / search open).
- Responsive — RWD-режим, ползунок ширины через все breakpoint'ы (между ними, не только на стандартных).
- Mobile menu / overlays / dropdowns — открыты вручную хотя бы раз.
- Dark mode / accessibility — Lighthouse / axe DevTools / contrast check.
- Code hygiene —
git diffглазами; нетconsole.log,// TODO when approve, dead fallback'ов;grepenv-vars подтверждает существование. - Schema/spec compliance — если выводится structured data → провалидировано через Rich Results / Fast Schema Analyzer.
- Existing data — если фича триггерится на новых данных → продумано, что с историческими.
B. PR description template (обязательные секции)
- Summary
- Changes
- Pre-merge tasks — что нужно сделать до merge
- Migration plan — что с существующими данными
- Validation done — какие тесты прогнаны, ссылки на preview-валидаторы
- Compare URLs (preview ↔ prod)
C. Workflow rules (свод)
- После первого
git pushветки — никаких rebase / force-push / squash локально. - Squash — только при финальном merge через UI (кнопка "Squash and merge").
- Никаких "TODO when approve" в коде. Если код не готов — Draft PR.
- После approve — изменения только с явным "please re-review".
- Branch reuse OK (как предложил Michael), но история не переписывается.
D. Spec-read checkpoint
Перед стартом задачи Иван пишет в Jira-комменте: "Read parent ICUS-X + attachments. Acceptance criteria: [список]. Questions: [если есть]." → Антон подтверждает.
E. Internal validation pass
Перед "Open PR на ревью Stevens" — Антон / Андрей делает 5-минутный pass по checklist'у выше. Если не сходится — возвращает Ивану.
F. Lessons learned log
После каждого замержённого PR Антон записывает 1–2 повторяемых замечания. Иван перечитывает перед стартом следующего.
G. Размер батча
PR не висит OPEN дольше 2 недель. Если затягивается — деление.
9. План встречи
Часть 1 — наедине с Антоном (~30 мин, без Ивана)
Цель: обсудить общую картину и системные выводы до разговора с Иваном.
- Контекст письма Alexis (5 мин)
- Сводка по 5 PR (10 мин) — пройти главы 2–6 этого документа, остановиться на самом тяжёлом (#832 + #847 + header)
- Ключевые вопросы Антону (10 мин) — открыть
meeting/questions-anton.md, пройти разделы A (история сигналов), B (self-QA), C (workflow) - Договориться о формате разговора с Иваном (5 мин) — что выносим жёстко, что мягче
Самое важное обсудить с Антоном до разговора с Иваном:
- Сигнал Alexis 23.02 (он тегнул Антона напрямую) — что было сделано в ответ?
- Commit-after-approve в #847 — это разовая ошибка или системный пробел понимания workflow у Ивана?
- Готовы ли мы к 7 процессным изменениям (раздел 8)?
- Тон ответа Stevens (после встречи).
Часть 2 — втроём (с Иваном) (~45 мин)
- Контекст письма (5 мин) — кратко переcказать
- PR #847 git-история (15 мин) — открываем Bitbucket вместе:
- merge strategy PR #837
- force-push'и в
ICUS-216-faq - локальный rebase/squash перед PR #847
- reflog
- PR #847 commit-after-approve (5 мин) — разобрать
meeting/questions-ivan.mdПриоритет 1 - PR #846 (header) self-QA (10 мин) — Приоритет 3
- Системные паттерны и предложения (10 мин) — раздел 7 + 8 этого документа, согласовать
К встрече иметь открытыми
- Этот документ (
meeting/briefing.md) — основной материал analysis/cross-pr-patterns.md— детальная сводкаmeeting/questions-anton.md+questions-ivan.md— приоритизированные вопросы- Bitbucket / Иван готов открыть локальный git
- Спеки:
claims/pr-837/spec/,claims/pr-846/spec/, ICUS-211/212 (вclaims/pr-842/spec/spec-content.md)
После встречи
- Заметки в
meeting/notes.md - Решения и план в
outcome/decisions.md - Только после этого — черновик ответа Stevens через Tom