# Часть XXIII. Cases, snapshots и evaluation ## 168. Case file ```law language "law.core" version "0.1"; package kz.bvr.cases version "1.0.0"; namespace "urn:kz:law:bvr:cases"; case Project17 { context { jurisdiction KZ; legal_time @2026-08-25; temporal_resolution_policy KZ_CIVIL_DAY_RESOLUTION; decision_time @2026-08-25T14:30:00+05:00; knowledge_time @2026-08-25T14:00:00+05:00; timezone "Asia/Qyzylorda"; calendar KZ_2026; interpretation OfficialBvrReading; mode compliance; } const project: BlastProject = entity_ref("urn:case:project:17"); const operator: Company = entity_ref("urn:case:company:17"); // Событие — ссылка на индивид §79; его intrinsic payload (`time`) // поставляет закреплённый snapshot дела, а не запись в исходнике. const blast: BlastEvent = entity_ref("urn:case:blast:17"); assert operator_of(project, operator); assert charge_mass(project, 500 kg); assert blast_occurs(project, blast); assert approved(project) { evidence APPROVAL_DOCUMENT_17; } assert measured_safety_distance(project, blast, 280 m) { evidence MEASUREMENT_17; } } ``` Имя ЧЛЕНА АВТОМАТА §201.1 (состояния либо перехода) дело пишет так же, как его пишет сама программа, — голым именем; разрешается оно по ТОЙ ПРОГРАММЕ, к которой дело предъявлено, её таблицей членов. Программа при этом остаётся вне дела (§169): предъявляет её вызывающий, и без предъявления член не разрешается вовсе. Имя члена уникально в пакете статически (§160.2, `LDC-E1351`), и таблица членов программы, прошедшей проверку, однозначна; имя, принадлежащее двум процедурам предъявленного CLIR сразу (собранного вручную), не разрешается ни в программе, ни в деле — выбор процедуры за автора реализация делать НЕ ДОЛЖНА (`LDC-E1330`, DECISION-0156 §8.8). ### 168.1. Ground-термы аргументов и запись Rational Аргументы assertion §71 (в пакете и в деле) и literal-аргументы запроса §172 — ground-термы: сопоставление фактов и запросов ведётся по каноническим значениям, а не по синтаксису термов. У `Rational` §35 собственного литерала нет; его единственная поверхностная форма — деление целочисленных литералов §58 (`2 / 1`, `10 / 3`). В ground-позиции эта форма ЕСТЬ запись значения и понижается в каноническое `Rational`-значение (E-0005), а не в вычислимый терм: терм, хранимый синтаксически, никогда не совпал бы со значением, выведенным правилом, и утверждение молчаливо не участвовало бы в выводе. Запись обязана быть канонической: числитель и знаменатель взаимно просты, знаменатель положителен. Неканоническая пара (`10 / 4`, `3 / 0`) отклоняется диагностикой `LDC-E1324` с указанием канонической формы — молча сокращать значит подменять записанное автором, молча хранить — подменять значение мёртвым термом. Знак — часть числового литерала: `-60`, `-26.0`, `-100.00 KZT`, `-3 / 2` записывают отрицательные значения (у Rational знак живёт в числителе, канон E-0005). Операции унарного минуса над не-литералом (`-x`) в срезе 0.1 нет. Мгновение §19 в ground-позиции — тот же темпоральный литерал `@…`, вид `Instant` выводится по наличию времени. Прочие вычислимые термы в ground-позициях (`if`, вызов функции, агрегат, арифметика вне Rational-записи) отклоняются диагностикой `LDC-E1325`: терм, сохранённый синтаксически, в сопоставлении значений не участвовал бы, и утверждение молча выпадало бы из вывода — тот же класс обманки, что у Rational до свёртки. ### 168.2. Оси контекста transport-среза Инлайн-контекст дела и блока `given` §267 понижается по закрытому словарю осей. Временны́е оси и `timezone` ложатся в `context` документа; две оси — политики вычисления §170 и ложатся в `options` документа, потому что §89 и E-0001 называют контекст их поверхностным носителем, а исполняют их обе реализации из `options`: - `interpretation ;` — выбор прочтения §152; повторяемо (несколько осей — несколько выбранных прочтений); понижается в отсортированный список `options.selectedInterpretations` полными StableId. Существование прочтения проверяет ИСПОЛНЕНИЕ (обе реализации отвечают issue «не объявлена в пакете») — при lowering программа не предъявлена (§169). Значение — локальное имя либо `пакет::Прочтение` (DECISION-0152 §7): прочтение ЧУЖОГО пакета адресуется той же квалификацией §23, что и у оси `calendar` ниже, и разрешается против resolve-контекста мира с проверкой состава экспорта §24 и вида цели по `exportKinds` — только `pub interpretation`. Без этого группа §155, собранная у соседа, была бы неразрешима из дела потребителя: при `exactly_one` каждое такое дело получало бы `INTERPRETATION_REQUIRED` §156, неотличимый от опечатки в имени; - `calendar ;` — выбор `calendar_snapshot` §85; скалярная и неповторяемая, понижается в `options.calendarSnapshot` полным StableId. Существование узла проверяет исполнение, поскольку при lowering программа не предъявлена; повтор и значение, не являющееся идентификатором, дают `LDC-E1307`. Без оси один узел выбирается автоматически, два и более дают `AMBIGUOUS_CALENDAR` до вычисления, а неизвестное имя — отказ с StableId; - `on_accepted_conflict halt;` — политика E-0001; единственное значение — `halt`, любое иное отклоняется при lowering: политика, записанная с опечаткой, была бы молча инертна, и дело исполнялось бы под другой семантикой конфликтов, чем читается. Ось вне словаря — предупреждение `LDC-E1307` «пропущена», как и прежде. #### Ось `mode` — режим оценки §171 (DECISION-0165) `mode <имя>;` — скалярная и неповторяемая ось; понижается в `case.options.mode`. Словарь значений закрыт перечнем §171: `advisory`, `compliance`, `regulatory`, `simulation`, `audit`. Имя вне перечня либо повтор оси — статический отказ `LDC-E1353`, а не предупреждение: опечатка в режиме молча отключала бы приём `assumed_for_simulation` §73, и дело исполнялось бы под другой политикой допущений, чем читается. Без оси действует умолчание реализаций (`audit`); схема запроса ограничивает `case.options.mode` тем же перечнем, поэтому значение вне словаря отвергается и по wire-каналу. #### Именованная ось: политика сроков §86 В 0.2 контекст несёт только ссылку на именованную закреплённую политику §86: ```law deadline policy KZ_DEFAULT_DEADLINES_2026 { start_count same_day; include_end true; roll no_roll; } case Historical1993 { context { legal_time @1993-03-12; deadline_policy KZ_DEFAULT_DEADLINES_2026; } } ``` Ось понижается в поле `deadlinePolicy` как полный StableId узла `deadline_policy`; профиль §89.1 несёт ту же ссылку, а уровни по-прежнему сливаются field-wise. Имя должно обозначать локальную декларацию политики: необъявленная ссылка — статический `LDC-E1332` до исполнения. Политика ЧУЖОГО пакета адресуется квалификацией `пакет::Политика` — той же, что у осей `calendar` и `interpretation` выше (DECISION-0165 §1.8): имя разрешается против resolve-контекста мира с проверкой состава экспорта §24 и вида цели по `exportKinds` — только `pub deadline policy`. Неразрешённая квалифицированная ссылка — `LDC-E1105`; экспортированное имя иного вида — `LDC-E1357`. Без этого дело, исполняемое над корпусной политикой, обязано было бы переписывать её у себя, и две копии расходились бы молча. Старая `deadline_policy { … }` является замороженной формой 0.1. В режиме совместимости 0.1 она по-прежнему понижается в inline record; в 0.2 она отвергается `LDC-E1333`, а не поддерживается вторым транспортом. Таким образом расхождение §13 ↔ прежний §168.2, названное DECISION-0077 §2.2, закрыто одной канонической формой. Неполная или неверно типизированная запись отвергается в самой декларации политики теми же статическими проверками §86. #### Именованная ось: политика темпорального разрешения §82.1 `temporal_resolution_policy <Имя>;` — скалярная и неповторяемая ось, ссылка на локальную декларацию §82.1; понижается в `options.temporalResolutionPolicy` полным StableId. Ось стоит в `options`, а не в `context`, по тому же основанию, что `calendar`: это ССЫЛКА на узел программы, а не значение временно́й оси, и caseHash обязан зависеть от выбора одинаково у всех хостов. Необъявленная ссылка — статический `LDC-E1332`, как у политики сроков. Существование узла проверяет исполнение: без оси единственная политика выбирается автоматически. Отличие от оси `calendar` — в том, КОГДА поднимаются `MISSING` и `AMBIGUOUS`. Календарь §85 читает каждая операция сроков §86, поэтому `AMBIGUOUS_CALENDAR` поднимается до вычисления по факту двух узлов. Политику §82.1 читают только СМЕШАННЫЕ сравнения, и её отказы поднимаются ТОЛЬКО когда разрешение потребовалось: `Date` в поле `time` события §79.1, сравнение `Date` с `Instant`, границы `over` §124.4.1 либо `window` §138 в датах против Instant-событий. Тогда ноль политик даёт `TEMPORAL_RESOLUTION_POLICY_MISSING`, а две и более без оси — `AMBIGUOUS_TEMPORAL_RESOLUTION_POLICY`; дело, не потребовавшее разрешения, исполняется при любом их числе (§82.1, errata E-0143). Квалификация `пакет::Политика` допускается по тому же правилу, что у политики сроков (DECISION-0165 §1.8; вид цели — `pub temporal resolution policy`). ### 168.3. Единый типизированный `EvaluationRequest` Нормативная граница исполнения имеет ровно одну форму: `evaluate(request: EvaluationRequest)`. Её закрытая wire-схема — `evaluation-request.schema.json`; неизвестное поле отвергается до любого вывода кодом `EVALUATION_REQUEST_INVALID`. Python- и Rust-API, CLI, WASM, FFI, MCP и Constructor обязаны сначала собрать этот тип и не имеют параллельной перегрузки `evaluate(ir, case, query, options, …)`. `EvaluationRequest` содержит `ir`, `case`, `query` и явную semantic version. Семантические опции имеют единственный носитель — `case.options`; второе верхнеуровневое поле `options` запрещено. Поэтому manifest и caseHash не могут зависеть от того, через какой хост был вызван движок. Pinned calendar resource, external snapshots, ExecutionReceipt и `editions_as_presented` §92 (errata E-0167) являются transport-полями запроса. Они не вкладываются в `case.options`: календарные байты и receipt не входят в caseHash, а external snapshots покрываются своими пинами и разделом manifest §170. Адаптер хоста может читать файл или буфер, но перед evaluation обязан закончить это чтение и передать полученное значение в `EvaluationRequest`; движок не обращается к ambient clock, filesystem или сети (§211). Снимки, предъявленные сценарию §267, остаются тем же транспортом; пин их содержимого — объявленный `contentHash` в манифесте семьи — обязателен, а сам снимок обязан нести `programHash` предъявленной программы (§47.2, DECISION-0244). `editions_as_presented` в `case.options` не вкладывается по тому же основанию: это свойство ПОДАННОЙ ПРОГРАММЫ (её состав уже спроецирован вызывающим), а не опция дела, и `caseHash` от него не зависит — одно и то же дело законно исполняется и по праву своей даты, и по предъявленному составу редакций. В манифест §170 и `semantic_hash` значение входит: два разных ответа обязаны различаться хэшем воспроизводимости. **Строка профиля канона (DECISION-0170).** У пакета-дела с названным профилем §170.1 подготовка `ask` пишет в `case.options.jurisdictionProfile` строку `"/#sha256:<64 hex>"` из блока `profile` лока. Это единственное объявленное исключение из правила §168.4 «всё, что входит в `caseHash`, пишет понижение дела»: граница проходит между ПОНИЖЕННЫМ `case` (`lawc lower-case`, строки нет) и ПОДГОТОВЛЕННЫМ `case` (`ask --out`, строка есть); шаг детерминирован по локу и повторная подготовка идемпотентна. Строка входит в `caseHash`, `manifest`, `semanticHash` и `resultHash` намеренно. Без профиля поле в `case.options` не пишется. Строка, уже стоящая в `case.options` понижения и не равная локу, — `LDC-E1367`; `eval` сохранённого запроса лока не имеет и проверяет только грамматику строки — существования и состава профиля он не доказывает. ### 168.4. Пакет-дело и операция `ask` (DECISION-0165) Пользовательское состояние живёт в обычном пакете §10 — **пакете-деле**: `law.toml` с зависимостями, `law.lock` с пинами §11, корень `.law`, одно или несколько дел `.lawcase`, необязательные сохранённые вопросы §172 и тесты §267. Нового вида узла, конструкции `world` и отдельного формата состояния нет: «мир» здесь — программа §23 из закреплённых пакетов, дело — её вход. Состав корня пакета-дела закрыт: заголовок пакета, `import`, метаданные и декларации политик (`deadline policy` §86, `temporal resolution policy` §82.1, `evidence policy` §78.2, локальный `calendar snapshot` §85). Нормативные и структурные декларации (правила, нормы, приоритеты, ограничения, процедуры, отношения и типы, package-level `assert`, `facts`) в корне пакета-дела — статический отказ `LDC-E1355` при подготовке `ask`; проверка идёт по всем `.law` корня после раскрытия развёрток §279, а не по имени файла. Нормы пользователя оформляются отдельным пакетом с явным импортом и пином: ответ по праву, дописанному самим спрашивающим, должен быть виден по составу мира — `envelope.imports` корня и конверту `ask`, — а не спрятан в корне. Дела объявляются секцией `[[cases]]` манифеста (`name` — декларация `case`, `path` — файл внутри пакета); это метаданные обнаружения по образцу `[[tests]]` (DECISION-0127), в нормативную схему манифеста они не входят. Каждая пара (путь, имя) регистрируется ровно один раз; осиротевший `.lawcase` в границах пакета, запись без файла или без одноимённой декларации, дубль — отказ `LDC-E1354`. Вложенный пакет — свой корень; `deps/` и готовые выпуски авторскими делами не являются. Операция `ask` — единственная форма исполнения пакета-дела у всех хостов: `пакет + выбранное дело + вопрос + явные ресурсы → проверка пинов → понижение программы и связывание мира → понижение дела и вопроса под предъявленным контекстом → EvaluationRequest §168.3 → evaluate`. Программа — корень и его полное закреплённое замыкание; сложение узлов без объявленного импорта не допускается, а лок, закрепивший пакет вне транзитивного замыкания импортов корня, отвергается `LDC-E1358` до связывания. Всё, что входит в `caseHash`, пишет понижение дела: хост ничего не дописывает в `case.options` (единственное исключение — строка профиля канона, §168.3). **Библиотека, лок, импорты, мир (DECISION-0170).** Обозначения: **B** — развёртка профиля §170.1, названного корнем; **L** — `lock.packages`; **C** — транзитивное замыкание фактических `import` корня, построенное обходом `imports` CLIR из L, начиная с `import`-деклараций заголовка корня (без подтверждающих импортов прелюдии `law.std.*`; они доступны разбором до понижения, поэтому проверка не зависит от порядка шагов); **W** — пакеты исполняемого мира без корня. | Условие | Без профиля | С профилем | Код | |---|---|---|---| | состав лока | L = C | L = B | `LDC-E1358` / `LDC-E1367` | | импорты в локе | C ⊆ L (следует) | C ⊆ L | `LDC-E1367` | | мир | W = C | W = C | `LDC-E1358` | Профиль — граница допустимой библиотеки, НЕ состав мира: закреплённый, но не импортированный пакет B в W не входит — ни его нормы, ни факты, ни календари, ни единицы измерения (в том числе при нормализации единиц до связывания). `envelope.imports` корня — только его прямые импорты. Проверки стоят в подготовке до связывания. Материализованы в `deps/` только пакеты C; замкнутость B сверяется по CLIR реестра (§11, П14). Порядок диагностик при нескольких нарушениях (первый найденный — отказ): схема артефакта и дескриптора профиля → профиль против лока (`LDC-E1367`) → граница §10 (`LDC-E1366`, три перечня) → пины развёрток и ресурсов (`LDC-E1340`, `LDC-E8704`) → импорты (`LDC-E1110`, `LDC-E1111`) → мир (`LDC-E1358`). Понижение дела получает тот же resolve-контекст, что и программа: квалифицированные имена дела разрешаются в StableId зависимостей, без контекста ссылка отказывает `LDC-E1105` (E-0126) и никогда не остаётся строкой. Один `.lawcase` под одним закреплённым контекстом даёт одни канонические байты `case.json` и один `caseHash` по любому пути понижения — это следствие §168.3 (manifest не зависит от хоста), а не удобство. Вопрос принимается JSON-документом `query.schema.json` либо строкой `evaluate <выражение>;` в грамматике `test_item` §267.2; обе формы дают один канонический `query` с одним `queryId` (§172). Ожиданий у самостоятельного вопроса нет. Хост не строит программу сам, не фильтрует факты и не вычисляет право; все входы читаются до входа в evaluator (§211). Отказ подготовки отличим от вычисленного `NEITHER`/`BOTH`, `REQUIRES_JUDGMENT` и `RESOURCE_LIMIT` кодом и конвертом, одинаковыми у всех хостов. Документ дела (PDF, скан, письмо) — ресурс лока вида `document` с `contentHash` точных байтов; evidence §74 ссылается на него полем `uri` и обязан нести тот же `content_hash`; расхождение или отсутствие записи в локе — `LDC-E8704`. Файл в каталоге без evidence фактом не становится. **Сахар факта хоста (DECISION-0360).** Наружный вызов, у которого нет полного `Case`, передаёт факты массивом. Элемент — `$defs/FactInput` `evaluation-request.schema.json`: `predicate`, `args`, необязательные `negated`, `package`, `judgment` и `provenance`. `provenance` несёт `origin` (по умолчанию `case_input`, перечень §73 не растёт), `evidence` (StableId документа), `span` (`page`, `quote`, `offset`), `extractor` (`name`, `version`, `confidence`) и моменты `observedAt` / `recordedAt`. Хост понижает это в assertion: `origin` и `evidence[]` — поля узла; извлекатель — ProvenanceEdge `was_generated_by` с `attributes` `{extractor, version, confidence}` и `target` `urn:extractor:`; документ — `was_derived_from` на тот же StableId, в `attributes` страница, цитата и смещение. Сам документ и опоры живут массивами `evidence[]` и `supportEdges[]` запроса: один документ на много фактов, цитата и уверенность остаются у факта. Число `confidence` ядро не читает. Хост кладёт его в `payload.confidence` документа термом Decimal, если ключа ещё нет; порог применяет EvidencePolicy пакета через `field confidence` (§78.2.1). Без объекта `provenance` понижение прежнее. Извлечённый факт (`was_generated_by` с ключом `extractor`) при `origin case_input` и пустом `evidence` входит в поддержку как обычный `case_input` и даёт warning `FACT_WITHOUT_EVIDENCE`. Это не отказ и не новый origin. `adjudicated` с объектом `judgment`, чей `authority` не совпал с декларацией отношения, по-прежнему не входит в поддержку (`JUDGMENT_AUTHORITY_MISMATCH`, E-0089). ```json { "predicate": "ground_disturbed_rock", "args": ["urn:case:fictional:building-1"], "provenance": { "origin": "case_input", "evidence": "urn:case:fictional:plan#doc", "span": { "page": 12, "quote": "Грунт в основании здания — нарушенные скальные породы.", "offset": 0 }, "extractor": {"name": "laya", "version": "1", "confidence": "0.91"} } } ``` ### 168.5. Композиция сведений дел (DECISION-0169) Дело вправе взять из ДРУГОГО дела выбранные утверждения и их опоры. Это третий механизм рядом с импортом норм §23 и документами §168.4, и он не смешивается с ними: программа потребителя не меняется, чужие выводы (`positions`, `proof`, статус `accepted`) не переносятся, миры не сливаются. **Экспорт.** Поставщик явно называет записи: артефакт `law.case-export/0.1` (`case-export.schema.json`) несёт источник (пакет, дело, `resolutionHash` лока), выбранные `assertion`-узлы с явными `id`, привязки констант (`bindings` — транзитивное замыкание `const_ref`, достижимых из записей, их `payload`, `issuer` и `judgment`), документы, опоры (`supportEdges`), проверки подлинности и перечень вложений с хэшами; `contentHash` — sha256 канонических байтов артефакта без этого поля. Опоры отбираются по ПРОПОЗИЦИИ без полярности и по `relation`: у записи `assert P` относящимися считаются `supports P` и `refutes P`, у записи `assert not P` — те же рёбра, потому что §78.2.2 называет штатной опорой отрицания `refutes` с ПОЛОЖИТЕЛЬНЫМ `to`. Перечень relation закрыт этой парой: `authenticates`, `measures`, `reports` и `establishes` §75 говорят о документе, а не о пропозиции записи, и в снимок не попадают. Ребро с ОТРИЦАТЕЛЬНЫМ `to` пара тоже втягивает; оно перевозится и отвергается приёмкой потребителя, а не отбором. Отбор по равенству литералов терял бы опору всякого отрицательного утверждения. Документ, названный `from` относящейся опоры, входит в замыкание, даже если ни одна запись не называет его в поле `evidence`. Анонимный `assert` не экспортируется (`LDC-E1364`): его ID зависит от provenance и при повторном понижении не сохраняется. Недостающая привязка константы — тот же `LDC-E1364`: молчаливая ссылка на константу потребителя изменила бы смысл записи. Замыкание, которое нельзя собрать из разрешённых к передаче записей, — отказ с перечнем; целое дело поставщика скрыто не расширяется. `records` артефакта идут в порядке дела поставщика независимо от порядка `--record`; экспортируется дело КАК ПОНИЖЕНО — собственные подключения поставщика в экспорт не входят (экспорт, собранный из другого снимка, своих `sources` не несёт). **Пин.** Потребитель закрепляет снимок ресурсом лока вида `case-snapshot` (capability `law.case-export/0.1`, `resources/snapshots/<имя>/export.json`) с `contentHash` артефакта; вложения снимка сверяются по его перечню; расхождение — `LDC-E8704`. Поле `documents[].path` артефакта — путь ВНУТРИ каталога снимка вместе с префиксом `documents/`, и файл читается как `<каталог снимка>/`: второй префикс реализация не дописывает. `documentHash` каждого экспортированного evidence сверяется с байтами вложения и при экспорте, и при композиции. Сводный commitment — `case.options.evidenceSnapshotHash` = `"sha256:" + sha256(canonical_bytes(H))`, где `H` — массив `contentHash` ИСПОЛЬЗОВАННЫХ снимков, отсортированный по возрастанию строки и без повторов. Без подключений поле не пишется, и `sha256([])` не вычисляется. **Поверхность.** В `.lawcase`: `snapshot "<путь>";` на верхнем уровне и элемент дела `use { record ""; … }`. Это отдельная продукция `case_item`; в `given` теста §267 она отказывает `LDC-E1363`. Неизвестный alias или запись вне экспорта — `LDC-E1362`; неиспользованная декларация — предупреждение той же серии, дело не меняется. **Композиция.** Обе реализации строят составное дело одинаково: записи копируются как экспортированы — `id`, `origin`, временные поля, `evidence`, `contentHash` и `provenance[]` записи не меняются (identity неизменна); маршруты предъявления — `case.sources[]` (`alias`, `snapshot`, пакет, дело, `records`) в порядке `use`; привязки сливаются в `case.constants`, документы, опоры и проверки — в свои массивы; порядок — записи дела, затем снимки в порядке `use`, внутри снимка — порядок экспорта; `records` внутри источника — порядок экспорта без повторов (порядок и повторы записей в `use` маршрут не задают). Один `id` с побайтово равным каноническим содержанием — ОДНА запись по любому пути: снимок ↔ снимок («ромб»), снимок ↔ дело, дело ↔ дело; иное содержимое — `LDC-E1360`. Два снимка одного дела (пара `package.name` + дело, независимо от версии) — `LDC-E1361`, и он проверяется раньше `LDC-E1360`; снимок САМОГО составного дела (та же пара у потребителя) — тот же `LDC-E1361`: дело не предъявляет себя себе. Столкновение привязки с константой дела или программы при разных значениях — `LDC-E1360`. Пустое поле остаётся отсутствующим: пустых массивов композиция не пишет. Типы сущностей транспортом не переносятся: общая сущность — один `entity_ref`, совпадение имён ничего не объединяет. `ask` пины не обновляет. Понижение дела с `use` внутри пакета-дела даёт СОСТАВНОЕ дело: `lawc lower-case` и `ask` — одни байты (инвариант двух путей §168.4); служебный `lower-ask` отдаёт дело как понижено вместе с директивами, и составное строит подготовка `ask` обеих реализаций одинаково. **Приёмка.** Origin записи сохраняется; `assumed_for_simulation` поставщика принимается только в режиме `simulation` потребителя (§73), «перекраска» в `external_snapshot` запрещена. Опоры заново проходят политику потребителя; источник документа виден профилю §78.2 версии 0.2 слотом `source`, и отсутствие источника не означает доверия. Документ относится к источнику, если назван в поле `evidence` его записи ЛИБО является `from` опоры, экспортированной вместе с такой записью: относящейся к ней по таблице отбора И принадлежащей пространству имён поставщика (поле `package` узла, при его отсутствии — префикс StableId до `#`). Собственная опора потребителя к той же пропозиции — не импорт: её документ факта `source` не получает и сверяется локом потребителя §168.4, а не перечнем снимка. Импортированный документ несёт `uri` поставщика и сверяется перечнем `documents` закреплённого снимка; иное — `LDC-E8704`. Без `use` понижение не добавляет ни `sources`, ни пустых массивов, ни `evidenceSnapshotHash` — байты прежних дел не меняются. ## 169. Case restrictions Production `.lawcase`: - может объявлять entities/values локально; - может добавлять assertions/evidence/context; - не может изменять law rules; - не может импортировать unpinned packages; - не может вызывать live external capabilities; - в составе пакета-дела §168.4 объявляется секцией `[[cases]]` и исполняется операцией `ask` над закреплённым замыканием зависимостей. ## 170. Evaluation Input Manifest и Execution Receipt ```text evaluation_input_manifest { semantics "law.core/0.1.0"; program_hash "sha256:..."; lockfile_hash "sha256:..."; case_hash "sha256:..."; evidence_snapshot_hash "sha256:..."; jurisdiction_profile "kz.sources/2026.2.0"; interpretation_selection "OfficialBvrReading"; calendar_snapshot "kz.calendar/2026#sha256:..."; timezone_db_snapshot "tzdb/2026a#sha256:..."; solver_profile "law.solver.linear-decimal/0.1#sha256:..."; resolved_editions { ... } external_snapshots { ... } legal_time @2026-08-25; temporal_resolution_policy KZ_CIVIL_DAY_RESOLUTION; decision_time @2026-08-25T14:30:00+05:00; knowledge_time @2026-08-25T14:00:00+05:00; semantic_hash "sha256:..."; } execution_receipt { implementation "lawc-reference/0.1.0"; implementation_conformance "core-production/0.1"; started_at @2026-08-25T14:30:01+05:00; finished_at @2026-08-25T14:30:02+05:00; resource_usage { ... } receipt_hash "sha256:..."; } ``` `semantic_hash` входит в runtime IDs, cache key, result/proof hash. Он исключает compiler identity, wall-clock timing, host, log paths и performance counters. `ExecutionReceipt` входит только в auditable envelope/receipt hash. `core-auditable` требует receipt; pure conformance vectors могут сравнивать semantic output без него. **`jurisdiction_profile` (errata E-0161, DECISION-0170).** Поле манифеста несёт профиль канона §170.1 единой грамматикой `"/#sha256:<64 hex>"` и ПРИСУТСТВУЕТ только у расчёта над пакетом с названным профилем: значение берётся из `case.options.jurisdictionProfile` (§168.3), а при его отсутствии поле в манифесте ОТСУТСТВУЕТ — умолчание `examples.profile/0.1.0` упразднено, `null` не пишется. Значение иного вида в запросе или документе — отказ схемы; документы линии 0.1 (`semantics` = `law.core/0.1.0`) сохраняют прежнюю свободную строку. Пример выше показывает форму строки, а не умолчание. **`editions_as_presented` (errata E-0167).** Поле манифеста несёт дату `LegalTime` §2.15, на которую вызывающий предъявил состав редакций §92, и ПРИСУТСТВУЕТ только у вычисления с этим transport-полем запроса §168.3; без него поле в манифесте отсутствует, и документ байтово прежний. Поле входит в `semantic_hash` по тому же доводу, что `solver_profile`: ответ по предъявленному составу и ответ по праву на дату дела — разные ответы на одном `caseHash`, и хэш воспроизводимости обязан их различать. ### 170.1. Профиль канона (DECISION-0170) **Артефакт.** `law.profile/0.1` (`schema/profile.schema.json`, закрыт): `{schemaVersion, id, version, kind, title, asOf, language, semanticsRevision, packages[], profiles[], calendars[], expansions[], contentHash}`. - `id` — по грамматике имени пакета §10; `version` — точная версия; пара `id/version` у издателя иммутабельна; - `kind` — `jurisdiction` | `discipline` | `tradition` | `custom`; `title`, `asOf` (Date §48) — описательны: в вычисление не входят, в `contentHash` входят; `asOf` не заменяет ни `legal_time`, ни редакции актов; - `language`, `semanticsRevision` — линия языка и точная ревизия семантики (DECISION-0166 §4.5); у корня иные — `LDC-E1367`; - `packages[]` — `{name, version, namespace, contentHash, registryId?, features?}`; идентичность элемента — четвёрка `{name, version, namespace, contentHash}`; одна версия на имя; `features` — набор, ПРЕДОСТАВЛЯЕМЫЙ пакетом; необязательности в профиле нет — состав закрепляется целиком; - `profiles[]` — `{id, version, contentHash, registryId?}`; включение транзитивно; - `calendars[]` — `{node, contentHash, package}`: закреплённые календарные наборы §85 в форме ресурса `calendar-dataset`; `package` — элемент B, владелец узла; узел обязан существовать в CLIR этого пакета с тем же `datasetHash`; выбор набора остаётся оси `calendar` дела §168.2; - `expansions[]` — пакеты определений развёрток §279.1.8: `{name, version, contentHash}` (хэш значимых файлов, как в локе); записи `consumer`/`alias` пишет лок дела; - все массивы — множества: сортировка по канонической идентичности §208 (`name`, `id`, `node`, `name`), повторы, пустые массивы, пустой состав (`packages[]` и `profiles[]` оба отсутствуют), неизвестное поле и неизвестный `schemaVersion` — отказ схемы; - `contentHash` — sha256 канонических байтов артефакта без этого поля (нерекурсивно; вложенные хэши остаются). Любое поле меняет хэш. **Развёртка B(P)** — объединение `packages[]` P и развёрток `profiles[]` P, транзитивно. `LDC-E1367`: цикл или самовключение; в любом множестве элемент с одинаковым ключом и разным содержимым по двум путям — конфликт, не слияние (одинаковая четвёрка с разными `registryId`/`features`, один `node` с разными `contentHash` или владельцами; отсутствующее `features` — пустое множество); полностью равные элементы по двум путям — одна запись. **Замкнутость:** транзитивное замыкание по `imports` CLIR каждого пакета B обязано лежать в B по всей четвёрке; пакет, достижимый и не названный или названный с иным пином, — отказ генератора при публикации и `LDC-E1367` у потребителя. Пин зависимости в дескрипторе пакета (DECISION-0168 §6) сверяется с элементом B и по `registryId` до дедупликации; замена издателя транзитивной зависимости — `LDC-E1367`; в авторском режиме (`corpus/clir`) ни `registryId`, ни дескрипторов нет, и сверять нечего. **Что профиль не делает.** Не даёт видимости имён (§23), не исполняет неимпортированное (§168.4), не переносит фактов (§168.5), не выбирает редакцию акта на дату, не задаёт прочтений §152, не заменяет `[[tests]]` и не является прелюдией. **Публикация.** Авторский источник — `corpus/profiles///profile.toml`; генератор строит `profile.json` каноническими байтами и ОТКАЗЫВАЕТ, если хоть один пакет B не понижается на текущем дереве, его свежее понижение побайтно не равно закреплённому CLIR или его `envelope.imports` расходятся с байтами зависимостей: профиль либо полный, либо не публикуется. Реестр (DECISION-0168): дескриптор `law.profile-descriptor/0.1` (`schema/profile-descriptor.schema.json`) повторяет массивы артефакта полными элементами; `resolverUri = registry:///profile//`, путь `profile///{descriptor.json, profile.json}`; при загрузке артефакт сверяется с дескриптором равенством полных элементов (`LDC-E1367`). Выпуск пакета-дела несёт профили (`profiles////profile.json`), дескрипторы всех элементов B (`descriptors////descriptor.json`) и использованные локом развёртки (`expansions///`), инвентари — `passport.json` → `dependencies.profiles[]`, `dependencies.descriptors[]` (`descriptorHash` — sha256 канонических байтов всего дескриптора), `dependencies.expansions[]`; в выпуске развёртка разрешается по `(name, version, contentHash)` через инвентарь, а не по авторскому пути. ## 171. Evaluation modes ```text advisory compliance regulatory simulation audit ``` Mode не меняет legal semantics. Он может менять: - допустимость assumptions; - обязательность signatures; - severity diagnostics; - output redaction; - policy применения external judgment. Любая semantic difference между modes должна быть явной policy и записываться в manifest. ---