Скилл Reference

Контракты кода

Открытый формат директив @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. Ревью-агенты разбивают списки через точку с запятой, объединяют повторяющиеся ключи и убирают дубликаты имён.