Skip to content

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

NameDescription
DATE_TYPENo description.
EDITIONS_SCHEMA_VERSIONNo description.
INPUT_REJECTED_CODESNo description.
LEGAL_TIME_ARGNo description.
RULE_KINDNo description.
SCHEMA_VERSIONNo description.
TEMPLATE_KINDNo description.
VERDICT_CHANGENo description.
VERDICT_EXITNo description.
VERDICT_NOT_DATEDNo description.
VERDICT_NO_CHANGENo description.
VERDICT_PARAM_AXISNo description.

Functions

NameDescription
build_edition_reportОтчёт О-2: тот же каркас, что у О-1, но «до»/«после» — проекции ОДНОГО
build_reportСобрать отчёт. scenarios — пары (имя, сценарий); порядок в отчёте —
coverage_targetsНормы документа, требующие покрытия: (rules, norm_templates).
covered_idsId правил и шаблонов, доказанно применившихся в evaluation-документе.
datingДатируемость О-2-отчёта; None, если отчёт не по оси редакций.
exit_codeКод выхода CLI: 0 — изменений нет, 1 — изменения, 3 — датировать было
parameter_cutoversДаты, на которых переключаются ДАТИРОВАННЫЕ ПАРАМЕТРЫ акта (§87).
rejected_inputsIssues сценария класса «вход не вошёл в расчёт» (см. 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.