Безопасность и правоРазбор · На радарHabr AI→ оригинал

Слепой разработчик научил ИИ-агента не выдумывать ошибки доступности в коде

Незрячий программист развивает Accessibility Auditor Skill — инструкции для ИИ-агента, проверяющего доступность интерфейсов. Первые версии судили по одному файлу: ругались на «пропавший» атрибут, который уже добавляла библиотека, и правили общий компонент, не глядя на его потребителей. Автор дописал правила на реальных PR в открытые проекты, и один из них, для Nextcloud iOS, приняли.

AI-обработка оригинала Habr AI; редакция Hamidun News
Слепой разработчик научил ИИ-агента не выдумывать ошибки доступности в коде
Источник: Habr AI. Коллаж: Hamidun News.
Слушать статью
Паспорт материала и цифры
ПараметрДанные
ПервоисточникHabr AI ↗
Главный редактор
Ключевой факт #1Сначала проверяй реализацию компонента и версию библиотеки, потом объявляй проблему
Ключевой факт #2Добавляя свойство в общий интерфейс, найди всех его потребителей
В отчёте агент пишет, что проверилкод, тесты или скринридер

Представьте: ИИ-агент проверяет форму и бодро сообщает, что у поля нет aria-describedby. Вы открываете код, а связь с подсказкой давно создаёт компонент формы из библиотеки. Такие ложные находки съедают доверие к аудиту быстрее, чем пропущенные баги. С этим столкнулся незрячий программист, который пользуется скринридером и строит Accessibility Auditor Skill — набор инструкций для агента, проверяющего доступность по исходникам и на живых сайтах.

Смотреть не на место вызова, а на реализацию

Главная правка в скилле: прежде чем назвать что-то проблемой, агент идёт от места использования к реализации. Он выясняет, какой элемент получает фокус, откуда берётся его доступное имя, где создаются подпись, подсказка и сообщение об ошибке, как передаются идентификаторы и что делает установленная версия библиотеки. Заодно проверяет, что найденный файл вообще участвует в нужном сценарии: в репозиториях часто лежат старые компоненты с похожими названиями, и правка такого файла ничего не меняет для пользователя.

Если связь действительно потеряна в общем компоненте, чинить надо там и проверять все затронутые поля. Если она уже есть, дублировать её не нужно.

Уроки с конкретных PR

В PR для RTL агент разбирал сообщения авторизации и загрузки. Роли status и alert уже задают режим озвучки, поэтому лишний assertive или role="alert" может перебивать речь скринридера. Для спиннера рядом с текстом правило такое: если сообщение уже есть в тексте, декоративному индикатору не дают то же доступное имя, а скрывают его через aria-hidden. Этот PR закрыт без слияния, так что фрагмент показывает лишь предложенное изменение; реальную озвучку нужно проверять в работающем приложении.

В Vets-Who-Code свойство feedbackId добавили в общий интерфейс слишком широко, и оно оказалось доступно компонентам, которые его не обрабатывали. Отсюда правило: при добавлении свойства выяснить, кто его поддерживает и не попадёт ли оно лишним атрибутом в HTML. Идентификаторы проверяют в двух вариантах — сгенерированном и переданном снаружи. Иначе стандартный пример работает, а форма со своим ID теряет связь с ошибкой.

В suitenumerique/docs исправление зависело от внутреннего элемента Cunningham Select. Библиотека может поменять разметку, и селектор сломается. Теперь скилл предпочитает публичный API, а при обращении к внутренностям требует регрессионный тест на итоговые aria-hidden и tabindex. В той итерации такие проверки добавили в Playwright-тест, но полный e2e-прогон не выполняли.

Принятый результат и честные ограничения

Единственный приведённый принятый PR — Nextcloud iOS №4111, принятый 28 мая 2026 года. У строк папок в окне выбора места сохранения не было доступного имени: VoiceOver фокусировался на элементе, но не называл папку. Агент собрал имя из названия и уже показанных в ячейке сведений, отбросил пустые значения и назначил строке признак кнопки. Проверялся только исходный код: сборку iOS и тест с VoiceOver не делали, в окружении не было Xcode.

Автор прямо пишет, что замера доли ложных находок до и после правок у него нет. Есть правила и случаи, после которых они появились. Поэтому в отчёте агент обязан указывать, что именно сделал: разобрал код, прогнал тесты или слушал скринридер. Это разные уровни уверенности.

Что взять себе

Если вы строите агентов для ревью кода, не ограничивайтесь одним файлом. Заставьте агента проследить цепочку от вызова до библиотеки и проверить потребителей общих компонентов. Фиксируйте уроки с реальных PR прямо в инструкциях, чтобы не объяснять их заново в каждом проекте. И требуйте от агента честно называть тип проверки: чтение кода не заменяет тест со скринридером на устройстве.

Сюжет

Вопросы и ответы по материалу

Что известно по теме: смотреть не на место вызова, а на реализацию?

Главная правка в скилле: прежде чем назвать что-то проблемой, агент идёт от места использования к реализации. Он выясняет, какой элемент получает фокус, откуда берётся его доступное имя, где создаются подпись, подсказка и сообщение об ошибке, как передаются идентификаторы и что делает установленная версия библиотеки. Заодно проверяет, что найденный файл вообще участвует в нужном сценарии: в репозиториях часто лежат старые компоненты с похожими названиями, и правка такого файла ничего не меняет для пользователя.

Что известно по теме: уроки с конкретных PR?

В PR для RTL агент разбирал сообщения авторизации и загрузки. Роли status и alert уже задают режим озвучки, поэтому лишний assertive или role="alert" может перебивать речь скринридера. Для спиннера рядом с текстом правило такое: если сообщение уже есть в тексте, декоративному индикатору не дают то же доступное имя, а скрывают его через aria-hidden. Этот PR закрыт без слияния, так что фрагмент показывает лишь предложенное изменение; реальную озвучку нужно проверять в работающем приложении.

Что известно по теме: принятый результат и честные ограничения?

Единственный приведённый принятый PR — Nextcloud iOS №4111, принятый 28 мая 2026 года. У строк папок в окне выбора места сохранения не было доступного имени: VoiceOver фокусировался на элементе, но не называл папку. Агент собрал имя из названия и уже показанных в ячейке сведений, отбросил пустые значения и назначил строке признак кнопки. Проверялся только исходный код: сборку iOS и тест с VoiceOver не делали, в окружении не было Xcode. Автор прямо пишет, что замера доли ложных находок до и после правок у него нет.

ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ Практика · Hamidun Academy

Соберите рабочего ИИ-агента или сервис своими руками без ручного кода

В Академии Жемала Хамидуна (academy.hamidun.com) открыт бесплатный 72-часовой тест-драйв: интерактивные скетч-уроки по Claude Code и Cursor, живой Tech Radar и готовые шаблоны агентов.

Открыть 72ч бесплатный доступ →Интенсив по Вайб-кодингу
Что вы думаете?
Загружаем комментарии…