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

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Vulnerabilities – Threatpost
L
LINUX DO - 热门话题
H
Hacker News: Front Page
Hacker News - Newest:
Hacker News - Newest: "LLM"
L
Lohrmann on Cybersecurity
Cisco Talos Blog
Cisco Talos Blog
O
OpenAI News
S
Securelist
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
H
Heimdal Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
Microsoft Azure Blog
Microsoft Azure Blog
MyScale Blog
MyScale Blog
Webroot Blog
Webroot Blog
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
Latest news
Latest news
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic
D
Docker
D
DataBreaches.Net
A
About on SuperTechFans
T
Tor Project blog
V
V2EX
G
Google Developers Blog
博客园 - Franky
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
I
InfoQ
H
Help Net Security
V2EX - 技术
V2EX - 技术
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Security Affairs
SecWiki News
SecWiki News
The Register - Security
The Register - Security
人人都是产品经理
人人都是产品经理
NISL@THU
NISL@THU
小众软件
小众软件
B
Blog
T
Threatpost
P
Palo Alto Networks Blog
博客园 - 【当耐特】
L
LangChain 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 миллионов точек без потерь
Design by Contract в эпоху AI: как контракты Мейера защищают криптографию там, где тесты молчат
Miller83 · 2026-04-19 · via Все публикации подряд на Хабре

Средний

10 мин

2.7K

Кейс

Design by Contract Мейера не взлетел в 1986 из-за двойной работы. AI-агент убирает вторую половину. Я построил PKI-систему с аппаратным TRNG, формальными контрактами на криптографию и открытым репозиторием, чтобы это проверить.

1. Проблема: AI ломает быстрее, чем люди чинят

В марте 2026-го утекли внутренние документы Anthropic о модели Claude Mythos. Через пару недель они сами её анонсировали. Mythos нашёл 0-day в OpenBSD, который сидел в коде двадцать семь лет. Двадцать семь. В FFmpeg обнаружился похожий, шестнадцатилетней давности, а Linux kernel тоже зацепило. На поиск бага в OpenBSD ушло меньше пятидесяти долларов compute. FFmpeg до этого сканировали миллионы раз автоматическими инструментами, и ничего.

Ладно, допустим, это впечатляет. Но что с этим делать? Запретить AI искать баги не получится. Значит, нужно строить системы так, чтобы логические ошибки не доживали до продакшна.

Стандартный ответ: переписывать на Rust. Для memory corruption это и правда работает (хотя и не для всего legacy), ownership model не даёт скомпилировать use-after-free и buffer overflow, и баги в OpenBSD с FFmpeg были как раз из этой категории. Но вот в чём штука. Есть целый класс ошибок, которые ни один язык не видит, и это логические ошибки. Выбрал неправильный padding для RSA, компилятор молчит. Забыл проверить revocation сертификата или передал сырую entropy в DRBG без проверки качества, тесты зелёные. Потому что никто не написал тест на это.

Тесты вообще проверяют ровно то, что программист додумался проверить. Уязвимость в OpenBSD двадцать семь лет проходила все тесты. Все до единого.

Нужен подход, который работает не на уровне синтаксиса, а на уровне архитектурных гарантий. Который фиксирует “что система обязана делать” до первой строки кода. Не “как реализовать”, а “что гарантировать”. Разница принципиальная: реализацию можно переписать, а гарантия либо выполняется, либо нет.

Исторически, такой подход уже придумали. В 1986 году. Автор: Бертран Мейер. Design by Contract. И есть конкретная причина, почему вы скорее всего о нём не слышали.

Дальше: почему DbC не взлетел, что меняет AI-агент, и как это выглядит на реальной PKI-системе с открытым репозиторием.

2. DbC Мейера: почему не взлетело

Идея простая. Каждый модуль явно декларирует три вещи: что ожидает на входе (предусловия, PRE), что гарантирует на выходе (постусловия, POST), что никогда не нарушит (инварианты, INV). Например, функция деления: PRE: делитель ≠ 0, POST: результат × делитель == делимое. Просто, но формально.

Строго. Формально. И в mainstream не прижилось, что, в общем, предсказуемо.

Причина банальная: двойная работа. На практике это выглядит так: сначала пишешь контракт. Потом пишешь код. Потом пишешь тесты. Контракт это дополнительная нагрузка, которая не даёт немедленной отдачи. Когда горит дедлайн, контракты выбрасывают первыми.

В safety-critical областях DbC выжил. Ada/SPARK в авиации, ISO 26262 в automotive. По сути те же PRE/POST/INV, только под другими именами и с другим бюджетом. Там цена ошибки такая, что двойная работа оправдана. В обычной разработке: нет. И все это понимали.

Eiffel, язык Мейера со встроенными контрактами, остался нишевым. Microsoft Code Contracts для C#: заброшен. Java добавила assert в 1.4, но без обязательности. D language встроил контракты в синтаксис, и тоже не стал мейнстримом. Идея расползлась по assert’ам, аннотациям, типам. Но формальные PRE/POST/INV на уровне архитектуры так и не стали нормой.

Контракт

Пишет человек

Пишет человек

Код

Пишет человек

Пишет человек

Проверка

Компилятор Eiffel

Человек (тесты)

Итог

Двойная работа

Контракты выбрасывают

Мейер (1986)

Что получилось

40 лет DbC ждал момента, когда вторую половину работы можно будет отдать кому-то другому. И похоже, этот момент наступил.

Кстати, я не один это заметил. В последние пару лет пошли академические работы на стыке DbC и LLM. “A DbC Inspired Neurosymbolic Layer for Trustworthy Agent Design” (arxiv:2508.03665): контрактный слой между LLM и выходом. “Formal Specification and Runtime Enforcement for Reliable Autonomous AI Agents” (arxiv:2602.22302): ABC-контракты для AI-агентов. Fun2spec (openreview): LLM генерирует контракты для миллионов строк C/C++. В блогах пишут про “prompt contracts” и “files as contracts”.

Но все эти работы: либо теория без production proof, либо промт-инженерия без формальных PRE/POST/INV. Связку “DbC + AI-агент + криптография + открытый репозиторий” пока не показал никто. Мне было интересно попробовать.

3. Что меняет AI-агент

Человек пишет контракт. Агент берёт его и пишет код, тесты, проверки. А человек потом смотрит на 10 строк контракта вместо тысячи строк реализации и решает, всё ли правильно.

Собственно, всё. Агент берёт на себя реализацию и генерацию тестов, а двойная работа, которая убила DbC, исчезает. Контракт остаётся единственной задачей человека.

Контракт

Человек

Человек

Код

Человек

Агент

Проверка

Компилятор Eiffel

Агент + тесты + автоверификация

Почему не работало

Двойная работа

Делегировано

Мейер (1986)

С AI-агентом

На практике один цикл выглядит так. Пишу инвариант: “PKCS#1 v1.5 == ЗАПРЕЩЕНО”. Агент генерирует crypto_engine.py с RSA-PSS. Параллельно генерирует contract-тест, который пытается вызвать PKCS#1 v1.5 и проверяет, что система его отвергает. Тест прошёл, контракт соблюдён. Упал: агент правит реализацию, не контракт. Контракт: источник истины. Его не трогают.

Ошибка в контракте тоже возможна, конечно. Но в типичном случае проверить 10 строк декларации намерения, особенно если сверяешь с NIST или RFC, проще, чем искать логическую ошибку в 1000 строк реализации. Контракт это точка фокуса. Вместо вопроса “правильно ли написан код?” ты отвечаешь на вопрос “правильно ли я описал, что хочу?”. Второй вопрос проще.

4. Proof: PKI с аппаратным TRNG

Я построил PKI-систему с аппаратным генератором случайных чисел, и хочу рассказать как это было. Цель кейса: показать, что DbC + AI-агент работает не в теории, а на реальном fullstack embedded проекте с криптографией. От и до. На входе тепловой шум с ADC микроконтроллера. Он идёт в DRBG по NIST SP 800-90A, оттуда в генерацию ключей, потом CA выпускает сертификат X.509. Разработка шла на Windows, продакшн крутится на Linux ARM64 (RK3328, Cortex-A53), а firmware живёт на STM32.

Стек выглядит так: STM32G431 снимает тепловой шум с внутреннего ADC и отдаёт сырую энтропию через USB HID. На хосте (RK3328) Python-демон читает эти байты, прогоняет через health check по NIST 800-90B, и скармливает в HMAC-DRBG. Дальше CryptoEngine берёт выход DRBG и генерирует RSA/ECDSA ключи. KeyStorage шифрует приватные ключи AES-256-GCM и кладёт на диск. CA-сервис подписывает сертификаты. Пять модулей, каждый со своим контрактом на стыке.

Вот цифры. Главное здесь: две CRITICAL уязвимости найдены именно через контрактный подход, до продакшна.

Коммитов

131

Дни активной работы

11 (из 17 календарных)

Автор

1 человек

Тестов

62 contract + 15 HW + unit

MCU борды

3 (STM32G474, STM32G431, STM32H750)

Целевая платформа

RK3328 ARM64 (Cortex-A53)

Стоимость железа

~$129

Стоимость AI

1780₽ (~$16) за 30 сессий с трекингом

Метрика

Значение

Репозиторий открыт: github.com/vasilievsv/hw.pki-on-box

SELinux в enforcing, eBPF-фильтры, systemd sandboxing, всё как положено. По firmware: 12 пунктов криптоаудита по NIST 800-90B, все 12 закрыты, открытых ноль.

Разработка шла в несколько фаз. Сначала аудит прототипа и написание контрактов на каждый модуль. Потом реализация core: TRNG, DRBG, CryptoEngine, KeyStorage, CA-сервис, CRL. Параллельно contract-тесты, сначала на моках (62 теста), потом на реальном железе (15 HW-тестов). Отдельная фаза на firmware: три борды STM32, новая прошивка для G431, 12 пунктов криптоаудита. И финал: деплой на RK3328, пересборка ядра 5.10 с SELinux и eBPF, smoke-тесты на живой железке. Каждая фаза это отдельная сессия с агентом, со своей ролью и контекстом. Роли важны: тестировщик не пишет код, кодер не меняет контракты, архитектор не запускает тесты. Это не бюрократия, это способ не дать агенту уйти в сторону. Когда у сессии есть роль и контракт, агент работает в рамках. Без рамок он начинает “помогать” и ломает то, что уже работает.

5. Два контракта на двух стыках

Вся криптография в pki-on-box держится на двух контрактах, и каждый из них закрывает один архитектурный стык. Стыки выбраны не случайно: именно на границах модулей возникают логические ошибки, которые внутри модуля не видны. DRBG отдаёт байты, CryptoEngine их использует. Если на этом стыке не зафиксировать, какой padding допустим, ошибка неизбежна. Ниже упрощённые версии для иллюстрации, полные контракты в репозитории.

Первый, генерация ключей:

contract: key_generation
  PRE:
    - DRBG.seeded == true
    - DRBG.reseed_counter < max_requests
    - algorithm ∈ {RSA-2048, RSA-4096, ECDSA-P384, Ed25519}
  POST:
    - private_key.encrypted(AES-256-GCM)
    - nonce.unique()
    - public_key = derive(private_key)
  INV:
    - padding == RSA-PSS (подпись) | RSA-OAEP (шифрование)
    - PKCS#1 v1.5 == ЗАПРЕЩЕНО

Почему PKCS#1 v1.5 запрещён. Не каприз. Атака Блейхенбахера (1998) использует padding oracle в PKCS#1 v1.5 для восстановления plaintext. Это не теоретическая атака, её использовали на реальных системах. RSA-PSS и RSA-OAEP спроектированы так, чтобы этот класс атак был невозможен. Инвариант в контракте закрывает это на уровне архитектуры. До того, как кто-то случайно выберет v1.5 “потому что в примере на StackOverflow было так”.

Второй контракт, выпуск сертификата:

contract: certificate_issuance
  PRE:
    - issuer_ca.valid() && !issuer_ca.revoked()
    - csr.signature.verify() == true
  POST:
    - cert.serial.unique()
    - cert.signature.verify(issuer_ca.public_key) == true
    - cert.extensions.key_usage.set()
  INV:
    - cert_chain.depth <= max_path_length
    - root_ca.offline == true (air-gapped)

Автоматическая проверка через contract-тесты нашла две CRITICAL проблемы: неправильный padding (PKCS#1 v1.5 вместо RSA-PSS) и неправильный AES mode.

Почему обычные тесты это пропускают? Обе логические ошибки, и ни компилятор, ни линтер тут бесполезны. Обычные unit-тесты, может, и поймали бы, но для этого кто-то должен был догадаться их написать. А contract-тесты генерируются из формальной спецификации. Им не нужно, чтобы программист о чём-то догадывался.

Реализация: test_crypto_engine_contract.py

Вот как выглядит один из инвариантных тестов в коде:

class TestCryptoEngineInvariants:

    def test_rejects_pkcs1v15_padding(self, crypto):
        priv, pub = crypto.generate_rsa_keypair(bits=2048)
        data = b"invariant check"
        sig = crypto.sign_data(priv, data)
        # PSS обязан работать
        pub.verify(sig, data, padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.AUTO
        ), hashes.SHA256())
        # PKCS1v15 обязан сломаться
        with pytest.raises(Exception):
            pub.verify(sig, data, padding.PKCS1v15(), hashes.SHA256())

Тест не проверяет “работает ли подпись”. Он проверяет инвариант из контракта: система подписывает RSA-PSS, и PKCS#1 v1.5 обязан сломаться при верификации. Если кто-то случайно переключит padding, этот тест упадёт. Не потому что программист догадался, а потому что контракт потребовал.

6. Как это выглядит в работе

Процесс не линейный, но если упрощать, примерно так.

Сначала я формулирую контракт, PRE/POST/INV на стыке модулей. Для меня это самая сложная часть, потому что надо заставить себя думать не про код, а про гарантии: что система обязана делать, что ей запрещено.

На практике это выглядит так. Открываю новую сессию, указываю роль (coder, tester, architect), загружаю контекст предыдущей работы. Пишу контракт в yaml: PRE, POST, INV. Иногда контракт рождается за пять минут, если стык понятный. Иногда сижу полчаса, потому что не могу сформулировать инвариант. Это нормально. Если не можешь записать гарантию в одну строку, значит ещё не понимаешь, что именно система должна делать.

Дальше агент берёт этот контракт и генерирует реализацию, а параллельно ещё и contract-тесты, каждый из которых проверяет конкретное postcondition или пытается нарушить инвариант.

Тест упал, агент правит реализацию. Контракт не трогает. Контракт меняю только я, и только если понимаю, что сам ошибся в спецификации. Нарушение контракта это не warning и не TODO, это полная остановка. Код не мержится, пока все postconditions не зелёные.

Конкретный пример. В контракте key_generation стоит INV: padding == RSA-PSS. Агент сгенерировал CryptoEngine, и первая версия sign_data() использовала PKCS1v15. Contract-тест test_rejects_pkcs1v15_padding сразу поймал нарушение: верификация через PSS упала, потому что подпись была создана с другим padding. Агент переписал sign_data() на PSS, тесты позеленели. Весь цикл: контракт уже был, тест уже был, человек не участвовал. Я увидел зелёный прогон в логе и пошёл дальше.

На pki-on-box весь этот цикл занял 52 сессии с агентом (сессия = один чат с одной ролью и задачей), итого 1780₽ на compute. Embedded, DevOps и крипто одновременно, один человек. Без агента и контрактов я бы закладывал 60+ часов, и это оптимистично. Три домена (firmware, backend, infra), три операционки (Windows для разработки, Linux ARM64 для продакшна, bare metal для MCU). Контракты формализуют ожидания заранее, и агент реализует их без отклонений. Не надо объяснять ему по второму кругу, почему PKCS#1 v1.5 нельзя. Это записано в INV.

7. Ограничения и честные оговорки

Работает не с любой моделью. Модель должна удерживать формальные ограничения на протяжении длинной сессии и не забывать инварианты на пятидесятом сообщении в чате. Frontier-модели с этим справляются. Локальные на 7B параметров пока не тянут, но это вопрос времени.

Контракт тоже можно написать неправильно, и это важно понимать. Если в INV забыть запретить CBC mode для AES и оставить только GCM, агент послушно реализует CBC, и формально контракт будет соблюдён. Контракт не заменяет экспертизу. Он формализует то, что ты уже знаешь. Если не знаешь, формализовать нечего. На pki-on-box я дважды ловил себя на том, что контракт неполный: один раз забыл про AES mode (поймал на ревью), второй раз не указал минимальную длину entropy seed для DRBG. Оба раза фикс контракта занял одну строку, но без него агент бы генерировал формально корректный, но уязвимый код.

DbC не серебряная пуля. Он закрывает логические ошибки на архитектурных стыках, и только. Memory corruption это к Rust, race conditions к модели памяти, supply chain к совсем другим инструментам. И ещё: контракты работают на уровне модулей, не на уровне отдельных функций. Писать PRE/POST на каждый геттер бессмысленно. Контракт имеет смысл там, где есть архитектурный стык и цена ошибки высокая.

Заключение

Мейер придумал Design by Contract сорок лет назад. Идея была правильной, но момент не тот, и двойная работа убивала adoption.

Сейчас, в 2026, AI забирает вторую половину этой работы. Человек формулирует контракт, а агент реализует и проверяет. То, что раньше было “слишком дорого”, превратилось в “единственное, что нужно делать”.

У меня получилось 131 коммит за 11 дней, $129 на железо, 1780₽ на compute. И две CRITICAL, которые нашлись именно через контрактный подход, до продакшна.

Mythos показал, что AI ломает быстрее, чем люди чинят. От логических ошибок язык не спасает, а тесты проверяют только то, о чём додумался программист. Контракты работают иначе: они фиксируют то, что система обязана гарантировать. Додумался кто-то написать тест или нет.

Сорок лет назад Мейер предложил записывать эти гарантии явно. Тогда это стоило слишком дорого. Сейчас вторую половину работы берёт на себя агент, а контракт остаётся единственным артефактом, за который отвечает человек. Десять строк yaml вместо тысячи строк кода.

Если у вас в проекте есть криптография, платёжная логика, или любой другой код где ошибка в логике опаснее ошибки в памяти, попробуйте написать один контракт на самый критичный стык. PRE/POST/INV, десять строк. Дайте агенту реализовать и сгенерировать тесты. Посмотрите, что он найдёт.

Ссылки:

  • Meyer B. “Object-Oriented Software Construction” (1988, 2nd ed. 1997)

  • Meyer B. “Applying Design by Contract” (IEEE Computer, 1992)

  • Bleichenbacher D. “Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS#1” (CRYPTO 1998)

  • NIST SP 800-90A: Recommendation for Random Number Generation Using Deterministic Random Bit Generators

  • NIST SP 800-90B: Recommendation for the Entropy Sources Used for Random Bit Generation

  • “A DbC Inspired Neurosymbolic Layer for Trustworthy Agent Design” arxiv:2508.03665

  • “Formal Specification and Runtime Enforcement for Reliable Autonomous AI Agents” arxiv:2602.22302

  • Fun2spec: Code Contract Synthesis At Scale openreview

  • Contract-тесты: test_crypto_engine_contract.py

  • pki-on-box: github.com/vasilievsv/hw.pki-on-box