lawref.impact
Impact-отчёт черновика — L8.0, работа О-1 плана LAYERS-NEXT («законопроект как PR»).
Оркестрация без семантики (инвариант CLAUDE.md №5): модуль только вызывает
существующие входы — evaluate §168–§178, semdiff.diff_documents §215 — и
сравнивает канонические байты §208. Ни одно правило права здесь не
интерпретируется.
Отчёт из трёх частей (LAYERS-NEXT §3, О-1):
- (а) семантический diff узлов §215 между «до» и «после»;
- (б) сценарии с изменившимся исходом: исход = канонические байты {results, positions, conflicts, issues} evaluation-документа; для изменившихся прикладываются оба полных документа, включая парные proof-графы §179–§187;
- (в) покрытие норм «после»: норма покрыта, только если ДОКАЗАННО применилась
в каком-нибудь сценарии — узел
rule_application§180 илиnorm_creation§135 в proof-графе (DECISION-0019, вариант C). Непокрытость — отчётная величина, не код выхода: решение 0019 ещё черновик.
Сценарий — словарь {“case”: {…}, “query”: {…}}, той же формы, что
артефакты evaluate-векторов (case.json + query.json; календарный ресурс в v1
не поддержан). Опции исполнения читаются из case[“options”] — ровно как в
run_vector.
Attributes
| Name | Description |
|---|---|
DATE_TYPE | No description. |
EDITIONS_SCHEMA_VERSION | No description. |
INPUT_REJECTED_CODES | No description. |
LEGAL_TIME_ARG | No description. |
RULE_KIND | No description. |
SCHEMA_VERSION | No description. |
TEMPLATE_KIND | No description. |
VERDICT_CHANGE | No description. |
VERDICT_EXIT | No description. |
VERDICT_NOT_DATED | No description. |
VERDICT_NO_CHANGE | No description. |
VERDICT_PARAM_AXIS | No description. |
Functions
| Name | Description |
|---|---|
build_edition_report | Отчёт О-2: тот же каркас, что у О-1, но «до»/«после» — проекции ОДНОГО |
build_report | Собрать отчёт. scenarios — пары (имя, сценарий); порядок в отчёте — |
coverage_targets | Нормы документа, требующие покрытия: (rules, norm_templates). |
covered_ids | Id правил и шаблонов, доказанно применившихся в evaluation-документе. |
dating | Датируемость О-2-отчёта; None, если отчёт не по оси редакций. |
exit_code | Код выхода CLI: 0 — изменений нет, 1 — изменения, 3 — датировать было |
parameter_cutovers | Даты, на которых переключаются ДАТИРОВАННЫЕ ПАРАМЕТРЫ акта (§87). |
rejected_inputs | Issues сценария класса «вход не вошёл в расчёт» (см. INPUT_REJECTED_CODES). |
render_editions_header | Строки оси редакций для текстового вида (пусто, если отчёт не О-2). |
render_text | Человекочитаемая сводка. Вербализованный вид diff-а — существующей |
report_bytes | Канонические байты отчёта (§208-эмиттер); контракт детерминизма гейта. |
verdict | Вердикт отчёта — одна политика на текстовый вид и на код выхода. |
DATE_TYPEattributemodule attribute#
DATE_TYPE = 'urn:law:std#Date'EDITIONS_SCHEMA_VERSIONattributemodule attribute#
EDITIONS_SCHEMA_VERSION = 'law.impact-editions/0.1'INPUT_REJECTED_CODESattributemodule attribute#
INPUT_REJECTED_CODES = ('ASSERTION_NOT_ACCEPTED', 'ASSERTION_OUTSIDE_VALID', 'TYPE_ERROR')LEGAL_TIME_ARGattributemodule attribute#
LEGAL_TIME_ARG = 'legal_time'RULE_KINDattributemodule attribute#
RULE_KIND = 'rule'SCHEMA_VERSIONattributemodule attribute#
SCHEMA_VERSION = 'law.impact/0.1'TEMPLATE_KINDattributemodule attribute#
TEMPLATE_KIND = 'norm_template'VERDICT_CHANGEattributemodule attribute#
VERDICT_CHANGE = 'SEMANTIC-CHANGE'VERDICT_EXITattributemodule attribute#
VERDICT_EXIT = {VERDICT_CHANGE: 1, VERDICT_NO_CHANGE: 0, VERDICT_NOT_DATED: 3, VERDICT_PARAM_AXIS: 4}VERDICT_NOT_DATEDattributemodule attribute#
VERDICT_NOT_DATED = 'NOT-DATED'VERDICT_NO_CHANGEattributemodule attribute#
VERDICT_NO_CHANGE = 'NO-CHANGE'VERDICT_PARAM_AXISattributemodule attribute#
VERDICT_PARAM_AXIS = 'PARAM-AXIS'build_edition_reportfunction#
def build_edition_report(document: dict, time_before: str, time_after: str, scenarios: list[tuple[str, dict]], world: list[dict] | None = None) -> dict[str, Any]Отчёт О-2: тот же каркас, что у О-1, но «до»/«после» — проекции ОДНОГО документа на две даты. Семантический diff §215 между проекциями и есть «семантический changelog редакции»: нормы, вошедшие в силу и вышедшие из неё; сценарии — контрфактические: те же факты, изменившееся право.
Контекст сценария по-прежнему НЕ трогается (сдвиг legalTime дела смешал бы
смену редакции с течением времени дела: окна effective §87, датированные
параметры §87, статус позиции §133). Взамен каждая сторона исполняется с
editionsAsPresented = дата ЭТОЙ стороны (§92, errata E-0167): проекция
§31 применяется ВМЕСТО условия 3 §92, а не поверх него. До 11.09.2026 поля
не было, и после E-0095 каждая сторона исполнялась по ПЕРЕСЕЧЕНИЮ двух
проекций — на дату отчёта и на дату дела: на us-liver-status терялась вся
поздняя редакция (девять расхождений), на паре 2026-06-30 → 2026-07-01
пакета КС врали восемь строк из одиннадцати.
world — CLIR-документы зависимостей (DECISION-0193): мир связывается и
проецируется ЦЕЛИКОМ, отчёт — о корне, изменения зависимостей — разделом
world (состав мира и мета их проекций). Без мира раздела нет.
build_reportfunction#
def build_report(before: dict, after: dict, scenarios: list[tuple[str, dict]], presented: tuple[str | None, str | None] = (None, None), scope: frozenset[str] | None = None) -> dict[str, Any]Собрать отчёт. scenarios — пары (имя, сценарий); порядок в отчёте —
по имени, чтобы байты не зависели от порядка аргументов CLI.
presented — даты предъявления состава редакций §92 (E-0167) по сторонам:
у О-1 обе стороны поданы документами и проекции нет, поэтому (None, None)
и байты отчёта прежние; у О-2 стороны суть проекции на две даты, и каждая
исполняется своей.
scope (DECISION-0193) — id узлов КОРНЯ, когда стороны суть связанный
мир: сценарии исполняются над всем миром, а семантический diff §215 и
цели покрытия DECISION-0019/C — по корню. Иначе правила зависимости-хаба
стали бы «непокрытыми» в отчёте каждого потребителя.
coverage_targetsfunction#
def coverage_targets(document: dict) -> tuple[list[str], list[str]]Нормы документа, требующие покрытия: (rules, norm_templates).
covered_idsfunction#
def covered_ids(kind: str, doc: dict) -> set[str]Id правил и шаблонов, доказанно применившихся в evaluation-документе.
datingfunction#
def dating(report: dict) -> dict | NoneДатируемость О-2-отчёта; None, если отчёт не по оси редакций.
Разрешение якоря от даты не зависит (_anchor_edition её не читает),
поэтому обе проекции дают один и тот же список; объединение — страховка
того же рода, что у unresolvedAnchors в шапке.
exit_codefunction#
def exit_code(report: dict) -> intКод выхода CLI: 0 — изменений нет, 1 — изменения, 3 — датировать было нечем. Отдельный код — чтобы вызывающий конвейер не читал «право не менялось» там, где проекция вовсе не работала.
Раздел целей (DECISION-0089 §4.1, --goals) старше: сломанная цель —
код 4 поверх любого вердикта diff-а, иначе «изменения есть» (1) читалось
бы конвейером как обычная поправка, а не как поправка, убившая цель.
parameter_cutoversfunction#
def parameter_cutovers(document: dict) -> list[str]Даты, на которых переключаются ДАТИРОВАННЫЕ ПАРАМЕТРЫ акта (§87).
Зачем это в отчёте оси редакций. Поправку можно закодировать двумя
способами, и оба законны: новой РЕДАКЦИЕЙ источника (её и меряет
проекция D1) либо датированным ЗНАЧЕНИЕМ ПАРАМЕТРА — Cap(legal_time)
с ветвями < 2026-01-01 и >= 2026-01-01. Второй способ проекция не
видит по построению и не должна видеть: build_edition_report намеренно
не трогает legalTime дела, чтобы не смешать две оси.
Отсюда отказ, ради которого функция и написана. На kz-osms — акте с
ОДНОЙ редакцией и параметрической поправкой 206-VIII — отчёт печатал
«изменений нет» на паре дат 2025-06-30 → 2026-06-30, хотя на этих самых
датах право отвечает 17 000 ₸ и 34 000 ₸. Отрицательное утверждение обо
всём корпусе делалось там, где мерилась не та ось (замер 01.09.2026).
Считаются литералы, а не вычисляются ответы: функция сообщает, что у акта ЕСТЬ рубеж в интервале, и не утверждает, что он что-то меняет, — это работа исполнения (О-1 с двумя legalTime).
rejected_inputsfunction#
def rejected_inputs(kind: str, doc: dict) -> list[dict]Issues сценария класса «вход не вошёл в расчёт» (см. INPUT_REJECTED_CODES).
Возвращается не счёт, а сами записи: аналитику нужно ИМЯ отвергнутого утверждения, иначе «дело не то» нечем чинить.
render_editions_headerfunction#
def render_editions_header(report: dict) -> list[str]Строки оси редакций для текстового вида (пусто, если отчёт не О-2).
render_textfunction#
def render_text(report: dict) -> strЧеловекочитаемая сводка. Вербализованный вид diff-а — существующей
командой python -m lawref diff (LS §3.6); здесь только итоги.
report_bytesfunction#
def report_bytes(report: dict) -> bytesКанонические байты отчёта (§208-эмиттер); контракт детерминизма гейта.
verdictfunction#
def verdict(report: dict) -> strВердикт отчёта — одна политика на текстовый вид и на код выхода.
Порядок разбора не симметричен, и это существо дела. «Изменение найдено» — утверждение ПОЛОЖИТЕЛЬНОЕ и об одной норме: найденное расхождение стоит и при неполной датировке. «Изменений нет» — утверждение ОТРИЦАТЕЛЬНОЕ и обо ВСЁМ корпусе, поэтому оно не печатается, пока хоть одна заякоренная норма осталась вне датировки: про такую норму проекция не ответила, а не ответила «нет» (§249 — не угадываем, а сообщаем).
Одного висячего якоря для NOT-DATED мало: узел датирует любой
разрешившийся якорь, и в undatedNodes попадает лишь узел, у которого не
разрешился НИ ОДИН.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.