Перейти к основному содержимому

Формат пака

Пак — контракт между генератором и раннером. Оба зависят только от packcore, поэтому формат меняется в одном месте, а не в двух приложениях.

packs/<практика>/
domain.json
tasks.json
materializations/<task_id>.json
migrations/
common/ создание схемы
tasks/<id>/ INSERT-ы вариантов данных
report/index.md
theme/
state.json
mock_llm/ заготовленные ответы модели для --mock

domain.json

ПолеЧто содержит
descriptionописание базы для студента
ddlSQL создания схемы
objectivesтемы курса: id, title, count: [min, max], required
totalсколько всего заданий: [min, max]
notesпожелания автора к данным и покрытию, уходят в промт
table_docsпояснения к таблицам и колонкам для студента

content_hash считается по всей области, кроме table_docs: тексты для студента можно править, не пересобирая практику.

tasks.json

ПолеЧто содержит
id, titleидентификатор и короткое имя
kindselect, dml или ddl
business_statementформулировка для студента, без имён таблиц
statementточная формулировка; по ней строятся проверки
objectivesидентификаторы тем курса
difficulty1–3
resultожидаемая форма результата для select
state_tablesтаблицы, состояние которых сравнивается, для dml
require_constructs, forbid_constructsограничения на текст решения

source_hash считается по всему заданию, кроме business_statement.

materializations/<task_id>.json

ПолеЧто содержит
task_id, source_hashк какой версии задания это относится
solution_sqlэталонное решение
variantsописания вариантов данных: id, kind, seed, quotas
checksсписок проверок: type, section, params
expectedожидаемый исход эталона на каждом варианте
negativesнамеренно неверные решения: label, sql

Элемент expected содержит своё для каждого типа задания: result_hash и result_rows для select, table_state_hashes и table_state_rows для dml, schema_snapshot для ddl.

Проверки

typeЧто сравнивает
schemaнабор и порядок колонок
cardinalityчисло строк: одна, много, допустимо ноль
result_exactрезультат построчно
result_hashхэш нормализованного результата
table_stateсостояние таблиц после dml
db_schemaструктуру схемы после ddl
sql_constraintsобязательные и запрещённые конструкции

Поле section делит проверки на public и sealed. Открытые студент видит по именам, скрытые существуют только на бэкенде.

state.json

{
"domain_approved": "9d6654cf…",
"tasks_approved": "39bc8483…",
"tasks_domain_hash": "9d6654cf…"
}

Три хэша, из которых складывается вся логика «устарело»: что утверждено как область, что утверждено как набор заданий и к какой версии области этот набор собран. Материализация сверяет свой source_hash с текущим заданием сама.

Нормализация результата

Перед сравнением результат канонизируется:

  • порядок строк приводится к каноническому, если задание не требует конкретного;
  • числа округляются до объявленной точности — 40 и 40.00 равны;
  • имена колонок сравниваются без учёта регистра;
  • NULL отличается от пустой строки и от нуля.

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

Совместимость

Версия движка данных записана в манифесте пака. Несовместимость по мажорной версии — отказ раннера запускать пак, а не молчаливое расхождение результатов. Имена токенов темы — отдельный контракт со своей версией в theme.json.