{
  "schema": 1,
  "product": "RAGRAF",
  "version": "0.4.0",
  "declared_at": "2026-10-27",
  "stage": "И32",
  "main": "README.md",
  "states": "docs/03_implementation/translations.json",
  "note": "Единственное место, где объявлено, ЧТО является пунктом списка, что внутри пункта защищено от перевода, каким видом объявлен каждый список и с какой строгостью защищённая часть требуется от перевода. До этапа И32 списки перевода проверялись только СЧЁТОМ: функция `section_profile` в `tools/check_translations.py` считает строки списков на каждый заголовок `##`, поэтому перевод, где пункт списка ПРОПАЛ, а соседний пункт склеен с ним, проходил зелёным — число пунктов верхнего уровня в разделе при этом может совпасть. Замер 27.10.2026 до правки (tools/check_list_items.py, первый прогон до правок текста): списков 4 в каждом из шести файлов, пунктов 22 (нумерованных 3, маркированных 19), всего по шести файлам 132 пункта; пунктов с обрамлённым кодом 8, с числом 3, со ссылкой 11 — и все 11 ссылок это якоря оглавления, различающиеся по языку законно. Расхождений защищённой части при этом НЕ нашлось ни одного: свойство сегодня выполняется во всех пяти переводах, но не проверялось ничем, и пропавший пункт при совпавшем числе увидел бы только глаз. Поэтому первый прогон проверки — не список порок для правки, а доказательство, что свойство держится, а сторож чувствителен (четыре порчи в песочнице: пропавший пункт, склейка двух пунктов, перестановка двух пунктов и подмена идентификатора внутри обрамлённого кода — каждая даёт ровно одну находку). Объявление вынесено в данные по той же причине, что состояния переводов (`translations.json`), терминология (`glossary.json`), допуски прозы (`prose.json`), адреса (`addresses.json`), правило команд (`commands.json`) и ячейки таблиц (`tables.json`): строгость, перечень языков и якоря оглавления меняются правкой этого файла, а не правкой проверки. Расширять допуск или вносить исключение можно только решением владельца, названным числом, а не для того, чтобы прогон позеленел.",
  "item_kinds": [
    {
      "name": "text",
      "about": "Переводимый пункт: пояснение, пункт перечня, строка требований. Свободно переводится; сверяются только защищённые части внутри — обрамлённый код (точно и по порядку), адрес ссылки (точно), числа (значением и набором с учётом кратности) и число разделителей `<br>`. Именно поэтому `2.5 GB` и `2,5 ГБ` — один и тот же пункт, а `74` вместо `77` — находка. Замер 27.10.2026: так объявлены три списка из четырёх (17 пунктов из 22)."
    },
    {
      "name": "anchor",
      "about": "Пункт оглавления: ровно одна ссылка, адрес которой — внутренний якорь `#…`, подпись переводится. Адрес якоря сверить с основным документом НЕЛЬЗЯ: заголовки переведены, и требовать равенства значило бы требовать непереведённого оглавления (замер 27.10.2026: во всех пяти переводах ни один из 11 якорей не совпадает с основным документом, и это правильно). Поэтому якоря объявлены по языку полем `anchors`, и проверка сверяет ПОЗИЦИЮ: объявленный якорь обязан стоять на своём месте. Куда якорь ведёт — предмет следующего слоя (внутренние ссылки на разделы), и эта проверка его не подменяет. Замер: так объявлен один список — оглавление, 11 пунктов из 22."
    }
  ],
  "parse_rule": {
    "about": "Правило разбора пункта объявлено здесь, а не выведено кодом, потому что от него зависит и находка, и её отсутствие. Главная опасность правила — ЛОЖНОЕ срабатывание: оно требует правки текста там, где перевод прав, поэтому правило названо в шапке объявления и проверено на всех 132 пунктах шести файлов до того, как стать сторожем.",
    "items": "Список — подряд идущие строки-пункты вне блоков ограждения. Пункт — строка, начинающаяся с маркера (`-`, `*`, `+` или число до 9 знаков с точкой либо скобкой) и хотя бы одного пробела после него, и непустого текста. Строка из одного маркера пунктом НЕ считается: у неё нет текста, и сверять в ней нечего. Список заканчивают: пустая строка, заголовок, строка обычного текста без отступа, начало или конец блока ограждения. Граница названа честно: «свободный» список (пункты через пустую строку) этим правилом делится на несколько списков — в README.md таких мест нет (замер 27.10.2026: списков 4, все плотные), и если появятся, объявление и baseline назовут это решением, а не пропуском.",
    "continuation": "ПЕРЕНОС: непустая строка с отступом сразу после пункта (или после его переноса) — продолжение этого пункта, а не новый пункт и не новый список. Текст пункта склеивается одним пробелом. Поэтому пункт, разбитый в переводе на три строки вместо двух, находкой не является: сверяется пункт, а не разбиение — замер 27.10.2026: у основного документа в четвёртом списке 8 строк переноса, у русского 7, у немецкого и испанского по 8, у хинди и китайского 0, и все пять переводов при этом верны. Обратная граница: строка БЕЗ отступа после пункта (например `CLI: …` на своём месте) пункт не продолжает и список заканчивает.",
    "nested": "ВЛОЖЕННОСТЬ по отступу: пункт с отступом — пункт того же списка, а не отдельный список; отступ сверяется по позиции (табуляция считается за четыре пробела). Замер 27.10.2026: пунктов с отступом ноль во всех шести файлах — вложенных списков в README.md нет, и правило объявлено под те вложенные списки, которые появятся. Отрисовка GitHub не воспроизводится: сравнивается ширина отступа, а не то, как браузер нарисует уровень вложенности.",
    "ordered": "НУМЕРОВАННЫЙ СПИСОК: сверяются и вид маркера (маркированный или нумерованный), и номер каждого пункта по позиции. `2.` вместо `1.` — находка: читатель ищет шаги по номерам, и сдвинутая нумерация ломает подписку на текст. Сам символ маркера (`-`, `*`, `+`) НЕ сверяется: на отрисовку он не влияет, и требовать его равенства значило бы требовать косметики. Замер 27.10.2026: нумерованных пунктов 3 в каждом файле, номера 1, 2, 3 во всех шести.",
    "protected": "Внутри пункта защищены: обрамлённый код (ТОЧНО и ПО ПОРЯДКУ — по нему читатель копирует имя файла или имя операции: `test_graph_algo.py`, `torch`, `secrets_*`), адрес ссылки (ТОЧНО; у пункта вида anchor — по объявленному по языку перечню якорей), числа (ЗНАЧЕНИЕМ и НАБОРОМ с учётом кратности) и число разделителей `<br>`. Переводимый текст не сравнивается вовсе. Признак «да/нет» в защищённые части НЕ входит и отдельным видом не объявлен: замер 27.10.2026 — пунктов с признаком в списках README.md ноль, и объявлять вид под случай, которого нет, значило бы описывать не тот документ. Если признак появится, он войдёт сюда решением, названным в объявлении.",
    "comparison": "Сверяются по порядку: вид и номер маркера, отступ, обрамлённый код, адреса ссылок, числа, число разделителей `<br>`. Числа сравниваются НАБОРОМ с учётом кратности, а не последовательностью: языки меняют порядок внутри пункта и пишут дробную часть запятой (`2,5 ГБ` против `2.5 GB`) — замер 27.10.2026: так в четырёх переводах из пяти, и это законная запись числа, а не находка. Числа, записанные словом, находкой не являются: в защищённые части входит цифровая запись, а слово переводится.",
    "boundary": "Правило повторено по виду документов, а не выведено из разметки Markdown: блок ограждения список ПРЕРЫВАЕТ (в README.md таких мест нет — замер), обратные кавычки считаются парными внутри пункта, перенос внутри обрамлённого кода не ожидается (замер: все 8 пунктов с кодом имеют чётное число кавычек в склеенном тексте), отрисовка списка GitHub не воспроизводится. Ошибка правила опасна в одну сторону: ложная находка требует правки текста перевода, пропуск оставляет расхождение незамеченным."
  },
  "anchor_rule": {
    "about": "ЯКОРЬ ОГЛАВЛЕНИЯ — единственная защищённая часть, которую нельзя сверить с основным документом, и поэтому она объявлена данными по языку. Причина измерена: оглавление ведёт в переведённые заголовки, и адрес пункта у каждого языка свой (`#what-it-is-and-why`, `#что-это-и-зачем`, `#was-es-ist-und-wofür`, `#qué-es-y-para-qué-sirve`, `#यह-क्या-है-और-क्यों`, `#这是什么以及为什么需要它`). Требовать равенства с README.md значило бы требовать непереведённого оглавления.",
    "comparison": "Сверяется ПОЗИЦИЯ: якорь пункта №i перевода обязан совпасть с объявленным якорем №i этого языка. Перестановка двух пунктов оглавления видна именно так (две позиции расходятся, находка одна — на список); переименование заголовка без правки объявления тоже видно, и это правильно: переименование — решение, которое записывается. Дополнительно проверяется вид пункта: ровно одна ссылка, адрес начинается с `#`, обрамлённого кода в пункте нет, якорь в объявлении не повторяется дважды (иначе два пункта вели бы в одно место).",
    "boundary": "Куда якорь ВЕДЁТ — не проверяется: существование заголовка с таким якорем, порядок заголовков в файле и правила преобразования заголовка в якорь (регистр, пробелы, знаки) — предмет следующего слоя, названного в отчёте этапа как «внутренние ссылки на разделы». Здесь сторожится только то, что пункты стоят на своих местах и остаются якорями."
  },
  "lists": [
    {
      "order": 1,
      "kind": "anchor",
      "items": 11,
      "ordered": false,
      "note": "Оглавление: 11 пунктов-якорей в основном документе и в каждом переводе. Подпись пункта переводится, адрес объявлен по языку (см. `anchor_rule`)."
    },
    {
      "order": 2,
      "kind": "text",
      "items": 3,
      "ordered": true,
      "note": "«Как это устроено»: три нумерованных пункта. Защищены код (`stale`, `path:line`, `provenance`, `stated`, `derived`, `index_rev`, `confidence`) и числа (`132/1278`, `19/1278`, `1278/1278`, `'25`). Замер 27.10.2026: числа совпадают во всех пяти переводах — набором, а не порядком."
    },
    {
      "order": 3,
      "kind": "text",
      "items": 3,
      "ordered": false,
      "note": "«Разработка»: три маркированных пункта про тесты, которым нужен внешний слой. Защищены имена файлов кодом (`test_joern_server.py`, `test_graph_algo.py`, `test_cpg_call_names.py`) и число `2.5` (в русском, немецком, испанском и хинди — `2,5`), которое сравнивается значением."
    },
    {
      "order": 4,
      "kind": "text",
      "items": 5,
      "ordered": false,
      "note": "«Хранилище секретов»: пять маркированных пунктов, каждый с переносом строки. Защищены код (`SecretBox`, `all`, `listed`, `owner_only`, `secrets_*`) и числа шифра (`XSalsa20-Poly1305` → 20 и 1305). Число переносов строк не сравнивается: у хинди и китайского пункты записаны одной строкой каждый, и это законно."
    }
  ],
  "baseline": {
    "date": "2026-10-27",
    "stage": "И32",
    "tool": "tools/check_list_items.py",
    "main_file": "README.md",
    "lists": 4,
    "items": 22,
    "ordered": 3,
    "items_per_list": [11, 3, 3, 5],
    "note": "Объявленный перечень основного документа: списки, их вид, их пункты. Проверка сверяет с ним ИЗМЕРЕННОЕ: список или пункт, добавленный либо пропавший в README.md, — это решение, которое записывается здесь, а не молчаливое изменение замера. Числа сняты 27.10.2026 вызовом инструмента: списков 4 (11, 3, 3, 5 пунктов), пунктов 22, из них нумерованных 3. Вид списка снят осмотром: оглавление — якоря, остальные три — переводимый текст с защищёнными частями."
  },
  "languages": {
    "ru": {
      "path": "community/README.ru.md",
      "item_tolerance": 0,
      "exceptions": [],
      "anchors": [
        "#что-это-и-зачем",
        "#возможности",
        "#как-это-устроено",
        "#установка",
        "#первые-шаги",
        "#требования-и-ограничения",
        "#документация",
        "#разработка",
        "#участие",
        "#проект-в-числах-и-измеренный-полигон",
        "#лицензия"
      ],
      "note": "Замер 27.10.2026: 22 пункта, расхождений 0. Оглавление — 11 своих якорей (заголовки переведены). Дробная часть числа записывается запятой (`2,5 ГБ`) — сравнивается значением, поэтому находкой не является. Число переносов строк в четвёртом списке не совпадает с основным документом (7 против 8) и не сравнивается: сверяется пункт, а не разбиение."
    },
    "de": {
      "path": "community/README.de.md",
      "item_tolerance": 0,
      "exceptions": [],
      "anchors": [
        "#was-es-ist-und-wofür",
        "#funktionen",
        "#wie-es-aufgebaut-ist",
        "#installation",
        "#erste-schritte",
        "#anforderungen-und-grenzen",
        "#dokumentation",
        "#entwicklung",
        "#mitwirkung",
        "#das-projekt-in-zahlen-und-der-gemessene-prüfstand",
        "#lizenz"
      ],
      "note": "Замер 27.10.2026: 22 пункта, расхождений 0. Якорь с умляутом (`#was-es-ist-und-wofür`) сохранён как есть: объявление повторяет адрес, а не нормализует его — нормализация якорей это правила GitHub, и они предметом этой проверки не являются."
    },
    "es": {
      "path": "community/README.es.md",
      "item_tolerance": 0,
      "exceptions": [],
      "anchors": [
        "#qué-es-y-para-qué-sirve",
        "#capacidades",
        "#cómo-funciona",
        "#instalación",
        "#primeros-pasos",
        "#requisitos-y-límites",
        "#documentación",
        "#desarrollo",
        "#contribuir",
        "#el-proyecto-en-cifras-y-el-banco-de-pruebas-medido",
        "#licencia"
      ],
      "note": "Замер 27.10.2026: 22 пункта, расхождений 0. Пункт оглавления «Contribuir» ведёт в `#contribuir`, а основной документ — в `#contributing`: это разные языки, и объявление фиксирует именно испанский адрес."
    },
    "hi": {
      "path": "community/README.hi.md",
      "item_tolerance": 0,
      "exceptions": [],
      "anchors": [
        "#यह-क्या-है-और-क्यों",
        "#क्षमताएँ",
        "#यह-कैसे-काम-करता-है",
        "#स्थापना",
        "#पहले-कदम",
        "#आवश्यकताएँ-और-सीमाएँ",
        "#दस्तावेज़",
        "#विकास",
        "#सहयोग",
        "#संख्याओं-में-परियोजना-और-मापा-गया-परीक्षण-क्षेत्र",
        "#लाइसेंस"
      ],
      "note": "Замер 27.10.2026: 22 пункта, расхождений 0. Пункты четвёртого списка записаны одной строкой каждый (переносов 0 против 8 в основном документе) — это законное разбиение текста, и находкой не является."
    },
    "zh": {
      "path": "community/README.zh.md",
      "item_tolerance": 0,
      "exceptions": [],
      "anchors": [
        "#这是什么以及为什么需要它",
        "#能力",
        "#实现原理",
        "#安装",
        "#第一步",
        "#环境要求与限制",
        "#文档",
        "#开发",
        "#参与",
        "#用数字看项目与实测基准",
        "#许可证"
      ],
      "note": "Замер 27.10.2026: 22 пункта, расхождений 0. Якоря без дефисов (`#能力`): в китайском заголовке нет пробелов, и адрес получается одним словом — это свойство языка, а не расхождение с объявлением."
    }
  }
}
