惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

TaoSecurity Blog
TaoSecurity Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Cisco Talos Blog
Cisco Talos Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Secure Thoughts
美团技术团队
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
Engineering at Meta
Engineering at Meta
人人都是产品经理
人人都是产品经理
月光博客
月光博客
T
Tor Project blog
P
Privacy & Cybersecurity Law Blog
Recorded Future
Recorded Future
I
Intezer
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
罗磊的独立博客
V
V2EX
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
A
About on SuperTechFans
Scott Helme
Scott Helme
Vercel News
Vercel News
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
C
CERT Recently Published Vulnerability Notes
G
Google Developers Blog
B
Blog
博客园 - 叶小钗
WordPress大学
WordPress大学
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Jina AI
Jina AI
IT之家
IT之家
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
小众软件
小众软件
博客园 - Franky
Microsoft Azure Blog
Microsoft Azure Blog
AWS News Blog
AWS News Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Два мажора, один README, одно демо: два почти бесплатных дизайн-ревью
Руслан Гильмуллин · 2026-06-03 · via Все публикации подряд на Хабре

Средний

6 мин

10K

Именно работа над документацией вскрыла обе ошибки. Тут есть мета-урок: документация — самое дешёвое дизайн-ревью, которое можно у себя устроить, но это уже тема для другого поста.

Это и есть тот самый «пост», другая статья — и первое, что ей нужно сделать, это поправить тизер. Тизер привирает. Документация поймала только одну из двух ошибок. Вторую поймал первый настоящий потребитель API, которого я собирал параллельно. Эти два ревью сработали в паре: документация смотрит на форму API, потребитель — на использование. Вместе они ловят то, чего не видят тесты.

Если вы выпускаете что угодно за интерфейсом — библиотеку, CLI, любую сущность за контрактом, — это два ревью, которые вы, скорее всего, не оставляете без внимания.

Напоминание

«Три мажора, две ошибки» разбирает движок и v4-API паузы — onStep, onDebugBreak, флаги debug на состояниях. Здесь я опираюсь на неё, не повторяясь слишком. Траектория v4 → v6 включает три брейкинг-мажора: переименование хука, ужесточение семантики halt и схлопывание lifecycle-тиков. Первые два всплыли в демо. Третий — в документации.

Демо: v4 → v5

Пока v4 уезжала в релиз, я начал собирать machines-demo — интерактивный отладчик Turing-машины и первый не-тестовый клиент движка.

Демо — естественный первый потребитель: у него двойная цель. Продуктовая — публичное распространение и демонстрация движка в действии. Техническая — обкатка изменений и проверка концепций на живой API-поверхности. Обе цели делают разработку демо неотъемлемой частью релизного цикла, а не опциональной добавкой к нему.

Демо задействовало оба хука одновременно: onStep заполнял буфер команд для UI-трейса на каждой итерации; onDebugBreak управлял циклом «пауза / продолжение».

Демо собиралось. Тесты проходили. Но писать его было неудобно, по двум причинам.

Во-первых, after-сработка onDebugBreak приходила с данными предыдущего yield’а — теми же, что предыдущий onStep уже показал. Демо обрабатывало одно и то же дважды, и вопрос «почему два хука для одного события?» задавал не я, а как будто сам код. Я открыл turing-machine-js#109 как RFC об отношениях этих двух хуков, перечислил четыре эскиза; резолюция сузилась до именования. onDebugBreak ставил целью использования «отладку», глагол же потребителя — «пауза». Переименование без зазрения совести и без алиаса. v5.

Во-вторых, в UI демо появился сценарий «приостановиться перед halt» — дать пользователю заглянуть в финальное состояние машины до того, как она завершится. Естественная реализация — флажок debug на самом haltState. Первый тест-кейс установил haltState.debug = { before: true, after: true }, потому что симметрия выглядела правильной. Срабатывал же только before. Хуже того: after-сработка на самой итерации, которая привела к halt, не доходила до обработки — цикл выходил, как только state.isHalt становилось true. turing-machine-js#108 разбил это на две части: восстановить потерянную after-сработку (баг); бросать исключение при записи в haltState.debug.after (API).

Обе претензии пришли со стороны потребителя. Демо не показал баг в коде — он показал формат взаимодействия с API. Имена не подходили под применение. Снисходительность к входным данным не соответствовала тому, что пользователь пытался сделать. Тесты сверяли поведение с собственной внутренней моделью движка — ок, зе́лено. Демо сверило поведение с ментальной моделью потребителя — и выдало две конкретные претензии (не ок).

Документация: v5 → v6

v5 уехала. README требовал обновления. Новый раздел про порядок диспатча должен был объяснить — словами, — когда срабатывают onPause(before), onStep и onPause(after) относительно той итерации, которую они описывают.

Первый честный абзац выглядел примерно так:

onPause(after, K) срабатывает на yield’е итерации K+1, с payload’ом, подставленным из снэпшота итерации K, до того как сработают onPause(before, K+1) или onStep(K+1).

Я какое-то время смотрел на это предложение. Короче не получалось. Предложение о подстановке — это не то, что читатель должен был встретить.

Код работал. Тесты проходили. Демо корректно потребляло хуки. Ошибка была не в этом — она была в форме диспатча, и эта форма становилась видна только с той стороны, где её приходилось формулировать словами.

Фикс схлопнул lifecycle: before(K) → step(K) → after(K) на одном и том же yield’е. Без подстановок. Без межитерационного планирования. Без финального добора для останавливающейся итерации (в «Трёх мажорах, двух ошибках» я перевёл это как «пост-цикловой добор»; сейчас, пожалуй, обошёлся бы покороче). Абзац README теперь звучит так:

На yield’е итерации K хуки срабатывают в lifecycle-порядке.

А такое предложение читатель проходит не задумываясь. turing-machine-js#119 уехал как v6.

Прямая цитата из предыдущей статьи:

Код работал, тесты проходили, документация была корректной. Просто дизайн был неправильным.

К этому хочется добавить: документация была корректной только при условии, что читатель смирится с тремя объясняющими предложениями, которые ему читать не следовало. Это не «корректная документация» — это документация, извиняющаяся за форму.

Ревью документацией поймало форму, не использование. Демо работало. Тесты проходили. Только давление прозы в этот раз вскрыло внутренние проблемы реализации.

Три ревью, три слоя

Опишем, что проверяет каждое:

  • Тесты сверяют код с самим собой. Внутренняя консистентность. Движок выдаёт то, что движок должен выдавать. Зелёные тесты — это база.

  • Первый настоящий потребитель сверяет код с ментальной моделью потребителя. Совпадает ли формат API с тем, что пользователь пытается сделать? Ревью реального взаимодействия с API привело к его изменению: переименованию и запрету halt-after.

  • Документация в виде прозы (не JSDoc, а связный README-нарратив) сверяет код с авторским объяснением. Есть ли у дизайна честное однопараграфное описание? Отсутствие такового заставило внимательно посмотреть на танец с подстановкой и отказаться от него.

Каждое ревью ловит то, что не ловит слой ниже. Тесты не ловят форму; потребитель не ловит проблемы взаимодействия, которые он умело может обойти; документация не ловит UX-неровности, которые ей упоминать не пришлось.

Стоимость асимметричная. Разработка настоящего потребителя — самое дорогое из трёх ревью; написание документации — самое дешёвое. И всё-таки даже самое дорогое из них обходится дешевле, чем переделывать API после того, как проблемы вскроются у пользователей: отсюда и «почти бесплатные» в заголовке. Настоящего потребителя нужно разработать до мажорного релиза — только это ревью делает API комфортным в использовании. Документация после этого ограждает то, что осталось.

Эвристики на следующий мажор

  1. Соберите первого настоящего потребителя до мажора. Не тест-фикстуру — а потребителя со своей ментальной моделью. Трудности, с которыми он сталкивается, — это те же трудности, с которыми потом столкнутся все ваши пользователи.

  2. Напишите параграф про порядок диспатча до того, как зафиксируете порядок диспатча. Если не получается одной фразой описать, что и когда срабатывает, — диспатч неправильный. Решения такого рода должны приниматься на этапе проектирования, а не документации, тогда когда не написано даже и строчки кода.

  3. Перечитайте документацию глазами незнакомца. Если параграф читается как извинение за форму — документация работает, она явила ошибку формы. Чинить надо форму, а не параграф.

Три мажора. Один README. Одно демо. Тестам сказать было нечего.


Код: turing-machine-js (движок) и machines-demo (первый не-тестовый потребитель, на котором всплыли v4 → v5).