Skip to content

rational-development

Композиция корректности. Как собрать рабочую систему из сервисов с подтверждённой спецификацией

«Программы должны быть написаны так, чтобы их корректность можно было доказать, а не угадать тестированием.»

— Niklaus Wirth, Systematic Programming

Это финальная статья серии про корректность программ. В предыдущих мы по кирпичу собирали модуль, сервис и спецификацию:

Сервис в результате этой дисциплины имеет спецификацию, подтверждённую тестами в изоляции. Юнит-тесты по формуле «1 + ветки антецедента» подтверждают, что каждый модуль ведёт себя по своему контракту. Компонентные сценарии в Gherkin через Docker Compose подтверждают, что сервис как чёрный ящик ведёт себя по OpenAPI/AsyncAPI и по карте режимов отказа в README.

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

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

И вот здесь индустрия ставит поверх всей пирамиды ещё один этаж: интеграционные тесты, e2e на Playwright, системные стенды, регрессионные прогоны на стейджинге. Тысячи сценариев. Часы прогонов. Десятки человеко-месяцев на поддержку.

В этой статье покажу, что весь этот этаж — компенсация отсутствия двух простых вещей: машиночитаемого контракта и канареечного деплоя. При наличии обоих корректность системы выводится из корректности сервисов и совместимости их контрактов. Без e2e, без стейджинга, без бесконечной регрессии.

Два скилла дисциплины. Скилл проектирования для opus и скилл реализации для sonnet

«Дисциплина — это мост между целями и достижениями.»

— Jim Rohn

В предыдущей статье мы вывели дисциплину: программа = дерево модулей с контролем диапазонов, юнит-тесты по формуле «1 + ветки антецедента», корректность доказывается по построению. Там была теория, оформленная как практическая методичка.

Этой статьёй закрываем разрыв между «понятно как» и «понятно что положить в Claude Code». На выходе — два самостоятельных артефакта:

  • program-design.skill — скилл для opus. Принимает функциональное требование, отдаёт пакет проектной документации.
  • program-implementation.skill — скилл для sonnet. Принимает пакет, отдаёт код по тикетам через Trunk Based Development.

Связующая нить — vertical slice architecture: каждый вход API режется в отдельный поток сверху вниз, со своим адаптером, своей бизнес-логикой, своим модулем I/O. Это резко упрощает и проектирование, и сборку бэклога, и параллельную работу нескольких агентов.

В следующей статье оба скилла прикручиваются к ubik-life/passkey-demo-api. Здесь — только сами скиллы и обоснование, почему они выглядят именно так.

Дисциплина проектирования программ. Скилл для opus и бэклог для sonnet

«Тестирование программ может служить для доказательства наличия ошибок, но никогда не докажет их отсутствия.»

— Edsger W. Dijkstra

Это практическая статья для вайб-кодера и джуна. Без академической мути. Цель — дать одну дисциплину проектирования, по которой opus проектирует программу, а sonnet получает готовый бэклог и реализует его в Claude Code.

Статья — концентрат четырёх разборов на codemonsters.team: структурное программирование, модульность, правильность программы, компонентные тесты.

Если ты дисциплинированно выполнишь то, что описано ниже, у тебя будет программа, которая работает правильно по построению. Не потому что её тщательно тестировали — а потому что её правильно спроектировали.