Контракты кода
Открытый формат директив @cc, размещающих структурированные допущения и требования рядом с кодом — спецификация, фокус внимания и верификация для людей и агентов, обеспечиваемые CLI cc-check.
Обзор
Code Contracts — простой открытый формат для указания структурированных допущений и требований, размещённых рядом с кодом, для более быстрой и качественной разработки ПО с участием агентов. Контракт записывается как директива @cc внутри документирующего комментария, обычно прикреплённая к объявлению функции, класса или метода:
/**
* @cc [owner:spolu,label:product] balance-pre-and-fail
* `from.balance` is expected to be greater than or equal to `invoice.amount`, fails with
* `InsufficientBalanceError` otherwise.
*/
export async function payInvoice(invoice: Invoice, from: Account): Promise<PaidInvoice> {
...
}
Зачем нужны контракты кода
Контракты кода пишутся и используются и людьми, и агентами для рассуждения о коде. Они служат трём целям:
- Спецификация — в отличие от отдельных файлов продуктовой или системной спецификации, которые расходятся с кодом и труднее обнаруживаются, контракты встроены локально. Люди рассуждают о поведении, не вникая в детали реализации; агенты используют их, чтобы направлять реализацию и показывать допущения людям и будущим агентам.
- Внимание — контракты сокращают циклы, нужные для рассуждения о коде, структурированно выделяя допущения и инварианты, экономя человеческое внимание как узкое место.
- Верификация — их структура и гранулярность позволяют инструментам проверять соответствие и упрощают поддержание кода со временем, давая агентам сигнал верификации, улучшающий их работу.
Инструментарий
CLI cc-check (npm install --global @spolu/cc-check) предоставляет:
cc-check format [file-like]— сообщает о некорректном синтаксисе@ccи дублирующихся ID контрактов в поддерживаемом исходном файле или файлеCONTRACTS. Без указания пути рекурсивно проверяет все поддерживаемые файлы в текущей директории. Никогда не переписывает файлы и не оценивает прозу контракта или соответствие реализации.cc-check list <file-like|location-like>— выводит контракты, прикреплённые к объявлениям в исходном файле, либо контракты, применимые к объявлению, содержащему указанное место в исходном коде, и его предкам. Контракты из родительских файловCONTRACTS, привязанные к директории, включаются по умолчанию; флаг--no-globalих исключает.
Спецификация и грамматика
Директивы @cc извлекаются из документирующих комментариев на любом поддерживаемом языке; перед парсингом убираются оформление и разделители комментария (/**, */, //, ///, тройные кавычки Python-докстрок, ведущие *). Каждая директива определяет один контракт, обычно размещённый рядом с объявлением функции, класса или метода.
Контракты, не привязанные к объявлению, живут в файле с именем CONTRACTS и применяются ко всему коду в директории этого файла и её потомках — типичный случай: директориальные правила вроде архитектурных границ, ограничений на зависимости или требований безопасности:
@cc [owner:spolu,label:architecture] database-access-thru-resources
Database accesses must happen exclusively through `Resource`-like interfaces.
@cc [owner:spolu,label:security] no-sensitive-data-logging
Credentials, tokens, secrets and user data must not be logged.
Директива — это @cc, за которым следуют опциональные метаданные в квадратных скобках и ID контракта: @cc [owner:spolu,label:product] balance-post. Ключи метаданных расширяемы; известные — owner, notify, label. У контракта может быть несколько владельцев, получателей уведомлений и меток; несколько значений одного атрибута разделяются точкой с запятой ([owner:spolu;tdraier,label:product]) вместо повторения ключа, хотя повторяющиеся ключи тоже допустимы.
Текст прозы непуст и продолжается до конца документирующего комментария, следующей директивы @cc в файле CONTRACTS или до конца этого файла. Он может занимать любое число строк; базовый формат не предписывает словарь, форму предложений, модальность или нотацию требований, хотя обычно предполагается Markdown.
ID контрактов уникальны и стабильны в пределах объявления, к которому они прикреплены (тот же ID может повторяться на другом объявлении); в файле CONTRACTS ID уникальны и стабильны в пределах этого файла и всех родительских файлов CONTRACTS. Один документирующий комментарий несёт ровно одну директиву @cc, но несколько последовательных комментариев-контрактов могут быть прикреплены к одному объявлению.
Семантика owner и notify
owner перечисляет имена пользователей GitHub, которых уведомляют при изменении или удалении существующего контракта; введение нового контракта владельцев не уведомляет. notify перечисляет пользователей, которых уведомляют при каждом обнаруженном нарушении контракта. Владельцы не уведомляются о нарушениях автоматически, если они также не указаны в notify. Ревью-агенты разбивают списки через точку с запятой, объединяют повторяющиеся ключи и убирают дубликаты имён.