Skip to content

lawref.fuzz

Фаззер кейсов — L8.1, работа О-4 плана LAYERS-NEXT.

Сидированная генерация типизированных case-входов по объявлениям пакета и прогон существующего движка над случайными мирами. Оркестрация без семантики (инвариант №5): модуль строит входы хелперами authoring, зовёт evaluate через impact.run_scenario и читает витрину — proof-граф §180/§135 для покрытия (мера DECISION-0019, вариант C) и отчёты §115 для конфликтов.

Цели поиска v1:

  • покрытие: правило, доказанно применившееся хотя бы в одном мире, получает минимизированный сценарий-тест (формат О-1: {“case”, “query”}, query — ground-вывод самого применения); правило, не применившееся ни в одном из миров, называется непокрытым — динамическая недостижимость, которой статический norm-statics не видит;
  • неожиданный CONFLICTED: миры строятся консистентными по входу (не больше одной полярности на атом), поэтому непустой conflicts §115 — всегда конфликт ПРАВИЛ, не входов; находка минимизируется до сценария;
  • отказы: pre-evaluation исключение на сгенерированном входе — находка отдельного вида.

Скалярные значения (остаток v1, закрыт 27.08.2026): для типа параметра, под который в САМОМ документе встречаются value-термы (правые части comparison §65, окна, константы), пул строится из этих добытых значений — правила с гардами «== / >= порога» становятся достижимыми, потому что порог и есть значение из документа. Тип без единого value-терма получает entity_ref, как раньше (живые кейсы делают так же: accused(x: Text) в T033 несёт entity_ref). Строгие неравенства с непредставленными в документе значениями остаются недостижимыми честно — соседние значения не синтезируются (арифметика по типам была бы семантикой в инструменте).

Константы документа (остаток, закрытый 30.08.2026): добываются так же, но ТОЛЬКО в направленном режиме и только из обратного замыкания самой цели. Гард entered_state(v, AmTor) требует const_ref на объявленное состояние, и синтетическая сущность не совпадёт с ним никогда — из-за этого профиль процедуры §160 не покрывался ни у одного пакета корпуса. В слепом режиме пулы остались синтетическими НАМЕРЕННО: глобальная добыча выбирает константу произвольно и вытесняет капом MAX_GROUNDINGS уже работающие подстановки (замер: −2423 подстановки у 84 пакетов из 157).

Контрпримеры к декларируемым инвариантам (цель «в» эскиза, закрыта 27.08.2026): инвариант пакета — constraint §93.1 (necessary-направление определения: antecedent верен ТОЛЬКО ЕСЛИ requirement). Поиск — направленные миры над обратным замыканием предикатов констрейнта; контрпример = мир, где движок отвечает antecedent TRUE_ONLY, а какой-то конъюнкт requirement — НЕ TRUE_ONLY. Оба статуса читаются truth-запросами, сам констрейнт нигде не вычисляется (инвариант №5: сравниваются выходы движка). Requirement сложнее конъюнкции литералов/established — назван в manifest.skippedConstraints.

Не входит (горизонт плана): последовательности событий — реализованы отдельным инструментом L8.2 (lawref.loophole, DECISION-0035).

PRNG — hash-DRBG sha256(seed:counter): import random в lawref запрещён линтом детерминизма, и это правильно — сид входит в манифест отчёта, и прогон с тем же сидом обязан быть байтово воспроизводим.

Shrinking детерминирован и PRNG не трогает: (0) срез по зависимостям — одним прогоном выбрасываются утверждения предикатов, не достижимых назад от тела целевого правила через головы промежуточных, затем (1) ddmin (complement-вариант delta debugging, O(n log n) прогонов против O(n²) у жадного). При исчерпании гранулярности результат 1-минимален; бюджет SHRINK_BUDGET — общий на минимизацию.

Направленная генерация (targeted): для каждого непокрытого правила миры строятся только над его релевантными входами (обратное замыкание тела); попытка 0 — плотная, все ground-атомы положительно и без расхода PRNG (максимум шансов конъюнкции), дальнейшие — сидированные вариации с пропусками и отрицаниями (пути через not_known и defeater).

Attributes

NameDescription
CONSTRAINTS_CAPNo description.
FIXED_CONTEXTNo description.
MAX_GROUNDINGSNo description.
POOL_SIZENo description.
SCALAR_POOLNo description.
SCHEMA_VERSIONNo description.
SHRINK_BUDGETNo description.
TARGET_CONST_POOLNo description.
WORLD_CAPNo description.

Functions

NameDescription
cap_linesСтроки о капах — одни на текстовый вид и на потребителей.
render_textNo description.
report_bytesNo description.
run_fuzzПрогнать фаззер; отчёт детерминирован кортежем

CONSTRAINTS_CAPattributemodule attribute#

CONSTRAINTS_CAP = 8

FIXED_CONTEXTattributemodule attribute#

FIXED_CONTEXT = {
  'legalTime': '2026-01-01',
  'timezone': 'UTC',
  'decisionTime': '2026-01-01T00:00:00+00:00',
  'knowledgeTime': '2026-01-01T00:00:00+00:00'
}

MAX_GROUNDINGSattributemodule attribute#

MAX_GROUNDINGS = 8

POOL_SIZEattributemodule attribute#

POOL_SIZE = 2

SCALAR_POOLattributemodule attribute#

SCALAR_POOL = 3

SCHEMA_VERSIONattributemodule attribute#

SCHEMA_VERSION = 'law.fuzz/0.1'

SHRINK_BUDGETattributemodule attribute#

SHRINK_BUDGET = 200

TARGET_CONST_POOLattributemodule attribute#

TARGET_CONST_POOL = 24

WORLD_CAPattributemodule attribute#

WORLD_CAP = 40

cap_linesfunction#

def cap_lines(report: dict) -> list[str]

Строки о капах — одни на текстовый вид и на потребителей.

Называется цена капа: сколько подстановок срезано и у каких непокрытых правил цель могла не поместиться в мир. По ним «без применения» читается как «не искали», а не как «мёртвая норма».

render_textfunction#

def render_text(report: dict) -> str

report_bytesfunction#

def report_bytes(report: dict) -> bytes

run_fuzzfunction#

def run_fuzz(document: dict, seed: int, worlds: int, world_cap: int = WORLD_CAP, targeted: int = 0, max_groundings: int = MAX_GROUNDINGS) -> dict[str, Any]

Прогнать фаззер; отчёт детерминирован кортежем (документ, сид, миры, кап мира, targeted, кап подстановок).

Оба капа названы в манифесте и, когда режут, — поимённо: предикаты с усечённым произведением (groundingsTruncated) и непокрытые правила, у которых хоть один релевантный предикат усечён или плотный мир цели не поместился в кап (coverage.capBound). «Без применения» под капом и «без применения» при полном пространстве — разные ответы, и до 01.09.2026 отчёт их не различал: непокрытое читалось как мёртвое право.

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

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