Skip to content

lawref.loophole

Bounded-поиск лазеек — L8.2 плана LAYERS-NEXT (горизонт §5, заведён поручением владельца; см. spec/decisions/0035-loophole-and-amend.ru.md).

Лазейка — последовательность шагов (дата, утверждение), после которой цель достигнута, а НИ НА ОДНОМ шаге не возникло позиции VIOLATED (§136–§137) или CONFLICTED (§134 публикует и violated-сторону). Право на каждом шаге — своё: документ проецируется на дату шага машиной применимости D1 (impact.edition_projection, §31), rule-окна effective §87 движок читает сам. Факты аккумулируются: шаг добавляет одно положительное утверждение, и каждый следующий шаг переоценивает ВЕСЬ накопленный мир на своей дате.

Оркестрация без семантики (инвариант CLAUDE.md №5): модуль только строит входы (alphabet — по машинерии фаззера О-4), зовёт evaluate через impact.run_scenario и читает витрину — статусы позиций из ответа на positions-запрос и truth status цели. Ни одно правило права здесь не интерпретируется; сравниваются выходы движка.

Поиск детерминирован БЕЗ PRNG: bounded model checking — исчерпывающий обход в ширину (кратчайшие последовательности первыми) по отсортированным датам и атомам, с капами и бюджетом вызовов evaluate; каждое усечение названо в манифесте (правило «no silent caps»). Даты кандидатов добываются механически из самого документа (границы effective, lifecycle редакций §31, Date-термы) плюс день после каждой границы — ради «после окна».

Классификация находки — двумя контрольными прогонами, тоже через движок:

  • orderSensitive: те же утверждения одним пакетом на финальной дате НЕ проходят (значит существенна последовательность, не набор);
  • timingSensitive: тот же пакет на ПОЗДНЕЙШЕЙ дате кандидатов не проходит (значит существенно окно — классическая лазейка «успеть до/переждать»).

Обход по проекции даёт и свою слепую зону, поэтому отчёт называет её сам: если проекция сняла правила пакета, манифест несёт маркер NORMS_NOT_IN_PROJECTION (то же имя, что у process-run, DECISION-0052 §8), а снятые ВСЕ правила на всех датах поднимают projectionVoid — «ноль находок» там сказано о пустом праве, а не об отсутствии лазеек. См. projection_report.

Пространство поиска усекается ДО обхода двумя капами — атомов alphabet и дат-кандидатов, — и оба управляются вызывающим (alphabet_cap, dates_cap; флаги --alphabet-cap, --dates-cap). Усечение не молчит вдвойне: манифест называет предикаты, у которых в alphabet не осталось НИ ОДНОГО действия (alphabetOmittedPredicates — измерено 01.09.2026 на doctrine/aba/equivalence-instruction: все 24 атома ушли на groundings журнала, и целевое действие в алфавит не попало ни разу), а «не найдено» при усечённом пространстве получает СВОЙ вердикт SPACE-TRUNCATED и код выхода 4 — по тому же доводу, что PARAM-AXIS у impact-editions: конвейер не должен читать «лазеек нет» там, где искали не во всём пространстве. Тот же код 4 у BUDGET-EXHAUSTED — обход, оборванный бюджетом посреди заданной глубины. Положительная находка стоит и при усечении; см. verdict.

Не входит: генерация отрицательных утверждений и скалярных значений (alphabet — положительные атомы по пулам О-4); adjudicated-события §73; оценка «хорошо/плохо» — отчёт называет пути, судить о дыре — нормотворцу.

Attributes

NameDescription
ALPHABET_CAPNo description.
DATES_CAPNo description.
DEFAULT_BUDGETNo description.
DEFAULT_DEPTHNo description.
FINDINGS_CAPNo description.
POSITIONS_QUERYNo description.
PROJECTION_LOSS_KINDNo description.
SCHEMA_VERSIONNo description.
SHRINK_BUDGETNo description.
VERDICT_ALREADYNo description.
VERDICT_BUDGET_EXHAUSTEDNo description.
VERDICT_EXITNo description.
VERDICT_FOUNDNo description.
VERDICT_NOT_FOUNDNo description.
VERDICT_PROJECTION_VOIDNo description.
VERDICT_SPACE_TRUNCATEDNo description.
VIOLATING_STATUSESNo description.

Functions

NameDescription
emit_scenariosКаждая находка — цепочка воспроизводимых сценариев формата О-1:
exit_codeКод выхода CLI: 1 — найдено, 0 — не найдено во всём пространстве (или
mine_datesДаты-кандидаты из документа: (даты, было_ли_усечение).
projection_reportЧто проекция §31/D1 сняла с дат обхода: (маркеры, датируемого_не_осталось).
render_textNo description.
report_bytesNo description.
run_searchОбход; отчёт детерминирован кортежем (документ, цель, depth, budget,
truncation_linesСтроки об усечении пространства — одни на текстовый вид и на MCP.
verdictВердикт отчёта — одна политика на текст, MCP и код выхода.
verdict_hintПояснение к вердикту, общее для текстового вида и MCP.

ALPHABET_CAPattributemodule attribute#

ALPHABET_CAP = 24

DATES_CAPattributemodule attribute#

DATES_CAP = 6

DEFAULT_BUDGETattributemodule attribute#

DEFAULT_BUDGET = 400

DEFAULT_DEPTHattributemodule attribute#

DEFAULT_DEPTH = 3

FINDINGS_CAPattributemodule attribute#

FINDINGS_CAP = 5

POSITIONS_QUERYattributemodule attribute#

POSITIONS_QUERY = {'queryId': 'urn:query:loophole:positions', 'kind': 'positions'}

PROJECTION_LOSS_KINDattributemodule attribute#

PROJECTION_LOSS_KIND = 'NORMS_NOT_IN_PROJECTION'

SCHEMA_VERSIONattributemodule attribute#

SCHEMA_VERSION = 'law.loophole/0.1'

SHRINK_BUDGETattributemodule attribute#

SHRINK_BUDGET = 120

VERDICT_ALREADYattributemodule attribute#

VERDICT_ALREADY = 'ALREADY-REACHABLE'

VERDICT_BUDGET_EXHAUSTEDattributemodule attribute#

VERDICT_BUDGET_EXHAUSTED = 'BUDGET-EXHAUSTED'

VERDICT_EXITattributemodule attribute#

VERDICT_EXIT = {
  VERDICT_FOUND: 1,
  VERDICT_NOT_FOUND: 0,
  VERDICT_ALREADY: 0,
  VERDICT_PROJECTION_VOID: 3,
  VERDICT_SPACE_TRUNCATED: 4,
  VERDICT_BUDGET_EXHAUSTED: 4
}

VERDICT_FOUNDattributemodule attribute#

VERDICT_FOUND = 'FOUND'

VERDICT_NOT_FOUNDattributemodule attribute#

VERDICT_NOT_FOUND = 'NOT-FOUND'

VERDICT_PROJECTION_VOIDattributemodule attribute#

VERDICT_PROJECTION_VOID = 'PROJECTION-VOID'

VERDICT_SPACE_TRUNCATEDattributemodule attribute#

VERDICT_SPACE_TRUNCATED = 'SPACE-TRUNCATED'

VIOLATING_STATUSESattributemodule attribute#

VIOLATING_STATUSES = ('VIOLATED', 'CONFLICTED')

emit_scenariosfunction#

def emit_scenarios(report: dict, goal_scenario: dict, out_dir) -> int

Каждая находка — цепочка воспроизводимых сценариев формата О-1: step-NN.json (positions-запрос на дате шага, факты накоплены) и goal.json (запрос цели на финальной дате).

exit_codefunction#

def exit_code(report: dict) -> int

Код выхода CLI: 1 — найдено, 0 — не найдено во всём пространстве (или цель достижима фоном), 3 — обход по пустому праву, 4 — обошли не всё: пространство усечено капом либо бюджет кончился (см. summary.verdict).

mine_datesfunction#

def mine_dates(document: dict, extra: list[str], cap: int = DATES_CAP) -> tuple[list[str], bool]

Даты-кандидаты из документа: (даты, было_ли_усечение).

Каждая найденная граница даёт и день ПОСЛЕ себя: включительность краёв различна (§87), и «сразу после окна» — отдельная точка поведения.

projection_reportfunction#

def projection_report(search: _Search, dates: list[str]) -> tuple[list[dict], bool]

Что проекция §31/D1 сняла с дат обхода: (маркеры, датируемого_не_осталось).

ЗАЧЕМ ЭТО ЗДЕСЬ. Право каждого шага — проекция акта на дату шага, и это ровно то, чем ловятся лазейки «успеть до вступления» и «переждать». Но у пакета, чьи редакции не несут lifecycle-дат (обычай, доктрина, реставрация текста — их не «вводили в действие» датой, и это ВЕРНО про них), проекция снимает все заякоренные правила на ЛЮБУЮ дату: обход честно исполняет пустое право и честно не находит путей. «Findings: 0» при этом неотличимо от «лазеек нет» — тот же класс, что у process-run, закрытый находкой NORMS_NOT_IN_PROJECTION (DECISION-0052 §8).

Замерено 30.08.2026 на vory.corpus.ponyatiya: цель gnutyi достижима одним шагом при обычном evaluate (TRUE_ONLY), а поиск возвращал ноль находок и alreadyReachable: false — все 28 правил сняты на каждой из дат-кандидатов, потому что ни одна из семи редакций lifecycle не объявляет.

Оркестрация, не семантика (инвариант CLAUDE.md №5): сравнивается ЧИСЛО правил в проекции с числом правил документа, состояния редакций берутся из меты как есть. Ни одно правило права здесь не интерпретируется.

Даты с одинаковой подписью потери сливаются в один маркер: шесть одинаковых строк на шести датах — шум, а не диагноз.

render_textfunction#

def render_text(report: dict) -> str

report_bytesfunction#

def report_bytes(report: dict) -> bytes
def run_search(document: dict, goal_scenario: dict, depth: int = DEFAULT_DEPTH, budget: int = DEFAULT_BUDGET, extra_dates: list[str] | None = None, alphabet_cap: int = ALPHABET_CAP, dates_cap: int = DATES_CAP) -> dict[str, Any]

Обход; отчёт детерминирован кортежем (документ, цель, depth, budget, alphabet_cap, dates_cap).

goal_scenario — {“case”?: {…}, “query”: {…}, “expect”?: {…}}: query — ground truth-запрос §168; case.assertions, если даны, — неизменный фон каждого шага; expect.truthStatus — целевой статус (TRUE_ONLY).

truncation_linesfunction#

def truncation_lines(manifest: dict) -> list[str]

Строки об усечении пространства — одни на текстовый вид и на MCP.

Называется не факт усечения, а его ЦЕНА: сколько атомов отброшено и какие предикаты остались без единого действия — по ним видно, искали ли там, где лежит ответ.

verdictfunction#

def verdict(report: dict) -> str

Вердикт отчёта — одна политика на текст, MCP и код выхода.

Порядок разбора несимметричен, как у impact.verdict: находка — утверждение ПОЛОЖИТЕЛЬНОЕ об одном пути и стоит при любом усечении. «Не найдено» — утверждение ОТРИЦАТЕЛЬНОЕ обо всём пространстве, и оно печатается только когда пространство было обойдено целиком: не по пустому праву (проекция сняла правила) и не по усечённому капом алфавиту или списку дат. Иначе это SPACE-TRUNCATED — «в этих границах не найдено, границы выбраны не вами».

verdict_hintfunction#

def verdict_hint(kind: str) -> str

Пояснение к вердикту, общее для текстового вида и MCP.

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.