tonify-sims

SIM 2 — распространение музыки по социальному графу Telegram · SPEC v1.3

Модельная спека: BA + плантированные клики с перекрытием, complex contagion, посев в хабы

Tonify Research · август 2026 · economist → engineer · реализация: sim2/tonify_graph_sim.py, seed=42

Задача: проверить GTM-гипотезу Tonify «посев трека в хабы (каналы) эффективнее случайного посева» на графе, воспроизводящем два свойства Telegram: степенной хвост контактов (хабы-каналы) и плотные пересекающиеся групповые чаты (широкие мосты Centola). Спека самодостаточна: engineer реализует её, не задавая вопросов. Правило матрицы {signed × independent} из HANDOFF к sim2 неприменимо: кассового слоя в модели нет, распространение от контракта не зависит — фиксируем явно, чтобы красная команда не искала пропажу.


CHANGELOG (жанр CRITIC.md: обвинение → вердикт → действие)

v1.0 → v1.1

Причина пересмотра: реализация v1.0 вернула штатный стоп §4.1 — p* не существует. Реализация инженера верифицирована и НЕ виновата: лемма 2.4 подтверждена наивной референс-реализацией гиперрёбер байт-в-байт на полном N=50k; T1/T2/T2b PASS (γ̂ = 2,913; медиана клик 12,0; покрытие 0,502); классика k=1 на месте (p_c = 0,10 при mean-field 0,025; охват до 100 % при p ≥ 0,95).

Обвинение. Равномерно независимая посадка клик v1.0 не создаёт широких мостов МЕЖДУ чатами: пересечение чата с каким-либо другим ≥ 2 общими узлами ≈ 1,2 % на чат. Complex contagion заперт в чате посева: медианный R_eff = 0,000 на ВСЕЙ сетке p, включая p = 1,0 (стохастики розжига нет — p_seed = 1); медианный охват 0,02–0,03 % N; у 54 % чатов-посевов G₁ = 0 — ни один внешний узел не имеет двух посеянных соседей (nucleation-барьер). Утверждение v1.0 §9.6 «независимая посадка консервативна» — неверно: это не консервативность, а полная блокада механики, которую sim2 обязан мерить.

Вердикт. Конструкция v1.0 фальсифицирована собственной валидацией — стоп сработал как задуман. Вторичный дефект: правило p* на медианном R_eff слепо при экстремальной бимодальности — при p = 1,0 макрокаскад зажигали 37,1 % чатов-посевов (255/688, верх IQR 87–100 % N при p ≥ 0,60), а медиана всё равно 0: медиана меряет вероятность розжига, не критичность распространения. Форс-тест инженера (p* := 0,7) дал медианный охват 0,03 % N — мишень T3(в) v1.0 провалилась бы и при формальном существовании p*.

Действие (v1.1).

  1. Посадка клик с перекрытием (§2.2): каждый чат наследует по o = 2 участника от n_par = 2 уже посаженных чатов. Широкие мосты и связность мостового слоя гарантированы по построению; обоснование реализмом, не подгонкой — §2.2 и честное ограничение §9.6.
  2. Правило p* переведено с медианного R_eff на средний охват (§4.1): mean = P(розжиг) × условный охват — монотонен по p и не слеп к бимодальности.
  3. Новая валидационная мишень T2c на мостовой слой (§5) — гарантия, что мосты появились.
  4. T3 переведена на средний охват, точка T3/C — p_C = max(p*, 0,7) (§4.3).
  5. Фазовая диаграмма дополнена кривыми P_macro и условным R_eff (§4.2, fig9); появилась аналитическая референс-оценка критики complex: p_c^chat ≈ 1/√(d̄_bridge−1) ≈ 0,52.

Механика заражения (§3.1–3.3), лемма о редукции (§2.4), протокол эксперимента A, фальсификатор GTM (§6), палитра и рантайм-бюджет — БЕЗ изменений: дифф реализации — функция посадки, C, правило p*, агрегаты и мишень T2c.

v1.1 → v1.2

Причина пересмотра: T3(б) FAIL при живой конструкции — всё остальное v1.1 сработало (T1/T2/T2b/T2c PASS: мосты у 100 % чатов, d̄(B_chat) = 4,62, слой связен — 1 компонента; complex ожил, p* = 0,15 существует; аналитика p_c^chat = 0,526 попала в измеренную).

Обвинение (самому economist’у). v1.1 перевела метрику T3 на mean (правильно), но порог (б) «G_BA complex < 5 % N» остался от медианной интуиции v1.0 — категориальная ошибка метрика/порог, зеркальная CRITIC §1 sim1. Факты инженера (p_C = 0,7, 40 прогонов): mean охват G_BA complex = 12,54 % (FAIL порога 5 %), медиана 0,024 % — старый порог прошла бы. Механизм: розжиг в 6/40 = 15 % прогонов через rich-club-ядро BA (степени центров розжига [11, 11, 17, 21, 32, 257] — не хабовый артефакт), зажёгшийся каскад доходит до 81,9–84,5 % N; mean = 0,15 × 83,6 % ≈ 12,5 %. Посылка §1.20 v1.1 «второй источник на G_BA почти не встречается при любом p» опиралась на МЕДИАНУ форс-теста v1.0 — в mean-выражении она неверна.

Вердикт. Контраст Centola жив и велик (G complex 93,7 % vs G_BA complex 12,54 % mean — 7,5×; P(розжиг) 1,00 vs 0,15; G_BA simple 98,6 % PASS), но T3(б) в mean-формулировке ловила не тот инвариант: тезис Centola — про НАДЁЖНОСТЬ распространения complex, а mean смешивает редкость розжига с величиной условного охвата (зажёгшийся каскад макроскопичен на обоих графах).

Действие (v1.2).

  1. T3 целиком переведена на P_macro (§5): единая метрика на все три условия, симметричная пара порогов ≥ 0,75 / ≤ 0,25. Обоснование порогов внешнее — семантика «достоверен/ненадёжен» (квартильная пара) плюс статразделимость при 40 прогонах — не подгонка под факты; фактические значения (1,00 / 0,15 / 1,00) известны из диагностики и проходят с запасами 0,25 / 0,10 / 0,25. Mean-матрица 2×2 печатается справочно (§4.3).
  2. §6: бюджет B = 1 при k = 2 вырожден структурно (двух РАЗНЫХ источников от одного сеяного узла не существует; все стратегии тождественно дают 0 органики) — исключён из критерия фальсификатора, точка остаётся на fig8.
  3. §1.17: число чатов-кандидатов исправлено «~760 (22 % C)» → факт 970 (28 % C). Систематика в аналитике: окно целочисленных размеров считалось без continuity-поправки округления; верно s ∈ {10..14} ⟺ x ∈ [9,5; 14,5) ⟹ 27,5 % C = 953, а не 22,1 % = 764. Правило зафиксировано в §1.17.
  4. Rich-club-розжиг на чистом BA вынесен в §9.12 как находка: «теория рукопожатий» ломается на complex вероятностно, не абсолютно; §1.20 и §4.3 согласованы с этим фактом.

Конструкция, правило p*, T2c, протоколы A/B, фальсификатор GTM — без изменений; дифф реализации — одно место в валидации (T3) и справочные числа.

v1.2 → v1.3

Причина пересмотра: внешний аудит красной команды по прогону v1.2. Вердикт аудита: «принять при выполнении требования 1»; отзываемых чисел НЕТ — вердикт фальсификатора («гипотеза хабов подтверждена на B ∈ [2; 500]») выдержал перепроверку на трёх осях (union-хабы, чистые BA-хабы, вариация p). v1.3 — не пересмотр конструкции, а достройка контроля интерпретации и требований к отчётности.

Обвинение. (1) Загрязнение union-хабов кликовыми рёбрами (§9.10 признавала качественно) количественно хуже признанного: у топ-500 по union-степени 81,6 % степени — кликовые рёбра; 384/500 узлов — не BA-хабы (deg_BA < 15); пересечение с топ-500 по deg_BA — 84/500; членства: медиана 8, max 42. «Хабы» v1.2 — в большинстве чат-хопперы, не «каналы». (2) На B ≤ 20 выигрыш хабов смешан с эффектом плотности посева вообще (cliques тоже бьют random: 712–1111); чистый хаб-эффект +14–19 % изолируется на B ≥ 50 (cliques сходятся к random: 222,8 vs 222,0). (3) p* = 0,15 на грани шага сетки: mean охват при p = 0,10 на независимых батчах сидов 3,86–4,40 % N против порога 5,00 (репо-факт 4,90) — граница батч-чувствительна. (4) Окно gif «25–40 кадров» §7 недостижимо при N_gif = 4 000 и p* = 0,15: max каскад 14 раундов на всех 40 сидах ⟹ max 20 кадров — дефект пережил две ревизии. (5) Прикидки §2.2 разошлись с фактом (max членств «~70» vs 42; «~565k рёбер, ⟨k⟩ ≈ 22,6» vs 586 182 / 23,45). (6) Процессное: пороги T3 v1.2 фиксировались ПОСЛЕ диагностических прогонов (пост-хок признан в CHANGELOG v1.2).

Вердикт. Вердикт фальсификатора устойчив и аудитом УСИЛЕН: контрольный прогон критика — посев топ-B по степени ЧИСТОГО G_BA (p = 0,15, 30 прогонов) — бьёт random на ВСЕХ B (B=5: reach-per-seed 4 213,6±206,9 vs 0,0; B=100: 254,8 vs 222,0; B=500: 59,2 vs 46,4), а на B ≥ 20 бьёт и top-union: union-определение хабов ЗАНИЖАЛО канальное преимущество, а не создавало его. От выбора p вердикт не зависит (проверено при p = 0,25/0,30). Подгонки порогов T3 не выявлено: PASS воспроизводится на независимых батчах сидов 43/44/45 — P_macro(G_BA complex) = 0,150/0,075/0,125, всюду под 0,25. Но контроль интерпретации и правило о порядке фиксации порогов обязаны жить в спеке.

Действие (v1.3). Трасса требование → правка:

  1. [блокер] Четвёртая КОНТРОЛЬНАЯ стратегия посева top-BA — топ-B по степени чистого G_BA (§4.1, strategy_id = 3; §7 fig8 — четвёртая кривая #00E08F). Критерий фальсификатора §6 НЕ меняется (top-hubs union vs random — менять критерий после трёх ревизий нельзя); top-BA — контроль интерпретации «каналы vs чат-хопперы», печатается рядом.
  2. [блокер] Блок «декомпозиция хабов» в stdout и README (§4.1 — точные определения; §8 — требование к артефактам): доля кликовой степени у топ-500 union, пересечение топ-500 union ∩ топ-500 BA, членства хопперов; контрольная строка top-BA в таблице эксперимента A.
  3. README обязан печатать строку механики малых B и оговорку батч-чувствительности p* (§8).
  4. §7: окно кадров gif «25–40» → «фактическая длина каскада + 5 финальных, ориентир 15–40» (старое окно несовместимо с N_gif = 4 000 при p* = 0,15 — см. Обвинение (4)).
  5. §2.2: прикидки заменены фактами прогона (42; 586 182; 23,45).
  6. Процессное правило (на все будущие ревизии): валидационные пороги фиксируются ДО диагностических прогонов; пост-хок изменение порога допустимо только с явным признанием в CHANGELOG и воспроизведением PASS на независимых батчах сидов (урок T3 v1.2).

Конструкция §2, правило p*, T2c, критерий §6, пороги T3 — без изменений; дифф реализации — одна стратегия посева, печать декомпозиции и метаданные фигур.


1. Параметры → источники

Каждый параметр — либо источник, либо флаг допущение с одной строкой обоснования. Немотивированных чисел нет.

# Параметр Значение Источник / флаг
1 N узлов 50 000 ТЗ (HANDOFF)
2 BA: параметр присоединения m 3 ТЗ; механизм — Barabási & Albert 1999
3 Глобальный seed 42 ТЗ, конвенция sim1
4 Размер клики: лог-нормаль μ = ln 12 ≈ 2,4849; σ = 0,6; округление до целого; клиппинг [5, 40] Границы [5, 40] и лог-нормальность — ТЗ. μ, σ — допущение: медиана 12 = типичный малый групповой чат; публичной статистики размеров приватных Telegram-групп нет; σ = 0,6 держит массу на границах клипа малой (~9,7 % в 5 и ~2,4 % в 40)
5 Число клик C 3 460 Калибровка на покрытие q = 0,50 (строка 6): наивная формула C = ln(1/(1−q))·N/(E[s]−n_par·o) = 3 398 занижает ~2 % (поправки наследования); C = 3 460 — эмпирическая интерполяция посадки seed=42 (покрытие 0,493 при C = 3 400; 0,506 при C = 3 500)
6 Доля узлов в ≥1 чате (покрытие) q 0,50 Допущение: групповые чаты — ядро Telegram-UX, но доля пользователей в ≥1 приватной группе не публикуется; 0,50 — консервативная середина. Проверка — T2b
7 Перекрытие чатов: n_par родителей, o общих узлов с каждым n_par = 2; o = 2 Допущение (обоснование реализмом и минимальностью): o = 2 — минимальная ширина широкого моста (Centola 2010: complex проводят перекрывающиеся кластеры); n_par = 2 — минимум, дающий мостовому слою среднюю степень ~4,7 > 2, т.е. ветвление > 1 достижимо при p < 1 и существование сверхкритики не висит на хвостах BA. Эмпирика перекрывающихся сообществ в реальных соцсетях — Palla, Derényi, Farkas & Vicsek, Nature 2005. Признание: посадка выбрана ТАК, ЧТОБЫ мосты существовали, — §9.6
8 Порог принятия complex k 2 разных соседа-источника ТЗ; Centola & Macy 2007, Centola 2010
9 Порог simple k 1 ТЗ (режим сравнения); контраст со слабыми связями — Granovetter 1973
10 Share rate p ось эксперимента; сетка {0,05; 0,10; …; 1,00}, шаг 0,05 (20 точек) ТЗ («p — ось фазовой диаграммы»); границы — полный носитель вероятности
11 Рабочая точка p* (для A, gif) min{p из сетки: mean охват(k=2, посев-чат §4.2) ≥ 5 % N} Правило-конструкция: привязка к измеренной фазовой (эксперимент B). Mean = P(розжиг) × условный охват — единственный из агрегатов монотонен по p при бимодальности (урок v1.0, CHANGELOG). Порог 5 % N = 2 500 узлов — допущение: макрокаскад, на порядок больше любого посева (≤500) и первого кольца (~55)
12 Вероятность трансляции посева p_seed 1 Допущение (GTM-реализм): посев = оплаченное/гарантированное размещение; органика транслирует с p
13 Память касаний бессрочная в рамках каскада, без затухания Centola & Macy 2007: exposures перманентны внутри каскада; отсутствие забывания — ограничение §9.1
14 Бюджеты посева B {1, 2, 5, 10, 20, 50, 100, 200, 500} Конструкция: лог-сетка от 1 узла до 1 % N; «равный бюджет» = равное число посеянных УЗЛОВ (ТЗ)
15 Прогонов на точку A: 30; B: 40; C: 40 Допущение: бюджет рантайма ≤ 10 мин (§8); разрыв, не видимый поверх SEM на 30–40 прогонах, не является GTM-аргументом
16 Лимит раундов T_max 100 Техника: защитный предел; выход по T_max логируется
17 Посев экспериментов B и C один случайный чат размера 10–14 (факт: 970 кандидатов = 28 % C) Centola 2010: посев соседства (локально плотный); окно 10–14 убирает дисперсию размера посева. Аналитика окна — с continuity-поправкой округления: s ∈ {10..14} ⟺ x ∈ [9,5; 14,5) ⟹ 27,5 % C = 953 (фикс v1.2: без поправки выходило 764 — CHANGELOG)
18 Посев C на графе без клик случайный узел степени ≥ 11 + 11 его случайных соседей (итого 12) Конструкция: локальный посев того же размера, что медианный чат — симметрия протокола
19 R_eff пулированное отношение поколений (§3.4) по прогонам с G₁ ≥ 1; отдельно P_macro = P(охват ≥ 5 % N) Конструкция: кейс-репродукция ранних поколений; условие G₁ ≥ 1 и P_macro — декомпозиция бимодальности (розжиг × распространение), урок v1.0
20 Точка эксперимента C и T3: p_C max(p*, 0,7) Конструкция: глубоко в сверхкритике ОБЕИХ механик (аналитика: p_c^MF simple ≈ 0,03, p_c^chat complex ≈ 0,52 — запас ≥ 35 %); контраст C структурный, не параметрический, потолок его не маскирует. Уточнение v1.2: complex на G_BA при p = 0,7 МЕДИАННО мёртв (0,024 % N), но изредка зажигается через rich-club-ядро (≈ 15 % посевов — §9.12); именно это T3 ловит через P_macro
21 Хабы («каналы») топ-B узлов по степени итогового графа (BA + клики) ТЗ; степень союзного графа = суммарная досягаемость узла (личные + со-чатники); оговорка §9.10
22 GIF: N_gif, C_gif 4 000; 277 = round(3 460·4 000/50 000) ТЗ (разрешено 3–5k); пропорция клик сохранена, подпись «иллюстративный масштаб»
23 Палитра фон #0D0A1A; #6B2FFF / #00D4F5 / #FF4D8D / #FFD426 ТЗ, sim1

2. Конструкция графа, точно

2.1 Подложка: Barabási–Albert

G_BA = networkx.barabasi_albert_graph(n=50_000, m=3, seed=42). Рёбер (N−m)·m ≈ 149 991, средняя степень ≈ 6. Интерпретация ребра BA — личная связь (контакт, личка). Хвост степеней P(k) ~ k^−3 — мишень T1, меряется на чистом G_BA ДО посадки клик.

2.2 Плантированные клики с перекрытием (Telegram-чаты)

Число клик C = 3 460 (калибровка — §1.5). Посадка последовательная, c = 0…C−1:

  1. Размер: s_c = int(clip(round(LogNormal(μ = ln 12, σ = 0,6)), 5, 40)) — как в v1.0. Аналитика (для T2): медиана 12; E[s] ≈ 14,2; q10 = 6; q90 = 26; P(s=5) ≈ 9,7 %; P(s=40) ≈ 2,4 %.
  2. Наследование (перекрытие): чат 0 — родителей нет; чат 1 — один родитель (чат 0); чат c ≥ 2 — n_par = 2 РАЗНЫХ родителя, выбранных равномерно из уже посаженных чатов 0…c−1. Из каждого родителя равномерно без повторов берутся o = 2 его участника; дубли между родительскими парами схлопываются (унаследованных уникальных ≤ 4 < 5 ≤ s_c — переполнение исключено).
  3. Свежий добор: s_c − |унаследованные| узлов равномерно из всех V без повторов внутри чата (узел может состоять в нескольких чатах).
  4. Посадка: (а) все попарные рёбра клики добавляются в граф, дубликаты с BA-рёбрами, рёбрами других клик и рёбрами внутри унаследованных пар схлопываются — граф простой; (б) состав чата сохраняется в membership-структуре (нужна посеву кликами §4.1, посеву-чату §4.2, мишеням T2/T2c и НЕ нужна динамике — лемма 2.4).

Интерпретация наследования: новые чаты отпочковываются от существующих — людей приводят знакомые; реальные сообщества перекрываются (Palla et al. 2005), и именно перекрытия кластеров проводят complex contagion (Centola 2010). Побочный реализм: вероятность быть унаследованным ∝ числу текущих членств → хвост «чат-хопперов» (rich-get-richer по членствам) — §9.9.

Свойства посадки (аналитика + эмпирика seed=42, проверено скриптом):

RNG посадки: default_rng(SeedSequence(42, spawn_key=(0,0,0))).

2.3 Хабы = каналы

Хабы — топ-узлы по степени итогового графа G (BA + клики), тай-брейк — меньший id. Интерпретация: узлы максимальной суммарной досягаемости (Telegram-каналы и суперактивные участники чатов — не различаются, оговорка §9.10). Ненаправленность хаба — ограничение §9.3.

2.4 Клика как гиперребро широковещания: формализация и лемма о редукции

Семантика ТЗ: «внутри клики одно сообщение = касание всем участникам одновременно». Формально: чат c — гиперребро h_c ⊆ V; трансляция узла u ∈ h_c порождает касание ⟨источник u → узел v⟩ для каждого v ∈ h_c \ {u} за один раунд. Личный канал: трансляция u порождает касание ⟨u → v⟩ для каждого BA-соседа v.

Лемма о редукции (подтверждена в v1.0 наивной референс-реализацией байт-в-байт). Если (1) касание идентифицируется ИСТОЧНИКОМ, а не сообщением, (2) каждый узел транслирует не более одного раза за каскад (§3.3), (3) граф простой, — то множество источников, коснувшихся v за историю каскада, равно множеству транслировавших соседей v в союзном графе G, и счётчик различных источников v равен сумме по раундам числа транслировавших соседей v. Следствие: динамика — один sparse-matvec на раунд (touches += A @ sharers_t), без явного перебора гиперрёбер; двойное касание «лично + через общий чат» от одного u схлопывается в один источник автоматически. Гиперрёберная семантика сохранена полностью.


3. Механика заражения, точно (без изменений против v1.0)

3.1 Состояния узла

3.2 Касание и принятие

Касание — событие ⟨источник u → узел v⟩ по любому из двух каналов (§2.4): личному (BA-ребро) или чатовому (общее гиперребро). Касания от одного источника по разным каналам/чатам считаются ОДНИМ источником (дедуп по u — лемма 2.4). Принятие: S-узел v принимает в конце раунда t, если touches[v] ≥ k. Complex: k = 2 (два разных соседа — Centola). Simple: k = 1. Оба канала активируются одной трансляцией: узел, решивший шарить, постит во все свои чаты И шлёт всем личным (BA) соседям — одна монетка p на узел, не на канал (упрощение — §9.5).

3.3 Синхронные раунды

t=0: посев Σ₀ принимает (A), will_share=да для всех сеяных (p_seed=1)
раунд t≥1:
  sharers_t = {узлы, принявшие в t−1 с will_share=да}
  touches  += A_csr @ indicator(sharers_t)          # лемма 2.4
  new       = {v ∈ S: touches[v] ≥ k}
  new → A; will_share[new] = (U(0,1) < p)           # монетка один раз, навсегда
терминация: sharers_t пусто (некому слать) ИЛИ t = T_max=100 (логируется)

sharers_t пусто ⟹ новых касаний не будет ⟹ каскад мёртв — критерий точный, не эвристика. Охват прогона = |A| в терминации (включая посев).

3.4 Поколения, R_eff, P_macro

G₀ = посев; G_t = узлы, принявшие в раунде t. Эффективный branching factor прогона:

R_eff = ( G₂ + G₃ + G₄ ) / ( G₁ + G₂ + G₃ ), при нулевом знаменателе R_eff := 0.

Пулированное отношение соседних ранних поколений (до насыщения; ratio-метод обходит атрибуцию complex-принятия двум родителям). Агрегация по прогонам (изменение v1.1): R_eff агрегируется средним ПО ПРОГОНАМ С G₁ ≥ 1 (условный на розжиг первого поколения); отдельно печатается P_macro(p) = доля прогонов с охватом ≥ 5 % N — вероятность макрокаскада (порог согласован с §1.11). Разложение mean охвата = P_macro × условный охват — рабочий язык бимодальности (урок v1.0). Суб-/крит-/сверхкритика: R_eff < 1 / ≈ 1 / > 1; аналитическая референс-линия R_eff = 1.

Замечание к розжигу (следствие §2.2): при посеве-чате общие узлы посева с соседними чатами сеяны и шарят гарантированно (p_seed = 1) ⟹ мостовые соседи посева зажигаются детерминированно, G₁ ≈ 55 узлов > 0 всегда. Nucleation-барьер v1.0 снят конструкцией; фазовый переход управляется РАСПРОСТРАНЕНИЕМ (мост проводит с вероятностью p² — оба общих узла шарят), а не розжигом.


4. Протоколы экспериментов

4.1 Эксперимент A — посев при равном бюджете (fig8)

Режим: complex k = 2, p = p*. «Равный бюджет» = равное число посеянных узлов B ∈ {1, 2, 5, 10, 20, 50, 100, 200, 500}. Стратегии:

30 прогонов на точку; RNG: spawn_key=(1, strategy_id·100+B_index, run); strategy_id приколочен: 0 = random, 1 = top-hubs, 2 = random-cliques, 3 = top-BA (нумерация 0–2 совпадает с v1.2 — воспроизводимость опубликованных чисел не трогается). Метрики: охват = |A| в терминации; reach-per-seed = (охват − B)/B. Агрегат — СРЕДНЕЕ по прогонам ± 1 SEM (критерий фальсификатора §6 определён на средних; mean честен при бимодальности — §3.4).

Декомпозиция хабов (v1.3) — печатается в stdout и в README рядом с таблицей A. Обозначим H₅₀₀ — топ-500 узлов по union-степени deg_G (тай-брейк — меньший id, §2.3); H₅₀₀^BA — топ-500 по степени чистого G_BA deg_BA (тот же тай-брейк). Три числа, считаемые В КОДЕ:

  1. Доля кликовой степени у топ-500 union = Σ_{v∈H₅₀₀}(deg_G(v) − deg_BA(v)) / Σ_{v∈H₅₀₀} deg_G(v). Разность deg_G − deg_BA = число соседей, добавленных кликовыми рёбрами сверх BA (дубликаты BA-рёбер схлопнуты — граф простой, §2.2.4).
  2. Пересечение H₅₀₀ ∩ H₅₀₀^BA (из 500).
  3. Членства хопперов: медиана и максимум числа чатов на узел по membership (§2.2) среди v ∈ H₅₀₀. Ориентир аудита v1.2: 81,6 %; 84/500; медиана 8 / max 42. Кодовые числа могут отличаться на детали определения; допусков-мишеней нет — блок справочный, не T-мишень.

Правило p* (изменение v1.1): эксперимент B гонится ПЕРВЫМ; p* = min{p из сетки: mean охват(k = 2, посев-чат §4.2) ≥ 5 % N}. По конструкции v1.1 p* существует (при p = 1 мосты проводят с вероятностью 1, мостовой слой связен ⟹ охват ≥ покрытие ≈ 50 % N); страховочная ветка сохраняется: если p* не существует — печатается «p* не существует; эксперимент A и фальсификатор GTM не интерпретируемы; конструкция пересматривается», T3 проваливается штатно. Никаких тихих fallback-ов.

4.2 Эксперимент B — фазовая диаграмма по p (fig9)

Оба режима: k = 1 и k = 2. Сетка p — 20 точек (§1.10), 40 прогонов на точку и режим. Посев прогона: один случайный чат размера 10–14 (весь состав; 970 кандидатов — факт §1.17; локально плотный посев — Centola 2010). RNG: spawn_key=(2, k·100+p_index, run). Измеряется: финальный охват (доля N, с посевом), R_eff и P_macro (§3.4).

Агрегаты (изменение v1.1): охват — МЕДИАНА + IQR и mean (медиана показывает типичный исход, mean — GTM-ожидание; расхождение кривых = визуальная подпись бимодальности); R_eff — среднее по прогонам с G₁ ≥ 1; P_macro — доля прогонов.

Выходы: p_c(k) = min{p: mean охват ≥ 5 % N} для k = 1, 2 (печатаются; p_c(2) = p*). Аналитические референс-вертикали: (а) simple — mean-field порог бондовой перколяции p_c^MF = ⟨k⟩/(⟨k²⟩−⟨k⟩) по фактическим степеням G (Newman 2002), подпись «аналитика (mean-field)»; (б) complex (новое в v1.1) — mean-field мостового слоя: p_c^chat = 1/√(d̄_bridge − 1), где d̄_bridge — фактическая средняя степень B_chat (ветвление чатового каскада b = (d̄−1)·p², мост проводит при p² — оба общих узла шарят); при d̄ ≈ 4,7 оценка ≈ 0,52. Подпись: «аналитика: mean-field мостового слоя, оценка СВЕРХУ (хвост степеней B_chat и личные BA-рёбра понижают порог)».

4.3 Эксперимент C — где ломается «теория рукопожатий» (T3)

Один чёткий протокол: контраст 2×2 «граф × механика» при одинаковом p и локальном посеве одинакового размера.

Читается так: simple (k=1) проводится длинными слабыми связями BA-хабов и живёт на обоих графах — «теория рукопожатий» Granovetter работает для информации. Complex (k=2) требует широких мостов: на G_BA розжиг ненадёжен — второй источник лишь изредка (≈ 15 % посевов) собирается в плотном rich-club-ядре BA (§9.12), хотя зажёгшийся каскад макроскопичен; перекрытия чатов G (§2.2) дают второй голос достоверно. Печатается матрица 2×2: P_macro и mean-охват. Численные пороги — мишень T3 (§5).


5. Валидационные мишени T1–T3

Engineer печатает блок VALIDATION (мишень → получено → допуск → PASS/FAIL) в stdout и в sim2/README.md ДО любых выводов. Любой FAIL ⟹ выводы не публикуются, процесс завершается с ненулевым кодом и текстом «МИШЕНЬ ПРОВАЛЕНА». Все мишени — assert-совместимые неравенства.

Мишень Что меряем Допуск Основание
T1 Показатель хвоста степеней чистого G_BA (до клик): дискретный MLE Ньюмана γ̂ = 1 + n·[Σ_{k_i≥k_min} ln(k_i/(k_min−0,5))]^{−1}, k_min = 15 γ̂ ∈ [2,6; 3,4] BA 1999: γ = 3; конечный N и k_min-обрезка дают ±0,4 (Newman 2005). v1.0-факт: 2,913 PASS
T2 Фактически посаженные размеры клик (C = 3 460 значений) медиана ∈ [11; 13]; среднее ∈ [13,3; 15,0]; P(s=5) ≤ 0,12; P(s=40) ≤ 0,04 Аналитика клипнутой лог-нормали §2.2; посадка v1.1 распределение размеров не меняет
T2b Доля узлов, состоящих в ≥ 1 чате ∈ [0,45; 0,55] Калибровка C на q = 0,50 (§1.5–1.6); эмпирика посадки: 0,493–0,506 на C = 3 400–3 500
T2c (новая) Мостовой слой B_chat (§2.2): (а) доля чатов c ≥ 1, имеющих ≥ 1 широкий мост (пересечение ≥ 2 узла с другим чатом); (б) средняя степень d̄(B_chat) (а) ≥ 0,99; (б) ∈ [4,0; 5,5] По построению (а) = 1,0 строго (o = 2 без повторов внутри родителя); (б): конструкционный минимум 2·n_par = 4 + случайные пересечения; эмпирика seed=42: d̄ ≈ 4,72. Связность B_chat — по построению, печатается справочно
T3 Канонический контраст Centola при p_C = max(p*, 0,7), 40 прогонов на ячейку; единая метрика — P_macro = P(охват ≥ 5 % N) (§3.4), mean-матрица 2×2 печатается справочно: (а) G_BA simple: P_macro ≥ 0,75; (б) G_BA complex: P_macro ≤ 0,25; (в) G complex: P_macro ≥ 0,75 все три неравенства Тезис Centola 2010 — про НАДЁЖНОСТЬ распространения complex на кластеризованной против random-топологии, поэтому мишень — на вероятности макрокаскада, не на величине условного охвата (зажёгшийся complex-каскад макроскопичен на обоих графах — §9.12). Пороги — симметричная квартильная пара: «достоверен» = чаще 3 из 4 посевов, «ненадёжен» = реже 1 из 4; обоснование внешнее — семантика пары плюс статразделимость (SE доли при 40 прогонах ≤ 0,08 ⟹ пороги разнесены на > 6 SE, контраст не спутать с шумом), не значения ре-рана. Урок v1.2: mean-порог «< 5 %» был категориальной ошибкой метрика/порог — CHANGELOG

T3 автоматически проваливается, если p* не существует (§4.1) — штатный стоп конструкции. Провал T3(в) при выполненных (а)–(б) читается отдельно: контраст Centola на месте, но мостовой слой слишком редок для макрокаскада — печатается именно это.


6. Фальсификатор GTM (критерий без изменений; оговорка B=1 — v1.2; контроль top-BA — v1.3)

Дословно из ТЗ: «если при complex contagion посев в хабы НЕ бьёт случайный при равном бюджете — гипотеза хабов Tonify неверна, так и написать».

Численный критерий (по эксперименту A, complex k = 2, p = p*, средние по 30 прогонам):

Оговорка контроля (v1.3): top-BA в критерий НЕ входит. Критерий определён на top-hubs (union-степень, §2.3) vs random и после трёх ревизий не меняется; top-BA (§4.1) — контрольная стратегия интерпретации «каналы vs чат-хопперы», её числа печатаются рядом с вердиктом без участия в нём.

Оговорка вырожденности (v1.2): B = 1 исключается из критерия. При k = 2 двух РАЗНЫХ источников от одного сеяного узла не существует структурно — все стратегии тождественно дают нулевую органику, точка не различает стратегии. Она остаётся на fig8 (и сама по себе GTM-факт: complex-трек не сеется одним постом), но сравнение стратегий и вердикт фальсификатора определены на B ≥ 2.

Критерий на средних, без статкритериев — намеренно: разрыв, который не виден поверх SEM на 30 прогонах, не является GTM-аргументом.


7. Фигуры

Общее: фон #0D0A1A, сетка/оси приглушённые, каждая кривая подписана «симуляция» или «аналитика» (референс-линии — #FFD426, пунктир) — конвенция sim1. Файлы в /figures (нумерация продолжает sim1: fig1–7 заняты).

fig8_reach_per_seed.png — эксперимент A. Оси: X — бюджет посева B (лог-шкала, 1…500); Y — reach-per-seed = (охват−B)/B. Кривые (симуляция, среднее ± лента 1 SEM, 30 прогонов): top-hubs #6B2FFF, random #00D4F5, random-cliques #FF4D8D, top-BA #00E08F (контроль, §4.1; выбор v1.3: зелёный — единственная свободная от занятых серий и референсов ось палитры, отличим от всех на фоне #0D0A1A). Референс: горизонталь y = 0 «нет органики» (#FFD426, пунктир, «аналитика: посев без размножения»). В подписи: режим complex k=2, значение p*.

fig9_phase_diagram.png — эксперимент B. Две панели, общая ось X = p (0,05…1,00). Верх: финальный охват (% N) — медиана + IQR-лента И mean тонкой линией того же цвета (расхождение mean/медианы = визуальная подпись бимодальности); complex k=2 #6B2FFF, simple k=1 #00D4F5 (симуляция). Референс-вертикали #FFD426 пунктир: p_c^MF simple («аналитика: mean-field ⟨k⟩/(⟨k²⟩−⟨k⟩)») и p_c^chat complex («аналитика: mean-field мостового слоя 1/√(d̄−1), оценка сверху»); измеренные p_c(1), p_c(2)=p* — засечки «симуляция». Низ: условный R_eff vs p (левая ось, те же цвета; горизонталь R_eff = 1 #FFD426 «аналитика: порог критичности»; заливка зон суб-/сверхкритики complex) и P_macro vs p (маркеры-точки без линии на общей левой оси — dual-axis запрещён; те же цвета с прозрачностью; подпись «P_macro = P(охват ≥ 5 % N)»). Подпись панели: «посев: один случайный чат (10–14 узлов); 40 прогонов/точку».

fig10_cascade.gif — один complex-каскад (k=2, p = p*), N_gif = 4 000, C_gif = 277, та же конструкция графа (§2, тот же μ/σ/клиппинг, та же посадка с перекрытием, seed=42), посев — случайный чат 10–14. Кадр = раунд (плюс 5 финальных статичных кадров); число кадров = фактическая длина каскада + 5 финальных, ориентир 15–40 (фикс v1.3: старое окно «25–40» недостижимо при N_gif = 4 000 и p* = 0,15 — max каскад 14 раундов на всех 40 сидах, CHANGELOG); ~4 fps, spring-layout (networkx, seed=42). Цвета узлов: непринявшие с 0 касаний — тусклый производный от фона (#2A2342); на пороге (1 касание из 2) — #00D4F5; принявшие — #FF4D8D; транслирующие в текущем раунде — вспышка #FFD426; посев — #6B2FFF. Размер узла ~ степень. Обязательная подпись в кадре: «иллюстративный масштаб N = 4 000; конструкция графа идентична основной (N = 50 000)».


8. Рантайм, детерминизм, артефакты


9. Честные ограничения

Модель сознательно НЕ моделирует:

  1. Забывание и отписки. Касания копятся бессрочно, принятие необратимо — охват является оценкой сверху; затухание внимания сдвинуло бы критику вправо.
  2. Конкуренцию треков и насыщение ленты. Один трек в вакууме.
  3. Направленность каналов. Реальный канал — направленный broadcast; наш хаб ненаправленный: и вещает, и слушает — переоценивает способность хаба ПРИНЯТЬ трек (собрать k касаний). Читать рядом с вердиктом фальсификатора §6.
  4. Гетерогенность порогов. k = 2 у всех; в реальности пороги распределены (threshold-модели Granovetter 1978) — часть узлов принимает с одного касания.
  5. Раздельные вероятности каналов. Одна монетка p на узел активирует оба канала; шанс переслать другу ≠ шанс запостить в чат.
  6. Посадка чатов подчинена существованию мостов — признание. v1.0 сажала клики независимо и равномерно; это дало ПОЛНОЕ отсутствие широких мостов (пересечения ≥2 у ~1,2 % чатов) и блокаду complex contagion при любых p (CHANGELOG) — артефакт независимой посадки, а не свойство Telegram. Посадка v1.1 (наследование o=2 от n_par=2 родителей) выбрана так, чтобы широкие мосты существовали ПО ПОСТРОЕНИЮ; оправдание реализмом: перекрывающиеся сообщества — эмпирика соцсетей (Palla et al. 2005), и именно перекрытия проводят complex (Centola 2010). Параметры n_par, o — минимальные, не подогнанные под величину эффекта; но КОЛИЧЕСТВЕННАЯ плотность мостового слоя (d̄ ≈ 4,7) — конструкция, не измерение Telegram. Выводы о местоположении критики p_c^chat переносятся на реальность с точностью до этой плотности.
  7. Гомофилию чатов к BA-ткани. Состав чата не коррелирует с личными (BA) связями участников; перекрытие живёт только в чатовом слое.
  8. Динамику графа. Граф статичен на время каскада.
  9. Хвост членств — побочный продукт наследования. Rich-get-richer по членствам (максимум 42 чата у узла — факт прогона, §2.2) правдоподобен («чат-хопперы», админы), но не калиброван ни на какие данные Telegram.
  10. Качество контента и статус хаба. p одинаков для всех узлов; посев транслирует с вероятностью 1 (оплаченный пост) — верхняя оценка эффективности посева; хаб определён суммарной досягаемостью (union degree), «канал» и «суперактивный юзер» не различаются.
  11. Размеры чатов — допущение. μ, σ лог-нормали не измерены; сетка чувствительности по μ, σ, q, n_par, o в scope sim2 не входит (ТЗ).
  12. Rich-club-розжиг на чистом BA — находка, не ограничение (v1.2). «Теория рукопожатий» ломается на complex вероятностно, а не абсолютно: даже без клик плотное ядро BA (взаимно связанные узлы высоких степеней; при ре-ране v1.1 — степени центров розжига 11–257) в ≈ 15 % посевов собирает второй источник, и зажёгшийся каскад доходит до ~82–84 % N. Клики меняют не возможность, а НАДЁЖНОСТЬ распространения: P(макрокаскад) 1,00 против 0,15 (T3). Оверклейм «без клик complex невозможен» в выводах запрещён.

Ни один вывод sim2 не заявляется сильнее своего фальсификатора (§6) и валидационных мишеней (§5).