Skip to content

lawref.evaluator.rules

Статический анализ правил, общий для strict и defeasible замыканий.

Барьер полноты §111/§190: агрегат читает предикат целиком, поэтому источник обязан быть завершён до чтения. Оба замыкания задают этот вопрос одинаково — и получают одинаковый ответ.

Functions

NameDescription
aggregate_barrier_problem§111/§190: агрегат (домен квантора) читает предикат ЦЕЛИКОМ, поэтому
all_generator_readsВСЕ generator-чтения правила, включая изъятые E-0116, — для барьера
body_condition_literalsЧтения условных термов тела и scope литералами — носитель
body_condition_readsЧтения опоры внутри условных термов §56 ТЕЛА и scope: [(вид статуса,
closure_levelsУровни замыканий §70 (errata E-0113): уровень замыкания на единицу выше
closure_waitsОжидание замыканий §70 строгим слоем (errata E-0174): id строгого
condition_leavesЛистья условия цели §124 (errata E-0218): связки and/or над
condition_literalpayload.goal.condition → ground-литерал (v1: атом или established-атом).
condition_readsЧтения условных термов §56 головы и тела вместе — для рангов и графа
defeasible_chain_predicatesErrata E-0172 (§110 п. 5/§111): предикаты, которые строгая цепочка
defeasible_head_literalsErrata E-0238: пары (предикат, полярность) голов обычных defeasible-
defeasible_predicatesПредикаты с ПОРАЖАЕМЫМ производителем (defeasible/defeater, §104) —
defeasible_rule_statusТа же классификация для §104 (defeasible/defeater) — порт тела
derived_predicatesПредикаты, которые программа выводит правилами (любой силы).
effect_reachable_predicatesПредикаты, достижимые от голов эффектов полномочий §127 строго-
generator_problemПричина, по которой generator comprehension правила вне исполнимого
generator_readsЧтения generator-ов агрегатов §59 и доменов кванторов §52 правила —
goal_condition_compoundСоставное условие цели §124 (E-0218), исполнимое по §64, — или None.
goal_condition_literal§124.3: forbearance reads the negative action atom (E-0179).
goal_condition_sides§64 над парами листьев условия цели (errata E-0218): стороны t/f
head_condition_literalsЧтения условного терма головы §56 литералами: (вид статуса, литерал) —
head_condition_readsЧтения опоры внутри условного терма ГОЛОВЫ §56: [(вид статуса, предикат)].
monotone_guard_aggregatesАгрегаты §59 МОНОТОННЫХ АГРЕГАТНЫХ ГАРДОВ §111
monotone_guard_growingРастёт ли коллекция монотонного агрегатного гарда §111 ВНУТРИ страты
monotone_guard_readsЧтения generator-ов МОНОТОННЫХ агрегатных гардов §111 (errata E-0116) —
monotone_guard_sum_aggregatesМонотонные гарды с агрегатом sum (§111, errata E-0116) — те, чьи
norm_goal_statusКлассификация цели §124: (исход, причина).
norm_rule_statusКлассификация правила с norm-головой §135 — порт цикла norms.py.
rule_execution_statusЕдиная точка для внешнего наблюдателя: пропустит ли исполнитель это
scope_conjunctsКонъюнкты scope правила — §90: «scope семантически объединяется с
stratification_problem§110 п.1–2: цикл предикатного графа с не-monotone ребром — issue, иначе None.
strict_positive_chainСтрого-позитивные рёбра программы: (голова строгого правила, предикаты
strict_positive_closureСемена плюс головы строгих правил, читающих достигнутый предикат, до
strict_rule_statusКлассификация строгого правила: (исход, причина, конъюнкты).

aggregate_barrier_problemfunction#

def aggregate_barrier_problem(node: dict, defeasible: set[str] | frozenset[str]) -> str | None

§111/§190: агрегат (домен квантора) читает предикат ЦЕЛИКОМ, поэтому его источник обязан быть завершён до чтения. До DECISION-0088 завершённым признавался только невыводимый предикат; теперь строгие производители завершаются стратами строгого слоя (strict.strict_ranks), и барьер держит лишь СТРОГОГО читателя над предикатом с ПОРАЖАЕМЫМИ производителями: страты поражаемого слоя есть только у поражаемых правил. Errata E-0112: обёртка monotone(P)/supported(P) барьер НЕ снимает — перечисление есть ребро completion §110 независимо от статуса. Errata E-0116 барьер тоже не трогает: изъятие снимает НЕМОНОТОННОСТЬ перечисления, но не поражаемость производителей — опора поражаемого правила может быть отнята дефитером, и тест monotone(P) над ней не монотонен. Поэтому здесь зовётся all_generator_reads, а не generator_reads.

all_generator_readsfunction#

def all_generator_reads(node: dict) -> list[tuple[str, str]]

ВСЕ generator-чтения правила, включая изъятые E-0116, — для барьера §111/§190: изъятие снимает немонотонность перечисления, но не поражаемость производителей.

body_condition_literalsfunction#

def body_condition_literals(node: dict) -> list[tuple[str, dict]]

Чтения условных термов тела и scope литералами — носитель body_condition_reads; полярность нужна ожиданию замыкания §70.

body_condition_readsfunction#

def body_condition_reads(node: dict) -> list[tuple[str, str]]

Чтения опоры внутри условных термов §56 ТЕЛА и scope: [(вид статуса, предикат)] — errata E-0177.

Позиция терма в теле не важна: гард-сравнение, формула §64.2, квантор §52, фильтр comprehension, аргумент литерала. Гард, истинный на ветви else, публикует голову, пока тест ложен, и вывод её не отзывает, — немонотонность та же, что у условной головы (head_condition_reads).

До errata flatten_body отдавал гард целиком (guard), и ранги, отказы и граф §110 его чтения пропускали: читатель вставал в страту производителя.

closure_levelsfunction#

def closure_levels(nodes: list[dict]) -> dict[str, int] | None

Уровни замыканий §70 (errata E-0113): уровень замыкания на единицу выше уровней всех замыканий, чьи негативы читают — транзитивно, через любую зависимость — производители его предиката или домена; без такой зависимости — уровень 1. Считается по ТОМУ ЖЕ графу, что и stratification_problem: вершина-замыкание достигает другую вершину- замыкание ровно тогда, когда её производители читают тот негатив. None — цикл между замыканиями (его называет stratification_problem раньше, чем сюда доходит вызов; здесь — страховка).

closure_waitsfunction#

def closure_waits(rules: list[tuple[dict, list[tuple[str, dict]]]], nodes: list[dict], derived: set[str] | frozenset[str]) -> dict[str, frozenset[str]]

Ожидание замыканий §70 строгим слоем (errata E-0174): id строгого правила → замыкания, до материализации которых оно не исполняется.

§70 ставит замыкание вершиной графа страт: producers(P ∪ domain) → closure(P) → readers(¬P). Сэндвич §231.1 повторяет строгий фикспойнт до замыкания и после него, а вывод append-only. Правило, чей тест опровергается негативом замыкания (unknown(P), not_known(¬P), перечисление ¬P), сработало бы в проходе ДО замыкания и не отозвалось бы. Такое правило ждёт замыкание — это подъём над вершиной, а не отказ. Ожидание транзитивно: правило ждёт и то, чего ждут строгие производители опор, опровергающих его тест, а производитель завершён, когда завершены все его чтения. Правило, чей тест замыкание делает только истинным (голый not P), не ждёт: второй проход сэндвича его и так исполняет.

Значения — только id замыканий, достижимых по графу §110, поэтому правило не ждёт замыкания, которое само питает: уровни E-0113 ставят такое замыкание выше. Пустой словарь — прежний сэндвич байт в байт.

condition_leavesfunction#

def condition_leaves(condition) -> list[dict] | None

Листья условия цели §124 (errata E-0218): связки and/or над литералами и established-литералами. None — форма вне подмножества.

Лист читается парой САМОГО литерала: established, поставленный понижением по умолчанию §66, Boolean-подъёмом §64.1 здесь не является — иначе condition not A при неизвестном A давал бы контрпример §137.

condition_literalfunction#

def condition_literal(condition) -> dict | None

payload.goal.condition → ground-литерал (v1: атом или established-атом).

Живёт здесь, а не в norms.py, по той же причине, что и классификации правил: тот же вопрос задают снаружи — norm_goal_status ниже и ворота verify/ci/gates/silence/check_dead_rules.py. Вторая копия списка допустимых форм разошлась бы с первой молча.

condition_readsfunction#

def condition_reads(node: dict) -> list[tuple[str, str]]

Чтения условных термов §56 головы и тела вместе — для рангов и графа §110, где позиция терма вид ребра не меняет (errata E-0176, E-0177).

defeasible_chain_predicatesfunction#

def defeasible_chain_predicates(nodes: list[dict]) -> set[str]

Errata E-0172 (§110 п. 5/§111): предикаты, которые строгая цепочка выводит из поражаемого вывода, — без самих голов поражаемых правил (у тех свой отказ DECISION-0088 и своё сообщение).

defeasible_head_literalsfunction#

def defeasible_head_literals(nodes: list[dict]) -> set[tuple[str, str]]

Errata E-0238: пары (предикат, полярность) голов обычных defeasible- кандидатов §104 — без дефитеров: дефитер вывода не утверждает (§107 п. 3), и строгая опора противоположного знака с ним комплемента не образует.

defeasible_predicatesfunction#

def defeasible_predicates(nodes: list[dict]) -> set[str]

Предикаты с ПОРАЖАЕМЫМ производителем (defeasible/defeater, §104) — DECISION-0088: строгий читатель not_known/агрегата над ними отказывается.

defeasible_rule_statusfunction#

def defeasible_rule_status(node: dict, derived: set[str]) -> tuple[str, str | None, list[tuple[str, dict]]]

Та же классификация для §104 (defeasible/defeater) — порт тела defeasible._rule_filter_l1. Полярность head здесь ЛЮБАЯ: барьеры §111 ограничивают строгое замыкание, а не поражаемое.

derived_predicatesfunction#

def derived_predicates(nodes: list[dict]) -> set[str]

Предикаты, которые программа выводит правилами (любой силы).

effect_reachable_predicatesfunction#

def effect_reachable_predicates(nodes: list[dict]) -> set[str]

Предикаты, достижимые от голов эффектов полномочий §127 строго- позитивными рёбрами (errata E-0134): after (у modify — и before) каждого norm_template модальности power, затем головы строгих правил, чьё тело читает такой предикат через established/supported/monotone, до фикспойнта. Поражаемые правила цепочку не продолжают: после материализации они не повторяются (DECISION-0021 §4.3) и опоры не дают.

generator_problemfunction#

def generator_problem(node: dict) -> str | None

Причина, по которой generator comprehension правила вне исполнимого подмножества, либо None (§52.1, errata E-0219).

Comprehension стоит в теле, голове или scope — под агрегатом §59 или доменом квантора §52, на любой глубине. До errata такой generator не проверялся при классификации вовсе: его отвергал перебор уже во время вычисления, и ValueError уносил evaluation-документ целиком — на ЛЮБОЙ вопрос к программе, а ворота молчания падали исключением вместо того, чтобы назвать правило.

generator_readsfunction#

def generator_reads(node: dict, derived: set[str] | frozenset[str] = frozenset()) -> list[tuple[str, str]]

Чтения generator-ов агрегатов §59 и доменов кванторов §52 правила — (статус, предикат) в порядке встречи, без повторов, тело И голова. DECISION-0088: это зависимости §110 для рангов обоих слоёв; errata E-0112: каждое — ребро completion, и статус обёртки (monotone, supported) вид ребра НЕ меняет: перечисление множества не монотонно.

Errata E-0116: изъяты чтения МОНОТОННОГО АГРЕГАТНОГО ГАРДА §111 — их отдаёт monotone_guard_reads, и это рёбра monotone, а не completion. derived — предикаты, выводимые правилами программы (derived_predicates): без них гард не распознать, поэтому пустое умолчание означает «выводимых нет» и изъятие шире не делает.

goal_condition_compoundfunction#

def goal_condition_compound(goal: dict) -> dict | None

Составное условие цели §124 (E-0218), исполнимое по §64, — или None. Атом сюда не входит: его разбирает goal_condition_literal прежним путём.

goal_condition_literalfunction#

def goal_condition_literal(goal: dict) -> dict | None

§124.3: forbearance reads the negative action atom (E-0179).

Keep the authored goal intact: conflicts and weak permission use its action. Only the lifecycle/knowledge projection is desugared.

goal_condition_sidesfunction#

def goal_condition_sides(condition: dict, store) -> tuple[list[str], list[str]]

§64 над парами листьев условия цели (errata E-0218): стороны t/f и их опоры. P and Q = (P.t and Q.t, P.f or Q.f), P or Q = (P.t or Q.t, P.f and Q.f); опоры стороны — объединение опор листьев, давших её. Лист — пара самого литерала (support_sides), без подъёма §64.1.

head_condition_literalsfunction#

def head_condition_literals(node: dict) -> list[tuple[str, dict]]

Чтения условного терма головы §56 литералами: (вид статуса, литерал) — носитель head_condition_reads; полярность нужна ожиданию замыкания §70 (errata E-0174).

head_condition_readsfunction#

def head_condition_reads(node: dict) -> list[tuple[str, str]]

Чтения опоры внутри условного терма ГОЛОВЫ §56: [(вид статуса, предикат)].

Такое чтение немонотонно ровно так же, как not_known в теле: ветвь else срабатывает, ПОКА тест ложен, и если предикат получит опору позже, правило сработает второй раз — а факт, выведенный ранним else, останется в store. Поэтому читатель обязан стоять ВЫШЕ страты производителей (§110/§113), и зависимость обязана быть видна ранжированию.

До errata: чтения жили только в теле, deps_of их и собирал; условие в голове не попадало ни в conjuncts, ни в generator_reads, и правило вставало в нулевую страту рядом с производителем.

monotone_guard_aggregatesfunction#

def monotone_guard_aggregates(node: dict, derived: set[str] | frozenset[str]) -> list[dict]

Агрегаты §59 МОНОТОННЫХ АГРЕГАТНЫХ ГАРДОВ §111 (errata E-0116).

Гард — ПОЗИТИВНЫЙ конъюнкт тела (голова и любая иная позиция не считаются) вида AGG(collect v … where G) OP c, где: пара AGG/OP — из _MONOTONE_GUARD_OPS; c не перечисляет ничего сам (в терме порога нет comprehension, значит нет и чтения выводимого предиката); G читает выводимые предикаты ТОЛЬКО через monotone/supported §65.

Знак слагаемых sum статика не видит, и требовать конъюнкт v >= 0 нельзя: он МЕНЯЕТ каноническое тело §206 и вместе с ним порядок конъюнктов — измерено на us.ofac_50, где добавленный конъюнкт передвинул гард перед monotone(blocked(lead)) и сумма считалась по пустой коллекции (EMPTY_AGGREGATE §59) в первом же раунде. Поэтому проверка отрицательного слагаемого — на ИСПОЛНЕНИИ гарда: MONOTONE_GUARD_NEGATIVE_ADDEND (§111, errata E-0116).

Такой тест не убывает вместе с множеством: least fixed point §103 по нему определён так же, как по точечному monotone(P), и generator-чтения — рёбра monotone, а не completion.

monotone_guard_growingfunction#

def monotone_guard_growing(node: dict, derived: set[str] | frozenset[str]) -> bool

Растёт ли коллекция монотонного агрегатного гарда §111 ВНУТРИ страты (errata E-0198).

Растёт ровно тогда, когда generator гарда читает ВЫВОДИМЫЙ предикат (по §111 — только через monotone(P)/supported(P) §65): правило стоит в страте своих производителей и повторяется, пока гард не выполнен, поэтому коллекция первого прохода — подмножество коллекции неподвижной точки, и ошибка вычисления над ней ещё не окончательна. У гарда, чей generator читает одну эмпирику, коллекция заморожена входом дела: первый проход равен неподвижной точке, удерживать нечего, и байты такого правила правка E-0198 не двигает по построению.

Замер 20.09.2026 по 1 281 снимку корпуса: монотонных агрегатных гардов 353, растущих — 32 в 27 правилах, и среди растущих не-count ровно один (us-ofac-50#BlockedEntityByAggregateOwnership2014).

monotone_guard_readsfunction#

def monotone_guard_reads(node: dict, derived: set[str] | frozenset[str]) -> list[tuple[str, str]]

Чтения generator-ов МОНОТОННЫХ агрегатных гардов §111 (errata E-0116) — (статус, предикат) в порядке встречи, без повторов. Дополнение к generator_reads: вместе они дают все generator-чтения правила.

monotone_guard_sum_aggregatesfunction#

def monotone_guard_sum_aggregates(node: dict, derived: set[str] | frozenset[str]) -> list[dict]

Монотонные гарды с агрегатом sum (§111, errata E-0116) — те, чьи слагаемые исполнитель обязан проверить на знак: монотонность суммы держится на неотрицательности, а статика её не видит.

norm_goal_statusfunction#

def norm_goal_status(template: dict) -> tuple[str, str | None]

Классификация цели §124: (исход, причина).

Дефект, ради которого заведена (измерен 30.08.2026 на ст. 910 п. 2 ГК РК, Особенная часть). Цель condition a(x) or b(x) проходит lawc check и лоуверинг молча — схема AchievementGoal объявляет condition как Formula, то есть §124 дизъюнкцию РАЗРЕШАЕТ, — а на исполнении обязанность не разряжается никогда. Улика на одном деле: соседняя обязанность с однолитеральной целью перешла в SATISFIED, а эта, содержащая тот же литерал внутри or, осталась ACTIVE, и ни одного issue выдано не было. Класс тот же, что у or в теле правила, но тише: там исполнитель хотя бы печатает NON_EXECUTABLE_RULE.

Отказ v1 честен (неверных ответов не даёт), но обязан быть НАЗВАН — отсюда причина, которую печатает norms.py и требуют ворота молчания.

norm_rule_statusfunction#

def norm_rule_status(node: dict, template_ids: set[str]) -> tuple[str, str | None, list[tuple[str, dict]]]

Классификация правила с norm-головой §135 — порт цикла norms.py. Два отказа: шаблон не разрешается и тело вне v1-подмножества. Именно здесь пропали KurultaiDissolutionBarrier и PresidentialOfficialImmunityRule Конституции — у них норм-голова, поэтому строгое замыкание их не видит вовсе, а тело с or не проходит flatten_body.

rule_execution_statusfunction#

def rule_execution_status(node: dict, derived: set[str], template_ids: set[str], defeasible: set[str] | frozenset[str] = frozenset(), effect_reachable: set[str] | frozenset[str] = frozenset(), defeasible_chain: set[str] | frozenset[str] = frozenset(), defeasible_heads: set[tuple[str, str]] | frozenset[tuple[str, str]] = frozenset()) -> tuple[str, str | None]

Единая точка для внешнего наблюдателя: пропустит ли исполнитель это правило и почему. Диспетчер по силе и виду головы — ровно тот, что разложен по трём модулям оракула (strict, defeasible, norms).

Оговорка: покрывает СТАТИЧЕСКИЕ отказы. Отказы, видимые только на деле (power без exercise-паттерна §127, priority с несвязанными переменными §118), рождаются в effects.py/defeasible.py во время вычисления и статикой не предсказуемы — ворота их не видят и не притворяются.

scope_conjunctsfunction#

def scope_conjuncts(node: dict) -> list[tuple[str, dict]]

Конъюнкты scope правила — §90: «scope семантически объединяется с when, но сохраняется отдельно в IR для indexing, analysis и объяснений».

Слово «объединяется» нормативно, и до 28.08.2026 обе реализации его не исполняли: нетривиальный scope давал skipped с причиной «за пределами v1». Отказ был ЧЕСТНЫМ (неверных ответов не давал), но цена его молчалива — норма, у которой условие применимости выражено по §91 отдельно от условия срабатывания §91.1, не исполнялась вовсе. В корпусе так молчали четырнадцать норм Закона «О правовых актах», включая пункт 1 статьи 5 («все иные акты не могут противоречить нормативным постановлениям Конституционного Суда»).

Разбор — тот же flatten_body, а не второй: §90 объединяет scope с when, значит и подмножество конструкций у них одно. Своя копия разошлась бы с телом ровно так же, как разошлись бы два списка исходов классификации. Тривиальный scope (None либо true) даёт пустой список — форма {"kind": "boolean", "value": true} уже возвращает [] из flatten_body.

stratification_problemfunction#

def stratification_problem(nodes: list[dict]) -> dict | None

§110 п.1–2: цикл предикатного графа с не-monotone ребром — issue, иначе None.

Детект как в статике lawc: для каждого НЕ-monotone ребра (потребитель → продюсер) ищется обратная достижимость по полному графу; найденный путь замыкает цикл, содержащий это ребро. Только-monotone циклы (transitive closure через supported §103) легальны и не репортятся. Ребро completion (E-0112) и рёбра вершин-замыканий (E-0113) — не monotone.

Объём — циклы, в которых участвует хотя бы одно strict-правило: именно их strict-LFP §103 иначе молча вычислил бы по немонотонному оператору (established гасится приходом негативной опоры: TRUE_ONLY → BOTH). Чисто defeasible-циклы детектируются расхождением рангов в defeasible_closure и репортятся своим сообщением.

strict_positive_chainfunction#

def strict_positive_chain(nodes: list[dict]) -> list[tuple[str, list[str]]]

Строго-позитивные рёбра программы: (голова строгого правила, предикаты его положительных конъюнктов established/голый атом, supported, monotone в scope и теле) — в порядке узлов. Общий носитель обходов E-0134 (эффект полномочия) и E-0172 (поражаемый вывод): оба спрашивают, куда поздний производитель доходит строгими правилами, и одна копия списка статусов не разойдётся со второй. Правило вне v1-разбора рёбер не даёт.

strict_positive_closurefunction#

def strict_positive_closure(seeds: set[str], chain: list[tuple[str, list[str]]]) -> set[str]

Семена плюс головы строгих правил, читающих достигнутый предикат, до фикспойнта (strict_positive_chain).

strict_rule_statusfunction#

def strict_rule_status(node: dict, derived: set[str], defeasible: set[str] | frozenset[str] = frozenset(), effect_reachable: set[str] | frozenset[str] = frozenset(), defeasible_chain: set[str] | frozenset[str] = frozenset(), defeasible_heads: set[tuple[str, str]] | frozenset[tuple[str, str]] = frozenset()) -> tuple[str, str | None, list[tuple[str, dict]]]

Классификация строгого правила: (исход, причина, конъюнкты).

Живёт здесь, а не в теле цикла strict_closure, потому что тот же вопрос задают снаружи: ворота verify/ci/gates/silence/check_dead_rules.py обязаны знать, какие правила корпуса исполнитель молча пропустит. Вторая копия этого списка разошлась бы с первой — и ворота докладывали бы о живых нормах, которых нет, либо молчали о мёртвых (тот же класс отказа, что у реестров в CLAUDE.md). Один список, два потребителя.

DECISION-0088 (WP-41): негативная голова §99, not_known §113 и агрегат по выводимому предикату §111 исполняются стратами строгого слоя (strict.strict_ranks). Отказ остаётся у строгого читателя not_known или агрегата над предикатом с ПОРАЖАЕМЫМИ производителями (defeasible): §113 ставит читателя выше страты производителей, а страты поражаемого слоя есть только у поражаемых правил — такое правило обязано быть defeasible.

Errata E-0134 (§111/§127): тот же отказ у строгого not_known/unknown/ refuted над предикатом из effect_reachable — достижимым от головы эффекта полномочия строго-позитивной цепочкой (effect_reachable_predicates): эффект материализуется после всех страт (§280.3), и умолчание считалось бы по снимку без него, не отзываясь потом.

Errata E-0172 (§110 п. 5/§111): тот же отказ у строгого not_known и перечисления над предикатом из defeasible_chain — выводимым строгой цепочкой из поражаемого вывода (defeasible_chain_predicates, без самих поражаемых голов). Strict closure страты исполняется до её кандидатов, поэтому такой предикат полон лишь стратой выше источника, а у строгого читателя страт поражаемого слоя нет. Сообщение своё: у предиката нет поражаемого производителя, есть цепочка.

Errata E-0238 (§107/§111/§127): отказ и у строгого правила, чья голова — КОМПЛЕМЕНТ головы обычного defeasible-кандидата (defeasible_heads: пары «предикат, полярность» правил силы defeasible), а тело или scope положительно читает предикат из effect_reachable: противник поражаемого вывода опоздал бы к его conflict group, и документ получил бы BOTH. Строгая опора той же полярности, что у кандидатов, комплемента не создаёт и не отклоняется.

Errata E-0176 (§56/§111): условный терм головы — status-sensitive читатель при любом статусе теста (ветвь else публикуется, пока тест ложен), и отказ звучит над всеми тремя поздними производителями: поражаемым, звеном цепочки и эффектом полномочия.

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

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