From 3575a9c14ed17c1f067fa4d8dbf661e8b5868122 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Thu, 12 Nov 2026 23:16:19 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B5=D0=BA=D1=82=20=D0=BD?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D1=80=D0=B0=D0=B8=D0=B2=D0=B0=D0=B5=D0=BC?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B0=20=D1=81=D0=B8=D0=BD=D1=82=D0=B5=D1=82=D0=B8?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=93=D0=A1=D0=9A=20(#38)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- .../specs/2026-11-12-synthgen-design.md | 276 ++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 docs/superpowers/specs/2026-11-12-synthgen-design.md diff --git a/docs/superpowers/specs/2026-11-12-synthgen-design.md b/docs/superpowers/specs/2026-11-12-synthgen-design.md new file mode 100644 index 0000000..e4c479e --- /dev/null +++ b/docs/superpowers/specs/2026-11-12-synthgen-design.md @@ -0,0 +1,276 @@ +# Настраиваемый генератор синтетики ГСК — проект + +Issue: RSHB/arm-ka-fixtures#38. Ветка `feat/38-synthgen`. Дата: 12.11.2026. + +## 1. Зачем + +Для ручного тестирования, демонстрации и проверки на объёме нужен набор первички группы компаний, который +**выглядит как выгрузки из 1С** и **внутренне согласован**: ОСВ по счетам, ББ и ОФР каждой компании построены из одних и +тех же проводок, поэтому сходятся между собой, а операции между компаниями группы дают пары ВГО и шахматку, на которые +есть что посмотреть. Набор должен генерироваться скриптом под нужный размер, а не собираться руками. + +Реальные фикстуры (`osv/rb`, `osv/schastl`, `osv-dkb/`) — две-три компании, неполные периоды, реальные ИНН. Контрольный +набор #35 (`synthetic-group/`, 7 компаний, ручные сценарии, оракул) решает другую задачу — проверку алгоритмов на +известных случаях — и для объёма не годится: состав фиксирован, контрагентов единицы, оформление не похоже на 1С. + +## 2. Цели, не-цели, анти-цели + +**Цели** +- Один скрипт генерирует ОСВ, ББ, ОФР по всем компаниям и периодам и файл состава ГК для импорта ЕЦП. +- Семь настроек (§3) из конфигурационного файла с переопределением из командной строки. +- Файлы по виду — выгрузки 1С (§6). +- Данные согласованы (§5.6) и детерминированы: одинаковые настройки и `seed` → побайтно одинаковый набор. + +**Не-цели (в этой задаче)** +- Оракул, ожидаемые результаты (`expected/`), ручные сценарии вида R-/P-/V-/G-/S- из #35. +- Сканы PDF и ответы ИС Сканирование. +- ББ/ОФР по ФСБУ 4/2023 и упрощённые формы — только 66н. +- Компании ГК вне ГСК, несколько ГК в одном прогоне, расшифровки, КФО клиента. +- Загрузка на стенд (для этого есть `load.py` в #35; приспособить его — отдельная задача). + +**Анти-цели (провал, даже если «работает»)** +- Реальные ИНН или имена реальных организаций в наборе (в том числе остатки реквизитов из образцов 1С, §6.2). +- ОСВ, не сходящаяся с ББ/ОФР той же компании; ББ, где 1600 ≠ 1700. +- Набор, который парсер `tabular-parser` (ОСВ) или разбор ББ/ОФР в Excel не принимает из-за оформления генератора. +- Пересечение компаний двух прогонов с разными префиксами на одном стенде (имя или ИНН). + +## 3. Настройки + +Файл YAML (`--config`), любой ключ переопределяется `--set ключ=значение`. Неизвестный ключ или значение вне диапазона — +ошибка до начала генерации. + +| # | Ключ | Смысл | По умолчанию | Диапазон | +|---|---|---|---|---| +| 1 | `group_size` | число компаний в ГК (все входят в ГСК) | 5 | 2–40 | +| 2 | `prefix` | префикс ГК: добавляется к названию группы и её компаний (§4.2), задаёт диапазон ИНН компаний группы | `SYN` | 2–12 символов, буквы/цифры, без пробелов | +| 3 | `periods` | число отчётных периодов | 4 | 1–12 | +| 4 | `start` | первый период, `ГГГГ-Qn` | `2025-Q1` | 2020-Q1 … 2030-Q4 | +| 5 | `osv_counterparties_mean` | среднее число **внешних** контрагентов в одной ОСВ (матожидание, §5.3) | 60 | 0–150 (ограничено словарём, решение 9) | +| 6 | `no_inn_companies` | сколько компаний группы выгружают ОСВ без ИНН контрагентов | 1 | 0–`group_size` | +| 7 | `vgo_mismatch_share` | доля пар ВГО с расхождением сторон | 0.1 | 0–1 | +| — | `seed` | зерно случайности | 1 | целое | +| — | `out` | каталог результата (или `--out`) | `./out/` | — | + +Пример: `uv run python -m synthgen --config synthgen/examples/default.yaml --set group_size=12 --set prefix=DEMO2 --out /tmp/demo2`. + +## 4. Словарь компаний и состав группы + +### 4.1 Словарь +Закоммиченный файл `synthgen/dictionary/companies.csv`: **400** вымышленных организаций — +`name;form;inn;kpp;kind` (`form` ∈ ООО/АО/ПАО/ИП; `kind` — отрасль для правдоподобия: агро, торговля, логистика, +производство, услуги, финансы, строительство). Около 10 % — ИП (ФИО + «ИП», ИНН 12 знаков, КПП пусто). Имена +собираются один раз детерминированным скриптом `synthgen/dictionary/build.py` из списков корней/отраслевых слов и +проверяются на совпадение с реальными: имена не должны совпадать с организациями из `fixtures/directories/` и фикстур ОСВ. +Из 400 записей **30 — банки** (`kind=банк`, АО/ПАО): они — кредиторы по 66/67 и только там. +ИНН — как в #35: регион `00` (не существует), верная контрольная сумма; номера словаря — диапазон `0100001–0109999` +(**не пересекается** с ИНН #35, где номера 1–99, решение 10). + +Внешние контрагенты всех ОСВ берутся из словаря. Компании группы — тоже из словаря (§4.2), и **такая запись в этом +прогоне внешним контрагентом не бывает**. + +### 4.2 Компании группы и префикс +- Из словаря выбираются `group_size` записей с `form` ∈ ООО/АО (не ИП); головная — АО. +- Имя компании группы: `<форма> " <имя из словаря>"`, например `АО "DEMO2 Северная Нива"`. Название ГК: `ГК `. +- ИНН компании группы — **не из словаря**, а из диапазона префикса: номер = `1000000 + 100 × h(prefix) + i`, где `h` — + детерминированный хеш префикса (SHA-256 → целое) в `0…89999`, `i` — порядковый номер компании (< 100). Так ИНН компаний + группы не совпадают с ИНН словаря, #35 и групп с другими префиксами (коллизия хеша ~1/90000; README её оговаривает). +- КПП — 9 цифр, как в #35: `00` + двузначный номер компании + `01001` (у ИП КПП нет). + +## 5. Модель данных + +### 5.1 Периоды +Периоды — `periods` кварталов подряд начиная с `start`. Каждый отчётный период — **нарастающим итогом с начала года**, +как выгружает 1С: Q1 → «1 квартал», Q2 → «1 полугодие», Q3 → «9 месяцев», Q4 → «год» (`ГГГГ-FY`). Пример: `start=2025-Q3`, +`periods=4` → `2025-Q3`, `2025-FY`, `2026-Q1`, `2026-Q2`. + +Книга проводок компании ведётся с 1 января года первого периода (входящие остатки датированы **31 декабря предыдущего +года** проводкой против вспомогательного счёта `000`, как в #35) до конца последнего периода. ОСВ показывают `000` только +как источник входящих остатков — в файлы ОСВ счёт `000` не выгружается. Переход года: сальдо на 31.12 становится входящим остатком следующего +года, ОФР обнуляется закрытием 90/91 на 99 и 99 на 84 (реформация) в последний день года. + +### 5.2 Экономика компании +Каждой компании назначается профиль из отрасли словаря и масштаб (выручка за год — логнормально, медиана ~1 млрд руб., +разброс ×10 в обе стороны; головная — холдинг с небольшой выручкой и крупными вложениями 58.01). По профилю генерируются +помесячные операции: +- продажи (62/90), закупки (60/10/41/20), себестоимость (90.02), коммерческие и управленческие расходы (44/26); +- ОС и амортизация (01/02/08), денежные средства (51), НДС (19/68), налог на прибыль (68.04/99), зарплата (70/69) — + минимально, чтобы ББ был правдоподобным; +- банковские кредиты (66/67 с внешним банком из словаря), прочие расчёты (76), прочие доходы/расходы (91). + +Деньги — `Decimal`, `ROUND_HALF_UP`, копейки в ОСВ; float только при записи в ячейку. + +### 5.3 Внешние контрагенты в ОСВ +ОСВ генерируются по счетам **01, 58, 60, 62, 66, 67, 76, 80, 90** с субсчетами (§6.1): чек-лист `BASIC` +(01, 58, 60, 62, 66, 67, 76, 90 — `docs/context/01-project-overview.md`) плюс 80 (уставный капитал — +нужен правилу гудвилла 58.01 ↔ 80, ДП §4) (решение 7). Счета 01 и 90 по контрагентам не разворачиваются (01 — по +субсчетам, 90 — по субсчетам 90.01/90.02/…/90.09; у компании группы выручка от других компаний группы видна в ОСВ 62 +продавца). 80 — по участникам (головная и миноритарий). Для каждой пары +(компания, счёт с контрагентами) генератор выбирает число внешних контрагентов `n` и набор `n` записей словаря; этот +набор постоянен по всем периодам компании (контрагент может иметь нулевое сальдо и обороты в отдельном периоде — тогда +строки нет, как в 1С). + +`n` — отрицательное биномиальное с матожиданием `mean × w(счёт)` (дисперсия ≈ 2 × матожидание), где веса +`w`: 60 — 1.6, 62 — 1.6, 76 — 1.0, 66 — 0.1, 67 — 0.05, 58 — 0.1, 80 — 0 (только участники). Веса нормируются так, +что **среднее `n` по всем файлам ОСВ счетов 58, 60, 62, 66, 67, 76 = `osv_counterparties_mean`**. Потолки: 60/62/76 — +словарь без банков и компаний группы (≈ 370 − `group_size`), 66/67 — 30 банков. Если потолок срезал выборку, недобор +перераспределяется на остальные файлы того же счёта; тест среднего (допуск ±15 % при числе файлов ≥ 20) применяется, +когда потолок не сработал ни разу, иначе README прогона пишет «среднее ограничено словарём» (решение 9). + +Обороты распределяются по контрагентам по Парето (несколько крупных, длинный хвост мелких), сумма = обороты счёта из +экономики §5.2. У части контрагентов (~20 %) только обороты без сальдо, у ~5 % — сальдо без оборотов (старая +задолженность). Знак сальдо по контрагенту — по смыслу счёта, у ~3 % в 60/62 — противоположный (аванс/переплата), +как в реальных ОСВ. + +### 5.4 Операции внутри группы +- Головная компания владеет долями всех остальных: 58.01 у головной по каждой дочерней ↔ 80 у дочерней по головной + (уставный капитал; доля головной = её часть в 80). Доли 51–100 %, у одной-двух дочерних — миноритарий из словаря + (внешний участник, только в 80). Вклады — входящие остатки, движения в периодах нет. +- Торговля: каждая компания с вероятностью 0.5 продаёт каждой другой (62 у продавца ↔ 60 у покупателя); объём — + 5–20 % выручки продавца; расчёты гасятся частично, на конец периода остаётся сальдо. +- Займы: головная выдаёт займы дочерним (58.03 ↔ 66.03/67.03), с процентами (76 ↔ 76, 91). +- Дивиденды: дочерние объявляют головной раз в год во 2 квартале (Дт 84 Кт 76.03 у плательщика ↔ Дт 76.03 Кт 91 у получателя — стороны правила ОФР 2310, ДП §4) + и **выплачивают в том же месяце** — на конец периода остатка нет, обороты видны в ОСВ 76 обеих сторон. Так дивиденды не + дают пар ВГО по сальдо и не создают ложных односторонних пар; дивиденды в расхождения §5.5 не попадают (решение 11). +- Каждая операция проводится **в двух книгах одновременно** симметрично (Дт у одной, Кт у другой — по смыслу счетов). + +### 5.5 Расхождения ВГО +Пара ВГО — (компания A, компания B, вид расчёта: торговля / заём). Доля `vgo_mismatch_share` пар (округление вниз, но +не меньше 1, если доля > 0 и пар ≥ 1) получает расхождение: в последнем месяце **первого** периода года, где у пары есть +сальдо, одна сторона проводит накладную (или начисление процентов), которой нет у другой («в пути»). Величина — доля от меньшей стороны сальдо пары на конец этого периода, **вперемешку** (решение владельца 12.11.2026): +половина пар с расхождением (чётные по порядку выбора) — 1–4 % (ниже порога 5 % ДП §4: ядро сводит по `min` +автоматически), другая половина — 8–25 % (выше порога: пара подсвечивается и ждёт корректировки аналитика). При +нечётном числе пар лишняя — крупная. README прогона пишет для каждой пары процент и сторону порога. Расхождение держится до конца +года и снимается в январе следующего года проводкой второй стороны (накладная дошла) — в следующем году пара снова +выбирается заново. Остальные пары сходятся точно. + +### 5.6 Согласованность (инварианты, проверяются тестами) +1. В каждой книге Σ Дт = Σ Кт по каждой проводке; сальдо `000` после входящих остатков — ноль. +2. ОСВ компании за период = свёртка её книги (сальдо на начало, обороты, сальдо на конец) по счёту/субсчёту/контрагенту; + строка родителя = сумма детей. +3. ББ = сальдо книги на конец периода по правилам свёртки счетов в строки 66н (из `forms.py` #35, §8); ОФР = обороты + 90/91/99 за период нарастающим итогом. В тыс. руб. с `ROUND_HALF_UP` построчно, итоги — суммы округлённых строк; + 1600 = 1700 обеспечивается подгонкой ±1 тыс. в одной строке (как `_plug` в #35). ОСВ — в рублях. +4. Пары ВГО без расхождения: сальдо у A по B = −(сальдо у B по A) по соответствующим счетам (62↔60, 58.03↔66.03/67.03, + 76↔76); с расхождением — разница ровно на сумму накладной «в пути» §5.5 во всех периодах от её проводки до конца + года и ноль после января. +6. Колонка ББ «На 31 декабря» года, предшествующего первому периоду, = входящие остатки книги (= «Сальдо на начало» + ОСВ первого года); колонки ранее этого (ББ «на 31 декабря» позапрошлого года, ОФР за прошлый год, если прошлого года + нет в книге) — масштабированные значения профиля без требования согласованности (решение 5). +5. Компания группы в ОСВ другой компании группы записана тем же именем, что в ЕЦП, и тем же ИНН, кроме §6.1 (без ИНН). + +## 6. Вид файлов + +### 6.1 ОСВ +Формат «ОСВ по счёту» 1С 8.3 (БП 3.0) по образцу `fixtures/osv/rb/2024-Q1/сч 60_ 1 кв 2024 г.xlsx`: лист `Лист_1`, +строки 1–10 — шапка (организация, «Оборотно-сальдовая ведомость по счету NN за <период>», «Выводимые данные…», +«Параметры: Валюта БУ, НУ: RUB», двухуровневый заголовок «Счет / Контрагенты», «Сальдо на начало периода / Обороты за +период / Сальдо на конец периода», «Дебет / Кредит»), строка 12 — счёт, далее субсчета (уровень группировки 1, отступ 1) +и контрагенты (уровень 2, отступ 2), внизу «Итого». Оформление — **как в образце**: Arial 8 (данные) / 9–10 (шапка) / +12 полужирный (заголовок), заливка шапки `F4ECC5`, строк счетов и субсчетов `F8F2D8`, тонкие рамки у всех ячеек +таблицы, фиксированные высоты строк, сетка узких колонок A…W с объединением ячеек (колонка «Счет» — A:D, суммы — +E:G, H:I, J:K, L:N, O:P, Q:… по образцу), формат `#,##0.00`, нулевые суммы — пустые ячейки, итог над детьми +(`summaryBelow=False`). Сетку колонок, ширины и объединения генератор берёт из образца программно (читает образец при +сборке шаблона), а не набирает вручную. + +ИНН контрагента у компаний **с ИНН** — отдельная колонка после наименования (решение 3), у компаний из +`no_inn_companies` — колонки нет. Парсер ищет колонку ИНН строго между колонкой текста и первой колонкой сумм +(`tabular-parser/api/src/parser/detect.py`, `_inn_col`), поэтому в ОСВ с ИНН сетка образца **сдвигается**: наименование +A:D, ИНН — новая колонка E (ширина ~11), суммы — со следующей колонки с той же внутренней сеткой объединений, что в +образце. Шаблон хранит сетку как «блок текста + опциональная колонка ИНН + блок сумм», а не как фиксированные буквы. В ОСВ без ИНН компании группы записаны: большинство — тем же именем, что в ЕЦП +(автоматическое сопоставление по имени), **одна** компания группы на каждую такую ОСВ-компанию — немного другим +написанием (без кавычек и формы в конце, «Северная Нива DEMO2 ООО», как в 1С у реальных контрагентов) — её аналитик +сопоставит вручную (решение 4). + +Имя файла: `сч NN_<период 1С>.xlsx`, например `сч 60_9 месяцев 2025 г.xlsx`, `сч 62_2025 г.xlsx`. + +### 6.2 ББ и ОФР +Шаблон — реальная выгрузка 1С на листе `TDSheet` (форма 66н): `fixtures/statements-xlsx/mezheninovskaya/2025-Q3/ +1_Форма1_бух_09.xlsx` (ББ) и `1_Форма2_бух_09.xlsx` (ОФР). Генератор **копирует книгу образца** (стили, объединения, +шрифты Times New Roman, высоты строк, рамки, формат нулей `[=0]"-";General`, блок «КОДЫ») и заменяет: +- реквизиты: наименование, ИНН, ОКПО, ОКВЭД, ОКОПФ/ОКФС, вид деятельности, адрес — вымышленные; **все** прочие ячейки + шапки с данными образца (аудитор, его ИНН/ОГРН, подписи, даты подписания) очищаются; тест проверяет, что ни одна строка + из образца, кроме неизменяемых текстов формы, не попала в файл; +- даты и заголовки колонок периодов («За 9 месяцев 2025 года», «На 31 декабря 2024 года», «На 31 декабря 2023 года» — + для ББ; текущий и прошлый год — для ОФР); +- значения — по кодам строк (колонка «Коды»), а не по номерам строк образца. + +Образец правили в Excel, поэтому при сборке шаблона (`synthgen/templates/build_templates.py`, один раз, результат +коммитится) генератор: заменяет **все** формулы значениями (итоги 1100/1200/1600/1300/1400/1500/1700, 2100/…/2500 и +заголовки второй страницы — генератор пишет числа сам); удаляет рабочие формулы и значения вне формы (ячейки правее +последней колонки формы); очищает ФИО в подписях и ставит вымышленные; оставляет в ОФР строки 2530, 2900, 2910 (2530 — +из книги, если есть, иначе «-»; 2900/2910 — «-»). Значения в файле — в тыс. руб. **целыми** (решение 12), расходы ОФР — +**отрицательными** числами, как в образце (в скобках их не пишет и 1С). Набор строк — 66н из `forms.py` #35 плюс +2530/2900/2910; `edition_of` из #35 не копируется (всегда 66н). + +Колонки сравнительных периодов (прошлый год / позапрошлый год), если книга их не покрывает (период до начала книги), +заполняются масштабированными значениями того же профиля (решение 5) — так у файла нет пустых колонок, но и +согласованность для них не требуется. + +Имена файлов: `ББ_<период 1С>.xlsx`, `ОФР_<период 1С>.xlsx`. + +### 6.3 Состав ГК (импорт ЕЦП) +`directories/ecp-.xlsx` в формате файла #35 `synthetic-group/directories/ecp-synthetic-group.xlsx` (он +прошёл импорт в ядро; реальная выгрузка `fixtures/directories/ecp-export-russkiy-biskvit.xlsx` отличается — лист +`Выписки_01.04.26`, без КПП, имена «ЭКО ВОЛОГДА, АО» — импорт ядра принимает оба вида): лист `Выписки`, колонки +`ИНН, КПП, iD ГК, Базовый РФ ГК в CRM, Группа компаний, Организация, ГСК, ГСЗ, Тип`; все компании — «Входит в ГСК»; +`iD ГК` = `-000001`; ИНН/КПП текстом. Перед реализацией исполнитель сверяет формат с эндпоинтом импорта +(`arm-core`, `POST /api/v1/directories/import`) и с `ecp.py` #35. + +## 7. Результат прогона + +``` +/ + README.md — настройки прогона, состав группы (имя, ИНН, доля головной), список пар ВГО с + расхождениями (стороны, вид, сумма), какие компании без ИНН и какой контрагент + записан «другим именем», число контрагентов по файлам — не оракул, а журнал генератора + config.yaml — фактические настройки (с seed) + directories/ecp-.xlsx + osv/<КОД>/<период>/сч NN_….xlsx + statements/<КОД>/<период>/ББ_….xlsx, ОФР_….xlsx +``` +`<КОД>` — короткий латинский код компании (`C01`…`Cnn`, головная — `C01`); полное имя — в README и ЕЦП. + +## 8. Код и переиспользование + +- Пакет `synthgen/` в корне fixtures (рядом с `synthetic-group/`), запуск `uv run --with openpyxl==3.1.5 --with pyyaml + python -m synthgen …`. Тесты — `synthgen/tests/`, pytest. +- Ветка #35 ещё не слита, поэтому нужные модули **копируются** в `synthgen/` (с пометкой источника в docstring), не + импортируются из `synthetic-group/`: `inn.py`, `ledger.py`, `xlsx.py` (детерминированное сохранение), `chart.py` + (субсчета из seed arm-core; добавить недостающие — 80.09, 84, 91.09, 99 — сверив с + `arm-core` seed `chart_of_accounts.csv`), правила свёртки счетов в строки ББ/ОФР из `forms.py`, запись ЕЦП из `ecp.py`. + Источник — worktree `/Users/andrey.epifancev/projects/awp-ca/.wt/synthetic-group/fixtures/synthetic-group/gen/`. + Дедупликация — после слияния обоих (follow-up). +- Сгенерированные наборы **в git не коммитятся** (`out/` в `.gitignore`); коммитятся код, словарь, пример конфигурации и + шаблоны, собранные из образцов (без реквизитов образца). + +## 9. Приёмка + +- `pytest` зелёный: инварианты §5.6, распределение §5.3 (среднее в допуске), доля расхождений §5.5, число ОСВ без ИНН, + ИНН из диапазона префикса и с верной контрольной суммой, отсутствие реквизитов образцов, детерминированность + (два прогона с одним `seed` → побайтно равны; разный `seed` → различаются), ошибки конфигурации. +- Прогон по умолчанию и прогон «крупный» (`group_size=15, periods=6, osv_counterparties_mean=150`) проходят парсер ОСВ + `tabular-parser` (зеркальный worktree, как в #35) без ошибок; разбор ББ/ОФР в Excel находит все коды и сходит + 1600 = 1700. +- Время крупного прогона — до 5 минут на ноутбуке разработчика. + +## 10. Что оставлено исполнителю + +Выбор распределений внутри указанных рамок, алгоритм генерации имён словаря, внутренняя структура пакета, формат +README прогона, точные субсчета внутри перечисленных счетов (из `chart.py`). + +## Decisions made without discussion + +| № | Дата | Решение | Обоснование | Цена ошибки | +|---|---|---|---|---| +| 1 | 12.11.2026 | Новый пакет `synthgen/` отдельно от `synthetic-group/` (#35), модули #35 копируются | #35 не слита; разные задачи (контрольный набор vs объём); импорт между каталогами связал бы их ветки | дублирование кода до follow-up | +| 2 | 12.11.2026 | Все компании ГК входят в ГСК; `group_size` — одно число | владелец назвал «размер ГСК/ГК» одной настройкой | нет сценария «член ГК вне ГСК» — добавить настройку позже | +| 3 | 12.11.2026 | ИНН — отдельная колонка после наименования | в образцах 1С ИНН нет; колонка уже принимается парсером (#35, приёмка tabular-parser); в имени ИНН сломал бы сопоставление по имени | если в реальных выгрузках ИНН иначе — поменять запись ОСВ | +| 4 | 12.11.2026 | В ОСВ без ИНН одна компания группы — с другим написанием имени | владелец: «аналитик сопоставит малую часть контрагентов» | если нужно больше ручных сопоставлений — сделать настройкой | +| 5 | 12.11.2026 | ББ «на 31.12» года перед первым периодом — из книги (входящие остатки); более ранние сравнительные колонки — масштабированные значения профиля | первая колонка должна совпадать с «Сальдо на начало» ОСВ того же набора; глубже книги нет, пустые колонки нетипичны для 1С | аналитик может заметить несоответствие позапрошлогодних цифр | +| 6 | 12.11.2026 | Только форма 66н | образец 1С с 66н есть (Межениновская, 9 мес. 2025); ФСБУ 4/2023 — не-цель | годовая отчётность 2025+ по новой форме не покрыта | +| 7 | 12.11.2026 | Счета ОСВ: 01, 58, 60, 62, 66, 67, 76, 80, 90 | чек-лист `BASIC` (01-project-overview) + 80 (правило гудвилла 58.01↔80); 02 не входит в `BASIC` | версия `EXTENDED` покажет пробелы чек-листа — добавить счета позже | +| 9 | 12.11.2026 | `osv_counterparties_mean` ≤ 150, потолки по словарю, перераспределение недобора | владелец задал словарь 200–400; при среднем 300 потолок 60/62 срезает выборку и среднее не выполняется | для большего объёма нужен словарь крупнее — расширить `build.py` | +| 10 | 12.11.2026 | ИНН словаря — номера 0100001–0109999, компании группы — 1000000+ по хешу префикса | не пересекаться с #35 (номера 1–99) и между префиксами на одном стенде | коллизия хеша префиксов ~1/90000 | +| 11 | 12.11.2026 | Дивиденды выплачиваются в месяце объявления, в пары ВГО по сальдо и расхождения не попадают | дивиденды проводятся через 76.03 у обеих сторон (стороны правила ОФР 2310) и гасятся в месяце объявления; остаток на дату ББ дал бы пару по 76.03 вне доли расхождений (ДП §4, правила 5–8) — остаток дал бы ложную одностороннюю пару | пары по дивидендам не видны в шахматке по сальдо (обороты видны в ОСВ 75/76) | +| 12 | 12.11.2026 | ББ/ОФР в тыс. руб. целыми, расходы ОФР отрицательными | так выглядит образец 1С; дробные тысячи в образце — следствие ручной правки | если ядро ждёт копейки в тысячах — поменять запись | +| 8 | 12.11.2026 | Значения по умолчанию §3 (5 компаний, `SYN`, 4 периода с 2025-Q1, 60 контрагентов, 1 без ИНН, доля 0.1) | разумный стартовый объём: «есть что смотреть», прогон быстрый | никакой — меняется настройкой |