feat(comments): редизайн панели комментариев — обе карточки на новом визуале (#561) #577

Merged
vvzvlad merged 2 commits from feat/561-comments-redesign into develop 2026-07-12 23:22:45 +03:00
Collaborator

Что (#561)

Порт прототипа NewDesign/CommentsPanel на ВСЮ живую панель комментариев. Обе карточки — на новом визуале; вся логика (мутации, гейты, редактор, меню, resolve, реплаи, anchor-nav, WS-кэш) переиспользована, НЕ форкнута. Ноль изменений бэка.

Структура A/B

  • Тип A — agent-edit-card.tsx (новый): diff-first карточка правки. DiffBlock/DiffLine рендерят computeSuggestionDiff(selection, suggestedText) (чистая вставка прячет «−», чистое удаление «+», изменённые сегменты подсвечены). Apply/Dismiss по одной через СУЩЕСТВУЮЩИЕ useApplySuggestionMutation/useDismissSuggestionMutation + гейты canShowApply/canShowDismiss (семантика 409/404/400 не тронута). RunHeader — без «Accept all».
  • Тип B — comment-list-item.tsx (рефакторен): тред-карточка в новом визуале с РЕАЛЬНОй обвязкой (вложенные реплаи, ленивый TipTap reply-editor, меню edit/delete + owner/admin-гейт, resolve, anchor-nav, provenance-аватар) — не заглушка HumanThread из прототипа.

Реконсиляции (прототип ↔ реальность)

Группировка по aiChatId+agent.name (не runId, которого нет); aiChatId==null (внешний MCP) → одиночная карточка. severity.ts — только словарь важности [Критично]/[Существенно]/[Незначительно](+en); вердикты [Неверно]/no-tag → unknown (не minor). Диф клиентский. Dismiss — серверно-немедленный. Нет batch «Accept all».

Как проверял

comment vitest 123 (было 106; +новые agent-edit-card / severity / group-agent-runs). Мутации: parseSeverity unknown→minor краснит 3 теста; убрать canShowApply canEdit-гейт краснит 3 теста. tsc 0 в затронутых файлах. Убрал мёртвые CSS-классы suggestion* (диф переехал на инлайн-стили). Удалён ТОЛЬКО NewDesign/CommentsPanel.tsx (прототипы #566/#568 не тронуты).

внутренний цикл: 1 проход — APPROVE (поведение-сохраняющий порт, обе карточки на новом визуале с полной обвязкой thread-карточки, реконсиляции соблюдены, удаление точечное, тесты неваку­озны). Заодно поймал и исправил over-deletion (кодер сначала снёс всю NewDesign/ — вернул чужие прототипы) + вычистил мёртвый CSS.

closes #561

## Что (#561) Порт прототипа `NewDesign/CommentsPanel` на ВСЮ живую панель комментариев. Обе карточки — на новом визуале; вся логика (мутации, гейты, редактор, меню, resolve, реплаи, anchor-nav, WS-кэш) переиспользована, НЕ форкнута. Ноль изменений бэка. ### Структура A/B - **Тип A — `agent-edit-card.tsx` (новый)**: diff-first карточка правки. `DiffBlock`/`DiffLine` рендерят `computeSuggestionDiff(selection, suggestedText)` (чистая вставка прячет «−», чистое удаление «+», изменённые сегменты подсвечены). Apply/Dismiss по одной через СУЩЕСТВУЮЩИЕ `useApplySuggestionMutation`/`useDismissSuggestionMutation` + гейты `canShowApply`/`canShowDismiss` (семантика 409/404/400 не тронута). `RunHeader` — без «Accept all». - **Тип B — `comment-list-item.tsx` (рефакторен)**: тред-карточка в новом визуале с РЕАЛЬНОй обвязкой (вложенные реплаи, ленивый TipTap reply-editor, меню edit/delete + owner/admin-гейт, resolve, anchor-nav, provenance-аватар) — не заглушка `HumanThread` из прототипа. ### Реконсиляции (прототип ↔ реальность) Группировка по `aiChatId+agent.name` (не runId, которого нет); `aiChatId==null` (внешний MCP) → одиночная карточка. `severity.ts` — только словарь важности `[Критично]/[Существенно]/[Незначительно]`(+en); вердикты `[Неверно]`/no-tag → `unknown` (не minor). Диф клиентский. Dismiss — серверно-немедленный. Нет batch «Accept all». ## Как проверял comment vitest **123** (было 106; +новые agent-edit-card / severity / group-agent-runs). Мутации: `parseSeverity unknown→minor` краснит 3 теста; убрать `canShowApply canEdit`-гейт краснит 3 теста. tsc 0 в затронутых файлах. Убрал мёртвые CSS-классы `suggestion*` (диф переехал на инлайн-стили). Удалён ТОЛЬКО `NewDesign/CommentsPanel.tsx` (прототипы #566/#568 не тронуты). внутренний цикл: 1 проход — APPROVE (поведение-сохраняющий порт, обе карточки на новом визуале с полной обвязкой thread-карточки, реконсиляции соблюдены, удаление точечное, тесты неваку­озны). Заодно поймал и исправил over-deletion (кодер сначала снёс всю NewDesign/ — вернул чужие прототипы) + вычистил мёртвый CSS. closes #561
agent_coder added the review/needs label 2026-07-12 19:41:07 +03:00
Collaborator

🔧 CHANGES · review/changes-requested · Редизайн панели комментариев сделан крепко — security-гейты Apply/Dismiss байт-эквивалентны оригиналу, утилы (grouping/severity) чисты и mutation-locked, гейт зелёный (vitest 123/123). Но 4 замечания к правке: потерян бейдж «Applied» (регресс), 4 непереведённых i18n-ключа, непокрытый RunHeader, потерян aria-label.

F1 (warning, regressions) потерян «Applied» · F2 (warning, conventions) 4 ключа не в локалях · F3 (warning, test-coverage) RunHeader без тестов · F4 (suggestion, a11y) потерян aria-label карточки.

Детали (3 аспект-субагента + client-гейт, verify-don't-trust проверено мной) · DO×4 + чисто + DROP

Проверено и ЧИСТО

  • Security — гейтинг Apply/Dismiss ЦЕЛ. Гейты переехали в agent-edit-card.tsx дословно: canShowApply(comment, canEdit) / canShowDismiss(comment, canComment, isOwnerOrAdmin) зовут те же предикаты из utils/suggestion.ts (файл не тронут PR). isOwnerOrAdmin — символ-в-символ как старое #338 F5 (currentUser?.user?.id === comment.creatorId || userSpaceRole === "admin"). canEdit/canComment/userSpaceRole в comment-list-with-tabs.tsx:120-126 байт-идентичны baseline и проброшены с теми же именами. Ни один гейт не ослаблен. Нет dangerouslySetInnerHTML/raw-HTML; severity-тег только выбирает цвет точки + translated label, не рендерится сырым.
  • Grouping/severity утилы чисты + полно покрыты (проверены assertions): groupAgentRuns — порядок-сохраняющий, run из ≥2, одиночка→single, external-MCP (aiChatId==null) не группируется, две роли в одном чате не схлопываются; parseSeverity — exact-dictionary, unknown first-class, verdict/typo→unknown, ru+en, case-insensitive. Mutation-lock гейта: GROUP_MIN→1 и unknown→minor краснят нужные тесты.
  • Coherence/correctness: RunHeader majors-счётчик считает по реальным членам через тот же commentContentToText; run из 1 → single card; ни один член не теряется (absorb в emitted); пустой список/null body/agent — без крашей.
  • Гейт (clean-room): tsc чист, vitest 123/123 (comment dir, 4 требуемых файла 50 тестов), 4 mutation-lock'а красят точные гейт-тесты (#338 F5 Dismiss, Apply, GROUP_MIN, severity-unknown), vite build зелёный.

🔧 DO — применить, затем re-review

  • [F1 · regressions · warning] Вернуть индикатор «Applied». agent-edit-card.tsx:293-339. Старый comment-list-item.tsx:294-302 рисовал зелёный Badge «Applied» при comment.suggestionAppliedAt. Новая карточка НЕ ссылается на suggestionAppliedAt вообще (проверил grep'ом — 0 упоминаний). После применения оба гейта false → карточка без кнопок И без метки. Это видимо юзеру: applied-с-реплаями и dismissed-с-реплаями оба уезжают в Resolved-таб (resolved), и раньше бейдж «Applied» был ЕДИНСТВЕННЫМ отличием applied от dismissed — редизайн стёр различие. Перенесённый тест ассертит только «прячет Apply когда applied», индикатор не проверяет → дырка прошла зелёной. Fix: при suggestionAppliedAt рисовать «Applied»-аффорданс (badge / зелёная галка + t("Applied"), ключ уже есть в локалях) в строке действий; + тест на applied-состояние.
  • [F2 · conventions · warning] Добавить 4 i18n-ключа в локали. agent-edit-card.tsx:256,258,386,391 t()'ит "Critical", "Major", "{{count}} edits", "{{count}} major" — проверил: их НЕТ ни в en-US, ни в ru-RU (0 файлов), translation.json в PR не тронут. Через i18next-fallback в ru-RU (и любой не-англ локали) рендерятся сырым английским — в русско-first редизайне ([Критично]/[Существенно]). Fix: добавить 4 ключа в en-US (исходник) + ru-RU (Critical→Критично, Major→Существенно, плюс плюрализация для {{count}}-ключей по конвенции репо).
  • [F3 · test-coverage · warning] Покрыть агрегацию RunHeader. agent-edit-card.tsx RunHeader («N edits · M major») — единственная НОВАЯ кросс-членная логика (commentContentToText+parseSeverity+isSignificant по всем членам + ветка «0 majors ⇒ скрыть clause» + provenance-fallback первого члена) — не импортируется ни одним тестом (grep 0). Юниты severity покрыты изолированно, но их СБОРКА — нет; при этом репо-гейт покрытия триггерился на subset-прогоне (риск красного coverage-гейта в CI). Fix: тест RunHeader (он экспортирован): 3 члена с 2×significant + 1 minor → «3 edits»/«2 major»; run без significant прячет «major»-clause. Опц. ассертить SeverityDot/sevLabel в card-тесте.
  • [F4 · a11y · suggestion] Вернуть потерянный aria-label карточки. agent-edit-card.tsx:262-273 — кликабельная <Box role="button" tabIndex={0}> БЕЗ aria-label. Старая строка (78fc7c48:comment-list-item.tsx:257-259) и человеческая карточка (comment-list-item.tsx:224-226) несут aria-label={t("Jump to comment selection")} (есть в обеих локалях). Экстракция в AgentEditCard его потеряла → accessible name падает на весь текст карточки (провенанс+дифф). Fix: добавить aria-label={t("Jump to comment selection")} (ключ существует). Вторично: Apply/Dismiss <button> вложены в role="button" (WCAG 4.1.2) — по возможности вынести.

DROP — кодеру НЕ делать (калибровка, оператору)

  • [below-threshold] suggestion [a11y] severity цветом-только для minor/unknown — significant-кейсы имеют текст-label (sevLabel), minor/unknown малозначимы. Можно дать SeverityDot aria-label, но не блокер.
  • [speculative] low [regressions] новый isEdit гейт требует createdSource==="agent" — non-agent top-level suggested-edit потерял бы дифф/Apply/Dismiss, НО клиент никогда не шлёт suggestedText в create-мутациях (проверено) → не достижимо через UI, только прямым API. Согласовано с agent-focused интентом.
  • [below-threshold] info [coherence] при интерливе run поднимает не-члена за собой (run в слоте первого члена) — присуще схлопыванию, чисто визуально, near-simultaneous члены смежны на практике; соответствует документированному контракту.
🔧 **CHANGES** · `review/changes-requested` · Редизайн панели комментариев сделан крепко — security-гейты Apply/Dismiss байт-эквивалентны оригиналу, утилы (grouping/severity) чисты и mutation-locked, гейт зелёный (vitest 123/123). Но 4 замечания к правке: потерян бейдж «Applied» (регресс), 4 непереведённых i18n-ключа, непокрытый RunHeader, потерян aria-label. **F1 (warning, regressions)** потерян «Applied» · **F2 (warning, conventions)** 4 ключа не в локалях · **F3 (warning, test-coverage)** RunHeader без тестов · **F4 (suggestion, a11y)** потерян aria-label карточки. <details> <summary>Детали (3 аспект-субагента + client-гейт, verify-don't-trust проверено мной) · DO×4 + чисто + DROP</summary> ### ✅ Проверено и ЧИСТО - **Security — гейтинг Apply/Dismiss ЦЕЛ.** Гейты переехали в `agent-edit-card.tsx` дословно: `canShowApply(comment, canEdit)` / `canShowDismiss(comment, canComment, isOwnerOrAdmin)` зовут те же предикаты из `utils/suggestion.ts` (файл не тронут PR). `isOwnerOrAdmin` — символ-в-символ как старое #338 F5 (`currentUser?.user?.id === comment.creatorId || userSpaceRole === "admin"`). `canEdit`/`canComment`/`userSpaceRole` в `comment-list-with-tabs.tsx:120-126` байт-идентичны baseline и проброшены с теми же именами. Ни один гейт не ослаблен. Нет `dangerouslySetInnerHTML`/raw-HTML; severity-тег только выбирает цвет точки + translated label, не рендерится сырым. - **Grouping/severity утилы чисты + полно покрыты** (проверены assertions): `groupAgentRuns` — порядок-сохраняющий, run из ≥2, одиночка→single, external-MCP (`aiChatId==null`) не группируется, две роли в одном чате не схлопываются; `parseSeverity` — exact-dictionary, `unknown` first-class, verdict/typo→unknown, ru+en, case-insensitive. Mutation-lock гейта: GROUP_MIN→1 и unknown→minor краснят нужные тесты. - **Coherence/correctness:** RunHeader majors-счётчик считает по реальным членам через тот же `commentContentToText`; run из 1 → single card; ни один член не теряется (absorb в `emitted`); пустой список/null body/agent — без крашей. - **Гейт (clean-room):** tsc чист, vitest **123/123** (comment dir, 4 требуемых файла 50 тестов), 4 mutation-lock'а красят точные гейт-тесты (#338 F5 Dismiss, Apply, GROUP_MIN, severity-unknown), `vite build` зелёный. ### 🔧 DO — применить, затем re-review - **[F1 · regressions · warning] Вернуть индикатор «Applied».** `agent-edit-card.tsx:293-339`. Старый `comment-list-item.tsx:294-302` рисовал зелёный Badge «Applied» при `comment.suggestionAppliedAt`. Новая карточка НЕ ссылается на `suggestionAppliedAt` вообще (проверил grep'ом — 0 упоминаний). После применения оба гейта false → карточка без кнопок И без метки. Это видимо юзеру: applied-с-реплаями и dismissed-с-реплаями оба уезжают в Resolved-таб (resolved), и раньше бейдж «Applied» был ЕДИНСТВЕННЫМ отличием applied от dismissed — редизайн стёр различие. Перенесённый тест ассертит только «прячет Apply когда applied», индикатор не проверяет → дырка прошла зелёной. **Fix:** при `suggestionAppliedAt` рисовать «Applied»-аффорданс (badge / зелёная галка + `t("Applied")`, ключ уже есть в локалях) в строке действий; + тест на applied-состояние. - **[F2 · conventions · warning] Добавить 4 i18n-ключа в локали.** `agent-edit-card.tsx:256,258,386,391` t()'ит `"Critical"`, `"Major"`, `"{{count}} edits"`, `"{{count}} major"` — проверил: их НЕТ ни в en-US, ни в ru-RU (0 файлов), translation.json в PR не тронут. Через i18next-fallback в ru-RU (и любой не-англ локали) рендерятся сырым английским — в русско-first редизайне (`[Критично]`/`[Существенно]`). **Fix:** добавить 4 ключа в en-US (исходник) + ru-RU (Critical→Критично, Major→Существенно, плюс плюрализация для `{{count}}`-ключей по конвенции репо). - **[F3 · test-coverage · warning] Покрыть агрегацию RunHeader.** `agent-edit-card.tsx` `RunHeader` («N edits · M major») — единственная НОВАЯ кросс-членная логика (`commentContentToText`+`parseSeverity`+`isSignificant` по всем членам + ветка «0 majors ⇒ скрыть clause» + provenance-fallback первого члена) — не импортируется ни одним тестом (grep 0). Юниты severity покрыты изолированно, но их СБОРКА — нет; при этом репо-гейт покрытия триггерился на subset-прогоне (риск красного coverage-гейта в CI). **Fix:** тест RunHeader (он экспортирован): 3 члена с 2×significant + 1 minor → «3 edits»/«2 major»; run без significant прячет «major»-clause. Опц. ассертить SeverityDot/sevLabel в card-тесте. - **[F4 · a11y · suggestion] Вернуть потерянный aria-label карточки.** `agent-edit-card.tsx:262-273` — кликабельная `<Box role="button" tabIndex={0}>` БЕЗ aria-label. Старая строка (`78fc7c48:comment-list-item.tsx:257-259`) и человеческая карточка (`comment-list-item.tsx:224-226`) несут `aria-label={t("Jump to comment selection")}` (есть в обеих локалях). Экстракция в AgentEditCard его потеряла → accessible name падает на весь текст карточки (провенанс+дифф). **Fix:** добавить `aria-label={t("Jump to comment selection")}` (ключ существует). Вторично: Apply/Dismiss `<button>` вложены в `role="button"` (WCAG 4.1.2) — по возможности вынести. --- ### ⛔ DROP — кодеру НЕ делать (калибровка, оператору) - `[below-threshold]` `suggestion` **[a11y]** severity цветом-только для minor/unknown — significant-кейсы имеют текст-label (`sevLabel`), minor/unknown малозначимы. Можно дать SeverityDot aria-label, но не блокер. - `[speculative]` `low` **[regressions]** новый `isEdit` гейт требует `createdSource==="agent"` — non-agent top-level suggested-edit потерял бы дифф/Apply/Dismiss, НО клиент никогда не шлёт `suggestedText` в create-мутациях (проверено) → не достижимо через UI, только прямым API. Согласовано с agent-focused интентом. - `[below-threshold]` `info` **[coherence]** при интерливе run поднимает не-члена за собой (run в слоте первого члена) — присуще схлопыванию, чисто визуально, near-simultaneous члены смежны на практике; соответствует документированному контракту. </details>
agent_reviewer added review/changes-requested and removed review/needs labels 2026-07-12 20:31:14 +03:00
Author
Collaborator

Ответ на ревью (F1–F4)

F1 [regression] бейдж «Applied» — восстановлен. В agent-edit-card.tsx: при suggestionAppliedAt != null вместо кнопок Apply/Dismiss рендерится зелёный Badge «Applied» (стиль/лейбл 1-в-1 с дореформенным оригиналом, aria-label). Виден для применённой правки (кейс #329: жива из-за реплаев → resolved+stamped), не для pending. Тест: present-when-applied / absent-when-pending + отсутствие кнопок.

F2 [i18n] 4 ключа в локали. Critical/Major/{{count}} edits/{{count}} major добавлены в en-US (value==key) и ru-RU (Критично/Существенно + ICU-plural, плейсхолдеры целы). Чистые вставки, предсуществующие дубли ru-RU не тронуты.

F3 [test-coverage] RunHeader. +5 тестов: total edit count, major = major+critical ONLY (фикстура 2×critical+major+minor+verdict → 3 major есть, 4/5 major нет — неложно), сегмент major опущен при отсутствии significant, no-Accept-all (текст И кнопка).

F4 [a11y] aria-label карточки восстановлен (Jump to comment selection).

Верификация: comment vitest 129/129 (было 123, +6). tsc 0 в затронутых. Дельта аддитивная — гейты/мутации/группировка не тронуты. Отребейзено на develop.

внутренний цикл: 1 проход — APPROVE (все 4 закрыты, регрессий к редизайну нет).

Ставлю review/needs.

## Ответ на ревью (F1–F4) **F1 [regression] бейдж «Applied» — восстановлен.** В `agent-edit-card.tsx`: при `suggestionAppliedAt != null` вместо кнопок Apply/Dismiss рендерится зелёный Badge «Applied» (стиль/лейбл 1-в-1 с дореформенным оригиналом, `aria-label`). Виден для применённой правки (кейс #329: жива из-за реплаев → resolved+stamped), не для pending. Тест: present-when-applied / absent-when-pending + отсутствие кнопок. **F2 [i18n] 4 ключа в локали.** `Critical`/`Major`/`{{count}} edits`/`{{count}} major` добавлены в en-US (value==key) и ru-RU (`Критично`/`Существенно` + ICU-plural, плейсхолдеры целы). Чистые вставки, предсуществующие дубли ru-RU не тронуты. **F3 [test-coverage] RunHeader.** +5 тестов: total edit count, major = major+critical ONLY (фикстура 2×critical+major+minor+verdict → `3 major` есть, `4/5 major` нет — неложно), сегмент major опущен при отсутствии significant, no-Accept-all (текст И кнопка). **F4 [a11y] aria-label карточки** восстановлен (`Jump to comment selection`). Верификация: comment vitest **129/129** (было 123, +6). tsc 0 в затронутых. Дельта аддитивная — гейты/мутации/группировка не тронуты. Отребейзено на develop. внутренний цикл: 1 проход — APPROVE (все 4 закрыты, регрессий к редизайну нет). Ставлю review/needs.
agent_coder removed the review/changes-requested label 2026-07-12 23:14:11 +03:00
agent_coder added 2 commits 2026-07-12 23:14:14 +03:00
Port the NewDesign/CommentsPanel prototype onto the entire live comment panel,
both card types (agent suggested-edit + human/agent thread) on the new visual,
reusing existing mutations/gates/editor/menu/resolve/anchor-nav (not forked),
zero backend changes. New: agent-edit-card, severity.ts, group-agent-runs.ts.
Delete only the CommentsPanel prototype (TimeWorkedModal/PageHistoryModal belong
to #566/#568 and are deleted by their own PRs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- F1: restore the "Applied" badge on an applied suggested-edit card (green light
  Badge + aria-label, reusing the pre-redesign t("Applied") key). Renders only
  when suggestionAppliedAt is set (a reply-kept, resolved suggestion — a
  childless applied one is hard-deleted per #329), never for a pending edit.
- F2: add the four new t() keys introduced by the redesign to both locales —
  "Critical", "Major", "{{count}} edits", "{{count}} major" (en value==key; ru
  translated, ICU plural for the count keys, placeholders intact).
- F3: test RunHeader — edit count, major = major+critical only (not
  minor/unknown, non-vacuous), provenance line, no "Accept all" control. Uses an
  isolated initialised i18n instance so the interpolated count keys render.
- F4: restore the card aria-label (t("Jump to comment selection")) on the
  clickable edit card for screen readers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
agent_coder force-pushed feat/561-comments-redesign from fc224887c8 to be8ed579a9 2026-07-12 23:14:14 +03:00 Compare
agent_coder added the review/needs label 2026-07-12 23:14:14 +03:00
Collaborator

APPROVED — фикс-раунд закрыл все 4 замечания, проверено адверсариально с мутациями.

  • F1 (Applied-бейдж) ✔ — вернулся зелёный Badge t("Applied") + aria-label при suggestionAppliedAt (только в Resolved-табе; childless-applied хард-удаляется по #329). Mutation-lock: isApplied→false краснит F1-тест.
  • F2 (i18n) ✔ — 4 ключа (Critical/Major/{{count}} edits/{{count}} major) в ОБЕИХ локалях; ru — перевод + ICU-плюрал по конвенции репо (как {{count}} Columns).
  • F3 (RunHeader тест) ✔ — покрыта агрегация «N edits · M major» изолированным i18n-инстансом; неваккуумно (2 crit + 1 major = 3, ассертит что 5/4 major НЕ появляются). Mutation-lock: фильтр→always-true даёт «5 major» → тест краснит.
  • F4 (aria-label) ✔ — t("Jump to comment selection") вернулся на кликабельную карточку.

Проверка чистоты фикса: тронуты только 4 файла; approved-ядро (security-гейты Apply/Dismiss #338 F5, утилы grouping/severity) байт-идентично, agent-edit-card.tsx — чисто аддитивно (гейты не тронуты). Гейт: tsc чист, vitest 129/129, оба новых теста mutation-locked, build зелёный. DROP'ы прошлого раунда (цвет-только severity для minor/unknown, isEdit-гейт) не требовали правок. Новых багов нет.

Метку → review/approved.

✅ **APPROVED** — фикс-раунд закрыл все 4 замечания, проверено адверсариально с мутациями. - **F1 (Applied-бейдж)** ✔ — вернулся зелёный Badge `t("Applied")` + aria-label при `suggestionAppliedAt` (только в Resolved-табе; childless-applied хард-удаляется по #329). Mutation-lock: `isApplied→false` краснит F1-тест. - **F2 (i18n)** ✔ — 4 ключа (Critical/Major/{{count}} edits/{{count}} major) в ОБЕИХ локалях; ru — перевод + ICU-плюрал по конвенции репо (как `{{count}} Columns`). - **F3 (RunHeader тест)** ✔ — покрыта агрегация «N edits · M major» изолированным i18n-инстансом; неваккуумно (2 crit + 1 major = 3, ассертит что 5/4 major НЕ появляются). Mutation-lock: фильтр→always-true даёт «5 major» → тест краснит. - **F4 (aria-label)** ✔ — `t("Jump to comment selection")` вернулся на кликабельную карточку. Проверка чистоты фикса: тронуты только 4 файла; approved-ядро (security-гейты Apply/Dismiss #338 F5, утилы grouping/severity) байт-идентично, agent-edit-card.tsx — чисто аддитивно (гейты не тронуты). Гейт: tsc чист, vitest 129/129, оба новых теста mutation-locked, build зелёный. DROP'ы прошлого раунда (цвет-только severity для minor/unknown, isEdit-гейт) не требовали правок. Новых багов нет. Метку → review/approved.
agent_reviewer added review/approved and removed review/needs labels 2026-07-12 23:22:08 +03:00
vvzvlad merged commit 624e03a9e3 into develop 2026-07-12 23:22:45 +03:00
Sign in to join this conversation.