Stevens / Ivan Issue Report

Брифинг к внутренней встрече

Документ для разговора с Антоном (тимлид) и затем Иваном. Один документ — все факты, скрины, претензии, выводы. Открывать в IDE с Markdown preview (VS Code: ⌘+K V) или любом md-viewer'е, чтобы видеть скрины.


Содержание

  1. Письмо Alexis Watson (29.04.2026)
  2. PR #837 — ICUS-216 FAQ
  3. PR #842 — IX-SIT60 YouTube schema
  4. PR #832 — IX-SIT60 schema for pages
  5. PR #846 — IX-SIT67 update header ⚠️ упомянут в письме
  6. PR #847 — FAQPage hotfix ⚠️ упомянут в письме
  7. Системные паттерны
  8. Предложения процессных изменений
  9. План встречи

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)

Письмо Alexis

4 ключевых тезиса

  1. Deviate from spec"deliverables (such as the header) that deviate considerably from spec and require revisiting"
  2. 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"
  3. Avoid rebasing after share"we'd kindly ask to avoid rebasing after code is shared to preserve history"
  4. 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)

Bemin Shaker — master vs develop

"I noticed the content model change for this... was made in master rather than develop. 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)

Michael — field config spec deviation

"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 — день открытия)

Michael — console.log debug

"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

Michael — build failed pre-merge tasks

"I tried merging this branch into vercel-stage... but the build failed due to Cannot 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)

Michael — invalid VideoObject

"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)

Michael — 700 entries not synced

"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 месяца до письма!)

Alexis — hold + pre-deployment question

"@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)

Michael — VideoJsonLd invalid hero

"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)

Bemin — undefined base URL

"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)

Bemin — hardcoded news prefix

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

Bemin — hardcoded creditText

"The Image Wrapper component has a credit field, 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)

Michael — Info For center-justified

"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)

Michael — menu wraps

"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)

Michael — mobile logo spec Michael — mobile logo feature branch

"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)

Michael — CTA duplication

"...need to be removed from this <UtilityMenu> to avoid duplication."

Request Info / Visit / Apply показаны дважды — в верхней части (правильно) и в нижнем UtilityMenu (дубликат).

5.5. Dark mode — недостаточный контраст на жёлтых CTA (Michael, 23.04)

Michael — dark mode contrast

"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)

Michael — search 4 issues spec Feature branch

"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)

Michael — sticky clarification

"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)

Michael — data-cta sys.id

"the person requesting this data-cta attribute 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 — архитектурно правильное решение

Ivan — PR description Fast Schema Analyzer

Иван сделал 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)

Bemin — bottomComponentsCollection

"This doesn't take into account Right Nav and Program Detail pages which have componentsCollection AND bottomComponentsCollection. 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)

Michael — commit-after-approve

Иван закоммитил 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)

Bemin — NEXT_PUBLIC_SITE_URL

"NEXT_PUBLIC_SITE_URL is not set as an environment variable, so wouldn't process.env.NEXT_PUBLIC_SITE_URL always 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")

  1. Spec sweep — открыт parent в Jira + все attachments; acceptance criteria сверены построчно с реализацией.
  2. Mockup overlay — preview ↔ мокап рядом; все состояния (default / sticky / hover / expanded / search open).
  3. Responsive — RWD-режим, ползунок ширины через все breakpoint'ы (между ними, не только на стандартных).
  4. Mobile menu / overlays / dropdowns — открыты вручную хотя бы раз.
  5. Dark mode / accessibility — Lighthouse / axe DevTools / contrast check.
  6. Code hygienegit diff глазами; нет console.log, // TODO when approve, dead fallback'ов; grep env-vars подтверждает существование.
  7. Schema/spec compliance — если выводится structured data → провалидировано через Rich Results / Fast Schema Analyzer.
  8. Existing data — если фича триггерится на новых данных → продумано, что с историческими.

B. PR description template (обязательные секции)

  • Summary
  • Changes
  • Pre-merge tasks — что нужно сделать до merge
  • Migration plan — что с существующими данными
  • Validation done — какие тесты прогнаны, ссылки на preview-валидаторы
  • Compare URLs (preview ↔ prod)

C. Workflow rules (свод)

  1. После первого git push ветки — никаких rebase / force-push / squash локально.
  2. Squash — только при финальном merge через UI (кнопка "Squash and merge").
  3. Никаких "TODO when approve" в коде. Если код не готов — Draft PR.
  4. После approve — изменения только с явным "please re-review".
  5. 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 мин, без Ивана)

Цель: обсудить общую картину и системные выводы до разговора с Иваном.

  1. Контекст письма Alexis (5 мин)
  2. Сводка по 5 PR (10 мин) — пройти главы 2–6 этого документа, остановиться на самом тяжёлом (#832 + #847 + header)
  3. Ключевые вопросы Антону (10 мин) — открыть meeting/questions-anton.md, пройти разделы A (история сигналов), B (self-QA), C (workflow)
  4. Договориться о формате разговора с Иваном (5 мин) — что выносим жёстко, что мягче

Самое важное обсудить с Антоном до разговора с Иваном:

  • Сигнал Alexis 23.02 (он тегнул Антона напрямую) — что было сделано в ответ?
  • Commit-after-approve в #847 — это разовая ошибка или системный пробел понимания workflow у Ивана?
  • Готовы ли мы к 7 процессным изменениям (раздел 8)?
  • Тон ответа Stevens (после встречи).

Часть 2 — втроём (с Иваном) (~45 мин)

  1. Контекст письма (5 мин) — кратко переcказать
  2. PR #847 git-история (15 мин) — открываем Bitbucket вместе:
    • merge strategy PR #837
    • force-push'и в ICUS-216-faq
    • локальный rebase/squash перед PR #847
    • reflog
  3. PR #847 commit-after-approve (5 мин) — разобрать meeting/questions-ivan.md Приоритет 1
  4. PR #846 (header) self-QA (10 мин) — Приоритет 3
  5. Системные паттерны и предложения (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