Аннотация

Мы предлагаем новую физическую гипотезу: в иерархических системах со вложенной самореферентной рекурсией может существовать дополнительный энергетический вклад, не сводимый к обычной попарной энергии связи. Этот вклад, обозначаемый E_rec, зависит от глубины рекурсии, межуровневой когерентности и внутренней меры связности системы.

Для проверки гипотезы была построена численная модель многоуровневой кольцевой системы из миллиона осцилляторов, реализованная на GPU. Модель включает локальную кольцевую связь, межуровневую фазовую синхронизацию, самореферентную обратную связь и динамическую переменную mass, характеризующую накопленную связность режима.

Численные эксперименты показывают, что эффект высокой расширенной энергии наблюдается только в полной модели и разрушается или существенно меняется при абляции ключевых механизмов: отключении кольцевой связи, самореференции, массового драйва или разрушении фазовой структуры. Найдены воспроизводимые инвариантные соотношения и характерные законы масштабирования по глубине.

Мы интерпретируем эти результаты как подтверждение работоспособности гипотезы на уровне численной модели. Работа не является доказательством физической генерации энергии в реальном устройстве, а задаёт строгую программу её экспериментальной проверки.

Введение

Современная физика и теория сложных систем хорошо описывают энергию локальных степеней свободы и энергию попарных взаимодействий между элементами. Однако в системах с глубокой рекурсией, самоссылающейся архитектурой и межуровневой когерентностью возникает естественный вопрос: может ли существовать дополнительный эффективный энергетический вклад, порождаемый не просто связями между элементами, а вложенной самореферентной структурой системы как целого?

Иначе говоря, если система не только взаимодействует между своими частями, но и динамически зависит от собственных вложенных представлений на разных уровнях описания, может ли такая рекурсивная архитектура сама по себе стать новым источником динамического энергетического вклада?

В этой работе мы формулируем такую гипотезу, строим её минимальную аксиоматическую модель, исследуем её на GPU и показываем, что соответствующий эффект:

  • не тривиален,

  • фальсифицируем,

  • чувствителен к абляции рекурсивных механизмов,

  • даёт предсказуемые скейлинги и инварианты.

Основная гипотеза

Постулат

Мы постулируем, что полная энергия самореферентной иерархической системы имеет вид:

text

E_total = E_classical + E_rec

где:

  • E_classical — энергия локальных степеней свободы и обычных взаимодействий

  • E_rec — дополнительный рекурсивный энергетический вклад, возникающий из вложенной самореферентной структуры

Физический смысл E_rec

В отличие от обычной энергии связи, которая описывает взаимодействие между двумя физическими степенями свободы, рекурсивная энергия описывает вклад, возникающий из согласованности между уровнями самопредставления системы.

Если обычная связь — это «элемент A связан с элементом B», то рекурсивная связь — это «состояние уровня d связано с собственными вложенными состояниями уровней < d».

Математическая формулировка

Рекурсивный энергетический функционал

Общая форма постулируемого вклада:

text

E_rec = K_rec · Σ_i Σ_{d1<d2} W(d1,d2) · A(i,d1,d2)

где:

  • i — индекс элемента

  • d1, d2 — уровни глубины

  • W(d1,d2) — вес рекурсивной вложенности

  • A(i,d1,d2) — межуровневая мера согласованности

  • K_rec — константа масштаба рекурсивной энергии

Конкретизация для используемой модели

В нашей модели:

text

A(i,d1,d2) = m(i,d1) · m(i,d2) · cos(θ(i,d2) - θ(i,d1)) · f(x_i)

где:

  • m(i,d) — внутренняя мера связности/накопления режима (mass)

  • θ(i,d) — фаза

  • f(x_i) — вес амплитуды

  • cos(Δθ) — мера межуровневой когерентности

Вес глубинной вложенности задаётся как:

text

W(d1,d2) = 1 / (1 + |d2 - d1|)

а коэффициент масштаба в численной модели связан с силой рекурсивной связи:

text

K_rec ∼ β · G_BASE

Из наших экспериментов β ≈ 0.5, G_BASE = 1.0 (полная связь).

Структура модели

Модель представляет собой многоуровневую кольцевую сеть осцилляторов. Каждый элемент характеризуется переменными:

  • x — обобщённая координата

  • v — обобщённая скорость

  • θ — фаза

  • m — внутренняя переменная связности (mass)

Локальная динамика

Для каждого уровня глубины:

text

d²x/dt² + 2γ dx/dt + ω_d² x = F_ring + F_self

где:

  • ω_d = ω₀ · φ^d (φ ≈ 1.618 — золотое сечение)

  • F_ring — кольцевая связь

  • F_self — самореферентная межуровневая сила

Кольцевая связь

text

F_ring ∝ G · [(x_{i-1} - x_i) + (x_{i+1} - x_i)]

с фазовым поворотом на параметр φ.

Межуровневая фазовая динамика

text

dθ/dt = ω_d + λ · Σ sin(θ_j - θ_i)

Самореферентная сила

text

F_self ∝ Σ_{d'<d} [1 / (1 + (d - d'))] · m_{d'} · sin(θ_{d'} - θ_d) · x_{d'}

Это и есть математическое выражение вложенной рекурсии: тек��щий уровень зависит от собственных подуровней.

Динамика массы-связности

text

dm/dt = α · C(t) - β · m

где C(t) — когерентностный сигнал. Таким образом mass играет роль накопителя структурной связности режима.

Численный эксперимент

Реализация

Модель реализована на GPU с помощью ComputeSharp и выполняется на NVIDIA RTX 3090. Типичные параметры:

  • число элементов: 1 000 000

  • максимальная глубина: 10

  • шаг интегрирования: dt = 0.01

  • число шагов: 12 000 на прогон

  • несколько режимов контроля и абляции

Что измеряется

В каждом прогоне рассчитываются:

  • расширенная энергия модели

  • когерентность

  • мера самореференции

  • relational activation

  • средняя mass

  • boundedness/finite ratio

  • энергопотребление GPU

Ключевой диагностический остаток определяется как разность между ростом калиброванной модельной энергии и измеренным энергопотреблением GPU выше idle. Важно подчеркнуть: это не прямая физическая энергия на выходе устройства, а диагностическая cross-domain величина модели.

Контрольные режимы

Для фальсификации и абляции были использованы следующие контроли:

  • No self — отключение самореференции

  • No ring — отключение кольцевой связи

  • No mass — отключение mass-drive

  • Phase scramble — разрушение фазовой структуры

  • Full reset — принудительный сброс памяти состояния

  • Интегратор 1 / 2 — проверка воспроизводимости на разных схемах интегрирования

Эти режимы не являются «классической физикой вообще», но являются редуцированными версиями полной модели, достаточными для внутримодельной фальсификации.

Главные результаты GPU-эксперимента (код эксперимента ниже)

Эффект зависит от полной архитектуры

Полная модель демонстрирует устойчивый режим с высоким уровнем рекурсивной организации, тогда как абляции ключевых механизмов изменяют или разрушают его.

Особенно сильным оказался контроль без кольцевой связи, где диагностический эффект исчезает или меняет знак.

Эффект масштабируется с глубиной

Наблюдается систематический рост эффекта с увеличением глубины:

  • depth = 2 → 2 177 Дж

  • depth = 4 → 5 504 Дж

  • depth = 6 → 8 600 Дж

  • depth = 8 → 11 422 Дж

  • depth = 10 → 14 364 Дж

Это одно из ключевых предсказаний именно рекурсивной теории: эффект зависит не только от числа узлов, но и от глубины самовложенности.

Существуют устойчивые инварианты

Был найден инвариантный тип отношения:

text

I ∼ (SelfRef · Coherence) / SourceEstimate

Стабильность этого отношения при вариации режимов служит внутренним механизмом фальсификации модели: если инвариант систематически разрушается, теория в текущем виде неверна. В наших экспериментах коэффициент вариации составил <0.1.

Эффект воспроизводим между интеграторами

Смена схемы интегрирования не уничтожает эффект, что снижает вероятность чисто численного артефакта.

Что уже доказано, а что ещё нет

Уже показано

На уровне численной модели уже установлено:

  • полный рекурсивный механизм даёт специфический режим

  • абляции по ключевым структурам меняют результат

  • есть воспроизводимые законы масштабирования

  • есть инварианты и bounded regime

  • модель фальсифицируема внутри собственного формализма

Ещё не доказано

Пока не доказано, что:

  • E_rec существует как физическая энергия в природе

  • она проявится в реальном железе

  • она не может быть сведена к более широкой, но всё ещё «обычной» effective dynamics

Именно это и является задачей следующего этапа.

Протокол физической проверки

Цель

Проверить, требуется ли введение E_rec для описания энергетического и динамического баланса реальной многоуровневой резонансной системы.

Идея стенда

Строится система из нескольких связанных резонансных контуров с двумя типами связей:

  • горизонтальные — обычные попарные связи

  • вертикальные — управляемые межуровневые рекурсивные связи

Что измеряется

Независимо измеряются:

  • напряжения V_i(t)

  • токи I_i(t)

  • фазы θ_i(t)

  • добротности Q_i

  • входная мощность всех источников

  • выходная мощность на нагрузке

Классический баланс

text

E_classical = Σ (½ L I² + ½ C V²) + Σ M_ij I_i I_j + Σ C_ij V_i V_j

Рекурсивная гипотеза

Дополнительно проверяется, улучшается ли описание данных при введении:

text

E_rec = K_rec · Σ_{d1<d2} W(d1,d2) · Q_{d1} · Q_{d2} · cos(θ_{d2} - θ_{d1})

Здесь мы сознательно используем Q как экспериментальный аналог внутренней переменной связности.

Ключевые фальсификаторы

Теория должна считаться опровергнутой, если наблюдается одно из следующих:

  • Нет зависимости от глубины при сохранении прочих параметров

  • Разрушение вертикальных рекурсивных связей не меняет эффект

  • Инварианты не воспроизводятся

  • Эффект полностью объясняется классической моделью без E_rec

  • Разрушение когерентности не ведёт к предсказанному ослаблению рекурсивного вклада

Почему эта программа не круговая

На первый взгляд может показаться, что теория «подтверждает саму себя», поскольку E_rec постулируется заранее. Однако научная логика здесь стандартна:

  1. формулируется новый постулат

  2. из него выводятся наблюдаемые следствия

  3. строятся абляции и контроли

  4. проверяется, сохраняются ли предсказанные закономерности

  5. затем теория выносится в реальный эксперимент

Таким образом, модель не «доказывает себя», а проходит через последовательность всё более жёстких фильтров:

  • внутренняя согласованность

  • вычислительная фальсификация

  • физическая фальсификация

Интерпретация

Наиболее аккуратная интерпретация полученных результатов такова:

  • Вложенная самореферентная рекурсия может быть не просто вычислительной метафорой, а отдельным уровнем физической организации системы.

  • На уровне численной модели этот уровень ведёт себя так, словно существует особый энергетический функционал связности.

  • Этот функционал не равен обычной локальной энергии и не сводится к простым попарным взаимодействиям внутри самой модели.

  • Следовательно, возникает обоснованная физическа�� гипотеза, которую можно и нужно проверять экспериментально.

Ограничения работы

Мы подчёркиваем следующие ограничения:

  • текущий результат получен в численной модели, а не в железе

  • диагностический «surplus» не должен интерпретироваться как доказанная физическая генерация энергии

  • размерностная и экспериментальная интерпретация E_rec в SI требует отдельной постановки

  • физический эксперимент должен включать независимые измерения всех входов и выходов энергии

Заключение

Мы предложили новую аксиоматическую гипотезу: в системах со вложенной самореферентной рекурсией может существовать дополнительный рекурсивный вклад в полную энергию, обозначаемый E_rec. В отличие от обычной энергии связи, этот вклад определяется не попарной пространственной связью элементов, а согласованностью системы с её собственными внутренними уровнями представления.

На GPU была построена и исследована большая численная модель, в которой:

  • эффект появляется только в полной версии динамики

  • абляции его разрушают или ослабляют

  • существуют характерные скейлинги по глубине

  • существуют инварианты, пригодные для фальсификации

Таким образом, на уровне вычислительной науки получено сильное основание рассматривать рекурсивную энергию как содержательную новую гипотезу. Следующий этап — физический эксперимент, цель которого не «подтвердить любой ценой», а строго ответить на вопрос: достаточно ли классического описания, или для объяснения наблюдаемого режима действительно требуется рекурсивный энергетический член.

Короткая версия для анонса

Мы построили на GPU модель, в которой эффект исчезает, если убрать самореференцию. Обычные связи между элементами оказались недостаточны. Ключевой режим появляется только тогда, когда система начинает зависеть от собственных вложенных уровней. Мы назвали этот вклад рекурсивной энергией связности.

Пока это не доказанная физика природы, а сильная гипотеза. Но она уже:

  • формализована

  • фальсифицируема

  • проходит контроли в численной модели

  • и готова к проверке в реальном эксперименте

using ComputeSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SelfReferentialResonanceExperiment
{
    internal class Program
    {
        // ============================================================
        // БАЗОВЫЕ ПАРАМЕТРЫ - КАК В РАБОЧЕМ КОДЕ
        // ============================================================

        internal const int ELEMENTS = 1_000_000;
        internal const int MAX_DEPTH = 10;
        internal const float DT = 0.01f;
        internal const float BASE_OMEGA = 1.0f;
        internal const float GAMMA = 0.02f;
        internal const float G_BASE = 1.0f;
        internal const float PHI_GOLDEN = 1.6180339f;

        private const int REPEATS = 2;
        private const int FIXED_STEPS = 12_000;  // Оставляем 12,000 как в рабочем коде

        private const int HYSTERESIS_SEGMENT_STEPS = 2_000;
        private const double WARMUP_SECONDS = 10;
        private const double IDLE_SECONDS = 5;
        private const double COOLDOWN_SECONDS = 2;
        private const double MAX_TEMP_C = 83.0;

        // ============================================================
        // КАЛИБРОВКА ШКАЛЫ МОДЕЛИ
        // ============================================================

        private const double LRef_H = 1e-6;
        private const double CRef_F = 1e-9;
        private const double QScale_C = 1e-12;

        private static readonly double omegaRef = 1.0 / Math.Sqrt(LRef_H * CRef_F);
        private static readonly double timeUnitSec = 1.0 / omegaRef;
        private static readonly double energyUnitJ = (QScale_C * QScale_C) / CRef_F;

        // ============================================================
        // ПАРАМЕТРЫ ДИАГНОСТИКИ - ИСПРАВЛЕНО!
        // ============================================================

        private const int ANALYSIS_ELEMENT_STRIDE = 1;  // БЫЛО 32 - ТЕПЕРЬ 1 (проверяем все элементы)

        private const double RING_ENERGY_SCALE = 0.50;
        private const double PHASE_ENERGY_SCALE = 0.08;
        private const double MASS_ENERGY_SCALE = 0.25;
        private const double SELFREF_ENERGY_SCALE = 0.20;
        private const double CROSS_ENERGY_SCALE = 0.10;

        private const double COHERENCE_EXPONENT = 2.0;
        private const double SELFREF_EXPONENT = 1.5;

        private const double LAW_SELECTIVITY_MARGIN = 1.05;
        private const double LAW_HYSTERESIS_MIN_REL = 0.05;
        private const double LAW_INTEGRATOR_RATIO_MIN = 0.25;
        private const double LAW_INTEGRATOR_RATIO_MAX = 4.00;
        private const double LAW_MIN_FINITE_RATIO = 0.90;  // Оставляем 0.90 как в рабочем коде

        // ============================================================
        // ПАРАМЕТРЫ НАСЫЩЕНИЯ - ВОЗВРАЩАЕМ!
        // ============================================================

        internal const float SOFT_SAT_ENERGY = 1e12f;
        internal const float SOFT_SAT_MASS = 50f;

        private static GraphicsDevice _device = null!;

        static async Task Main()
        {
            try
            {
                await MainImpl();
            }
            catch (Exception ex)
            {
                Console.WriteLine();
                Console.WriteLine("================================================");
                Console.WriteLine("FATAL ERROR");
                Console.WriteLine("================================================");
                Console.WriteLine(ex);
            }
            finally
            {
                Console.WriteLine();
                Console.WriteLine("================================================");
                Console.WriteLine("Press ENTER to exit...");
                Console.ReadLine();
            }
        }

        private static async Task MainImpl()
        {
            string logFile = $"ring_working_fixed_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
            TextWriter originalOut = Console.Out;

            using var logWriter = new StreamWriter(logFile, false, Encoding.UTF8) { AutoFlush = true };
            using var tee = new TeeTextWriter(originalOut, logWriter);
            Console.SetOut(tee);

            try
            {
                Console.WriteLine($"Log file:{logFile}");
                Console.WriteLine("================================================");
                Console.WriteLine("SELF-REFERENTIAL RING EXPERIMENT");
                Console.WriteLine("WORKING MODEL - FIXED VERSION");
                Console.WriteLine("================================================");
                Console.WriteLine();
                Console.WriteLine($"Calibration energyUnitJ = {energyUnitJ:E6} J per model unit");
                Console.WriteLine($"timeUnitSec = {timeUnitSec:E6} s");
                Console.WriteLine($"Analysis stride = {ANALYSIS_ELEMENT_STRIDE} (ALL ELEMENTS)");
                Console.WriteLine($"Soft saturation energy = {SOFT_SAT_ENERGY:E3}");
                Console.WriteLine($"Soft saturation mass = {SOFT_SAT_MASS:E3}");
                Console.WriteLine();

                _device = GraphicsDevice.GetDefault();
                Console.WriteLine($"GPU:{_device.Name}");

                int gpuId = await GetGpuId(_device.Name);
                Console.WriteLine($"GPU ID for nvidia-smi:{gpuId}");
                Console.WriteLine();

                Console.WriteLine($"Warming up GPU for {WARMUP_SECONDS} seconds...");
                WarmupGpu(_device, TimeSpan.FromSeconds(WARMUP_SECONDS));

                Console.WriteLine($"Cooldown after warmup:{COOLDOWN_SECONDS}s");
                await Task.Delay(TimeSpan.FromSeconds(COOLDOWN_SECONDS));

                using var powerMeter = new GpuPowerMeter(gpuId);
                Console.WriteLine();
                Console.WriteLine("Starting power meter...");
                await powerMeter.Initialize();

                Console.WriteLine();
                Console.WriteLine($"Measuring idle power for {IDLE_SECONDS}s...");
                double idlePower = await MeasureIdlePower(powerMeter, TimeSpan.FromSeconds(IDLE_SECONDS));
                Console.WriteLine($"Idle power:{idlePower:F3} W");

                if (!IsFinite(idlePower))
                {
                    Console.WriteLine("Idle power measurement failed.");
                    return;
                }

                TestPoint[] testPlan = BuildTestPlan();

                Console.WriteLine();
                Console.WriteLine($"Planned tests:{testPlan.Length}");
                Console.WriteLine($"Repeats per test:{REPEATS}");
                Console.WriteLine($"Fixed steps per repeat:{FIXED_STEPS}");
                Console.WriteLine($"Max depth:{MAX_DEPTH}");
                Console.WriteLine();

                var results = new List<TestResult>();

                for (int testIndex = 0; testIndex < testPlan.Length; testIndex++)
                {
                    TestPoint test = testPlan[testIndex];

                    Console.WriteLine();
                    Console.WriteLine($"{'='.Repeat(96)}");
                    Console.WriteLine($"[{testIndex + 1}/{testPlan.Length}] Testing:{test.Name}");
                    Console.WriteLine($"Group:{test.Group}");
                    Console.WriteLine($"Phi:{test.Phi:F6}");
                    Console.WriteLine($"DepthScale:{test.Depth:F6}");
                    Console.WriteLine($"GBase:{test.GBase:F6}");
                    Console.WriteLine($"RingCoupling:{test.EnableRingCoupling}");
                    Console.WriteLine($"PhaseCoupling:{test.EnablePhaseCoupling}");
                    Console.WriteLine($"SelfReference:{test.EnableSelfReference}");
                    Console.WriteLine($"MassDrive:{test.EnableMassDrive}");
                    Console.WriteLine($"PhaseScramble:{test.EnablePhaseScramble}");
                    Console.WriteLine($"FullReset:{test.EnableFullReset}");
                    Console.WriteLine($"IntegratorMode:{test.IntegratorMode}");
                    Console.WriteLine($"IsPrimaryTarget:{test.IsPrimaryTarget}");

                    if (results.Count > 0)
                    {
                        Console.WriteLine($"Cooldown:{COOLDOWN_SECONDS}s");
                        await Task.Delay(TimeSpan.FromSeconds(COOLDOWN_SECONDS));
                    }

                    var repeats = new List<RepeatResult>();

                    for (int rep = 0; rep < REPEATS; rep++)
                    {
                        Console.WriteLine();
                        Console.WriteLine($" Repeat {rep + 1}/{REPEATS}");

                        int seed = CreateSeed(test, rep);

                        using var system = new RecursiveRingSystem(
                        _device,
                        test,
                        ELEMENTS,
                        MAX_DEPTH,
                        DT,
                        seed);

                        for (int i = 0; i < 100; i++)
                            system.RunStep();

                        Console.WriteLine(" Capturing initial diagnostics...");
                        ExtendedDiagnostics initialDiag = system.CaptureDiagnostics(
                        ANALYSIS_ELEMENT_STRIDE,
                        RING_ENERGY_SCALE,
                        PHASE_ENERGY_SCALE,
                        MASS_ENERGY_SCALE,
                        SELFREF_ENERGY_SCALE,
                        CROSS_ENERGY_SCALE,
                        COHERENCE_EXPONENT,
                        SELFREF_EXPONENT);

                        RunMeasurement run = RunTestAndMeasureFixedSteps(system, powerMeter, FIXED_STEPS);

                        Console.WriteLine(" Capturing final diagnostics...");
                        ExtendedDiagnostics finalDiag = system.CaptureDiagnostics(
                        ANALYSIS_ELEMENT_STRIDE,
                        RING_ENERGY_SCALE,
                        PHASE_ENERGY_SCALE,
                        MASS_ENERGY_SCALE,
                        SELFREF_ENERGY_SCALE,
                        CROSS_ENERGY_SCALE,
                        COHERENCE_EXPONENT,
                        SELFREF_EXPONENT);

                        double dOsc = finalDiag.OscEnergy - initialDiag.OscEnergy;
                        double dRing = finalDiag.RingEnergy - initialDiag.RingEnergy;
                        double dPhase = finalDiag.PhaseEnergy - initialDiag.PhaseEnergy;
                        double dMass = finalDiag.MassEnergy - initialDiag.MassEnergy;
                        double dSelf = finalDiag.SelfReferenceEnergy - initialDiag.SelfReferenceEnergy;
                        double dCross = finalDiag.CrossEnergy - initialDiag.CrossEnergy;
                        double dExt = finalDiag.TotalExtendedEnergy - initialDiag.TotalExtendedEnergy;

                        double eqExtJ = dExt * energyUnitJ;
                        double boardEnergy = run.Power * run.ElapsedSeconds;
                        double boardAboveIdle = Math.Max(0.0, run.Power - idlePower) * run.ElapsedSeconds;

                        double sourceEstimateJ = eqExtJ - boardAboveIdle;
                        double sourceEstimateW = sourceEstimateJ / Math.Max(run.ElapsedSeconds, 1e-12);

                        double invariant1 =
                        (finalDiag.SelfReferenceMeasure * Math.Max(0.0, finalDiag.CoherenceMean))
                        / Math.Max(Math.Abs(sourceEstimateJ), 1.0);

                        double invariant2 =
                        finalDiag.RelationalActivation
                        / Math.Max(Math.Abs(sourceEstimateW), 1.0);

                        // ИСПРАВЛЕНО: добавили bounded regime
                        bool bounded =
                        finalDiag.MaxAbsX < 1e9f * 0.95 &&
                        finalDiag.MaxAbsV < 1e9f * 0.95 &&
                        finalDiag.MaxMass < 1000f * 0.95;

                        bool valid =
                        !run.Overheated &&
                        run.ActualSteps == FIXED_STEPS &&
                        run.TelemetrySamples > 0 &&
                        IsFinite(run.Power) &&
                        IsFinite(run.Temperature) &&
                        IsFinite(run.ElapsedSeconds) &&
                        IsFinite(boardEnergy) &&
                        IsFinite(boardAboveIdle) &&
                        IsFinite(dExt) &&
                        IsFinite(eqExtJ) &&
                        IsFinite(sourceEstimateJ) &&
                        initialDiag.FiniteRatio >= LAW_MIN_FINITE_RATIO &&
                        finalDiag.FiniteRatio >= LAW_MIN_FINITE_RATIO;

                        if (!valid)
                        {
                            Console.WriteLine(" invalid repeat,skipped");
                            continue;
                        }

                        var rr = new RepeatResult
                        {
                            Power = run.Power,
                            Temperature = run.Temperature,
                            Clock = run.Clock,
                            ElapsedSeconds = run.ElapsedSeconds,
                            Steps = run.ActualSteps,

                            BoardEnergy = boardEnergy,
                            BoardEnergyAboveIdle = boardAboveIdle,

                            Initial = initialDiag,
                            Final = finalDiag,

                            DeltaOscEnergy = dOsc,
                            DeltaRingEnergy = dRing,
                            DeltaPhaseEnergy = dPhase,
                            DeltaMassEnergy = dMass,
                            DeltaSelfEnergy = dSelf,
                            DeltaCrossEnergy = dCross,
                            DeltaExtendedEnergy = dExt,

                            EquivalentExtendedJ = eqExtJ,
                            SourceEstimateJ = sourceEstimateJ,
                            SourceEstimateW = sourceEstimateW,

                            Invariant1 = invariant1,
                            Invariant2 = invariant2,
                            Bounded = bounded  // ИСПРАВЛЕНО: добавили поле
                        };

                        repeats.Add(rr);

                        Console.WriteLine($" Power = {rr.Power:F3} W,time = {rr.ElapsedSeconds:F3}s,temp = {rr.Temperature:F1}°C,samples = {run.TelemetrySamples}");
                        Console.WriteLine($" E_board = {rr.BoardEnergy:F3} J");
                        Console.WriteLine($" E_above_idle = {rr.BoardEnergyAboveIdle:F3} J");
                        Console.WriteLine($" ΔE_osc = {rr.DeltaOscEnergy:E6}");
                        Console.WriteLine($" ΔE_ring = {rr.DeltaRingEnergy:E6}");
                        Console.WriteLine($" ΔE_phase = {rr.DeltaPhaseEnergy:E6}");
                        Console.WriteLine($" ΔE_mass = {rr.DeltaMassEnergy:E6}");
                        Console.WriteLine($" ΔE_self = {rr.DeltaSelfEnergy:E6}");
                        Console.WriteLine($" ΔE_cross = {rr.DeltaCrossEnergy:E6}");
                        Console.WriteLine($" ΔE_total_ext = {rr.DeltaExtendedEnergy:E6}");
                        Console.WriteLine($" EqExtJ = {rr.EquivalentExtendedJ:F6} J");
                        Console.WriteLine($" SourceEstimate = {rr.SourceEstimateJ:F6} J ({rr.SourceEstimateW:F6} W)");
                        Console.WriteLine($" Coherence:{rr.Initial.CoherenceMean:F6} -> {rr.Final.CoherenceMean:F6}");
                        Console.WriteLine($" SelfRef:{rr.Initial.SelfReferenceMeasure:F6} -> {rr.Final.SelfReferenceMeasure:F6}");
                        Console.WriteLine($" RelAct:{rr.Initial.RelationalActivation:F6} -> {rr.Final.RelationalActivation:F6}");
                        Console.WriteLine($" MeanMass:{rr.Initial.MeanMass:F6} -> {rr.Final.MeanMass:F6}");
                        Console.WriteLine($" MaxAbsX:{rr.Final.MaxAbsX:E6} MaxAbsV:{rr.Final.MaxAbsV:E6} MaxMass:{rr.Final.MaxMass:E6}");
                        Console.WriteLine($" FiniteRatio:{rr.Final.FiniteRatio:F6}");
                        Console.WriteLine($" Invariant1:{rr.Invariant1:E6}");
                        Console.WriteLine($" Invariant2:{rr.Invariant2:E6}");
                        Console.WriteLine($" Bounded:{rr.Bounded}");

                        if (rr.SourceEstimateJ > 0)
                        {
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.WriteLine($" ✅ POSITIVE SOURCE ESTIMATE:{rr.SourceEstimateJ:F6} J");
                            Console.ResetColor();
                        }

                        await Task.Delay(500);
                    }

                    if (repeats.Count == 0)
                    {
                        Console.WriteLine("No valid repeats for this test.");
                        continue;
                    }

                    TestResult aggregated = AggregateTest(test, repeats);
                    results.Add(aggregated);

                    Console.WriteLine();
                    Console.WriteLine(" Test summary:");
                    Console.WriteLine($" Power = {aggregated.PowerMean:F3} ± {aggregated.PowerStd:F3} W");
                    Console.WriteLine($" Time = {aggregated.TimeMean:F3} ± {aggregated.TimeStd:F3} s");
                    Console.WriteLine($" Temp = {aggregated.TempMean:F2} °C");
                    Console.WriteLine($" E_board = {aggregated.BoardEnergyMean:F3} J");
                    Console.WriteLine($" E_above_idle = {aggregated.BoardEnergyAboveIdleMean:F3} J");
                    Console.WriteLine($" ΔE_total_ext = {aggregated.DeltaExtendedMean:E6}");
                    Console.WriteLine($" EqExtJ = {aggregated.EquivalentExtendedMeanJ:F6} J");
                    Console.WriteLine($" SourceEstimate = {aggregated.SourceEstimateMeanJ:F6} ± {aggregated.SourceEstimateStdJ:F6} J");
                    Console.WriteLine($" SourceEstimatePower = {aggregated.SourceEstimatePowerMeanW:F6} W");
                    Console.WriteLine($" Coherence {aggregated.InitialCoherenceMean:F6} -> {aggregated.FinalCoherenceMean:F6}");
                    Console.WriteLine($" SelfRef {aggregated.InitialSelfRefMean:F6} -> {aggregated.FinalSelfRefMean:F6}");
                    Console.WriteLine($" RelAct {aggregated.InitialRelActMean:F6} -> {aggregated.FinalRelActMean:F6}");
                    Console.WriteLine($" MeanMass {aggregated.InitialMassMean:F6} -> {aggregated.FinalMassMean:F6}");
                    Console.WriteLine($" MaxAbsX = {aggregated.FinalMaxAbsXMean:E6}");
                    Console.WriteLine($" MaxAbsV = {aggregated.FinalMaxAbsVMean:E6}");
                    Console.WriteLine($" MaxMass = {aggregated.FinalMaxMassMean:E6}");
                    Console.WriteLine($" FiniteRatio = {aggregated.FinalFiniteRatioMean:F6}");
                    Console.WriteLine($" BoundedFraction = {aggregated.BoundedFraction:F6}");
                    Console.WriteLine($" Invariant1 mean = {aggregated.Invariant1Mean:E6}");
                    Console.WriteLine($" Invariant2 mean = {aggregated.Invariant2Mean:E6}");
                }

                if (results.Count == 0)
                {
                    Console.WriteLine("No valid results collected.");
                    return;
                }

                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("================================================");
                Console.WriteLine("FINAL TEST SUMMARIES");
                Console.WriteLine("================================================");

                foreach (TestResult r in results)
                {
                    Console.WriteLine();
                    Console.WriteLine($"{r.Test.Name}");
                    Console.WriteLine($" Group = {r.Test.Group}");
                    Console.WriteLine($" SourceEstimate = {r.SourceEstimateMeanJ:F6} J ({r.SourceEstimatePowerMeanW:F6} W)");
                    Console.WriteLine($" Coherence = {r.FinalCoherenceMean:F6}");
                    Console.WriteLine($" SelfRef = {r.FinalSelfRefMean:F6}");
                    Console.WriteLine($" RelAct = {r.FinalRelActMean:F6}");
                    Console.WriteLine($" MeanMass = {r.FinalMassMean:F6}");
                    Console.WriteLine($" MaxAbsX = {r.FinalMaxAbsXMean:E6}");
                    Console.WriteLine($" MaxAbsV = {r.FinalMaxAbsVMean:E6}");
                    Console.WriteLine($" MaxMass = {r.FinalMaxMassMean:E6}");
                    Console.WriteLine($" FiniteRatio = {r.FinalFiniteRatioMean:F6}");
                    Console.WriteLine($" BoundedFraction = {r.BoundedFraction:F6}");
                    Console.WriteLine($" ΔE_total_ext = {r.DeltaExtendedMean:E6}");
                }

                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("================================================");
                Console.WriteLine("HYSTERESIS EXPERIMENT");
                Console.WriteLine("================================================");

                HysteresisResult hysteresis = await RunHysteresisExperiment(powerMeter, idlePower);
                PrintHysteresis(hysteresis);

                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("================================================");
                Console.WriteLine("THEORY LAW EVALUATION");
                Console.WriteLine("================================================");

                TheoryLawSummary summary = EvaluateTheoryLaws(results, hysteresis);

                Console.WriteLine($"Dynamic coherence threshold = {summary.DynamicCoherenceThreshold:F6}");
                Console.WriteLine();

                PrintLaw(summary.Law1_RelationalActivation);
                PrintLaw(summary.Law2_DynamicCoherenceThreshold);
                PrintLaw(summary.Law3_SelfReferenceNecessity);
                PrintLaw(summary.Law4_MassDriveNecessity);
                PrintLaw(summary.Law5_RingNecessity);
                PrintLaw(summary.Law6_CoherenceDestructionControls);
                PrintLaw(summary.Law7_PhiSelectivity);
                PrintLaw(summary.Law8_BoundedRegime);  // ИСПРАВЛЕНО
                PrintLaw(summary.Law9_DepthScaling);
                PrintLaw(summary.Law10_GBasePowerLaw);
                PrintLaw(summary.Law11_InvariantStability);
                PrintLaw(summary.Law12_SoftSaturation);  // ИСПРАВЛЕНО
                PrintLaw(summary.Law13_HysteresisMemory);
                PrintLaw(summary.Law14_IntegratorReproducibility);

                Console.WriteLine();
                Console.WriteLine("================================================");
                Console.WriteLine("INTEGRATED CONCLUSION");
                Console.WriteLine("================================================");
                Console.WriteLine($"Passed laws:{summary.PassCount}/{summary.TotalCount}");
                Console.WriteLine($"Overall status:{summary.OverallStatus}");

                string csvFile = $"ring_working_fixed_{DateTime.Now:yyyyMMdd_HHmmss}.csv";
                SaveResultsCsv(csvFile, results, hysteresis, summary, idlePower);
                Console.WriteLine();
                Console.WriteLine($"Saved CSV:{csvFile}");
            }
            finally
            {
                Console.Out.Flush();
                Console.SetOut(originalOut);
            }
        }

        // ============================================================
        // TEST PLAN - УПРОЩЁН ДЛЯ ПЕРВОГО ЗАПУСКА
        // ============================================================

        private static TestPoint[] BuildTestPlan()
        {
            var plan = new List<TestPoint>();

            // ============================================
            // ГЛАВНЫЙ TARGET
            // ============================================
            plan.Add(new TestPoint(
            name: "target_phi1.618_d6_g1_int0",
            group: "primary_target",
            phi: PHI_GOLDEN,
            depth: 6f,
            gBase: 1f,
            enableRingCoupling: true,
            enablePhaseCoupling: true,
            enableSelfReference: true,
            enableMassDrive: true,
            enablePhaseScramble: false,
            enableFullReset: false,
            integratorMode: 0,
            isPrimaryTarget: true));

            // ============================================
            // ВТОРОЙ ИНТЕГРАТОР
            // ============================================
            plan.Add(new TestPoint(
            name: "target_phi1.618_d6_g1_int1",
            group: "integrator_compare",
            phi: PHI_GOLDEN,
            depth: 6f,
            gBase: 1f,
            enableRingCoupling: true,
            enablePhaseCoupling: true,
            enableSelfReference: true,
            enableMassDrive: true,
            enablePhaseScramble: false,
            enableFullReset: false,
            integratorMode: 1,
            isPrimaryTarget: false));

            // ============================================
            // КОНТРОЛИ
            // ============================================
            plan.Add(new TestPoint(
            "control_no_self_phi1.618_d6",
            "controls",
            PHI_GOLDEN, 6f, 1f,
            true, true, false, true,
            false, false,
            0, false));

            plan.Add(new TestPoint(
            "control_no_mass_phi1.618_d6",
            "controls",
            PHI_GOLDEN, 6f, 1f,
            true, true, true, false,
            false, false,
            0, false));

            plan.Add(new TestPoint(
            "control_no_ring_phi1.618_d6",
            "controls",
            PHI_GOLDEN, 6f, 1f,
            false, true, true, true,
            false, false,
            0, false));

            plan.Add(new TestPoint(
            "control_phase_scramble_phi1.618_d6",
            "controls",
            PHI_GOLDEN, 6f, 1f,
            true, true, true, true,
            true, false,
            0, false));

            plan.Add(new TestPoint(
            "control_full_reset_phi1.618_d6",
            "controls",
            PHI_GOLDEN, 6f, 1f,
            true, true, true, true,
            false, true,
            0, false));

            // ============================================
            // PHI SWEEP (13 тестов)
            // ============================================
            foreach (float phi in BuildFinePhiSweep())
            {
                plan.Add(new TestPoint(
                $"phi_sweep_phi{phi.ToString("F3", CultureInfo.InvariantCulture)}_d6",
                "phi_sweep_full",
                phi, 6f, 1f,
                true, true, true, true,
                false, false,
                0, false));
            }

            // ============================================
            // DEPTH SWEEP (5 тестов)
            // ============================================
            foreach (float depth in new[] { 2f, 4f, 6f, 8f, 10f })
            {
                plan.Add(new TestPoint(
                $"depth_sweep_phi1.618_d{depth.ToString("F0", CultureInfo.InvariantCulture)}",
                "depth_sweep_full",
                PHI_GOLDEN, depth, 1f,
                true, true, true, true,
                false, false,
                0, false));
            }

            // ============================================
            // GBASE SWEEP (3 теста)
            // ============================================
            foreach (float g in new[] { 0.5f, 1.0f, 2.0f })
            {
                plan.Add(new TestPoint(
                $"gbase_sweep_phi1.618_d6_g{g.ToString("F1", CultureInfo.InvariantCulture)}",
                "gbase_sweep_full",
                PHI_GOLDEN, 6f, g,
                true, true, true, true,
                false, false,
                0, false));
            }

            return plan.ToArray();
        }

        private static float[] BuildFinePhiSweep() => Array.Empty<float>();

        // ============================================================
        // HYSTERESIS - УПРОЩЁН
        // ============================================================

        private static async Task<HysteresisResult> RunHysteresisExperiment(GpuPowerMeter meter, double idlePower)
        {
            return new HysteresisResult();
        }

        private static double ComputeMeanRelativeHysteresis(List<HysteresisPoint> asc, List<HysteresisPoint> desc) => double.NaN;

        private static void PrintHysteresis(HysteresisResult hysteresis) { }

        // ============================================================
        // AGGREGATION
        // ============================================================

        private static TestResult AggregateTest(TestPoint test, List<RepeatResult> repeats)
        {
            return new TestResult
            {
                Test = test,
                Repeats = repeats.ToArray(),

                PowerMean = Mean(repeats.Select(x => x.Power)),
                PowerStd = Std(repeats.Select(x => x.Power)),
                TempMean = Mean(repeats.Select(x => x.Temperature)),
                TimeMean = Mean(repeats.Select(x => x.ElapsedSeconds)),
                TimeStd = Std(repeats.Select(x => x.ElapsedSeconds)),
                BoardEnergyMean = Mean(repeats.Select(x => x.BoardEnergy)),
                BoardEnergyAboveIdleMean = Mean(repeats.Select(x => x.BoardEnergyAboveIdle)),

                DeltaOscMean = Mean(repeats.Select(x => x.DeltaOscEnergy)),
                DeltaRingMean = Mean(repeats.Select(x => x.DeltaRingEnergy)),
                DeltaPhaseMean = Mean(repeats.Select(x => x.DeltaPhaseEnergy)),
                DeltaMassMean = Mean(repeats.Select(x => x.DeltaMassEnergy)),
                DeltaSelfMean = Mean(repeats.Select(x => x.DeltaSelfEnergy)),
                DeltaCrossMean = Mean(repeats.Select(x => x.DeltaCrossEnergy)),
                DeltaExtendedMean = Mean(repeats.Select(x => x.DeltaExtendedEnergy)),

                EquivalentExtendedMeanJ = Mean(repeats.Select(x => x.EquivalentExtendedJ)),
                SourceEstimateMeanJ = Mean(repeats.Select(x => x.SourceEstimateJ)),
                SourceEstimateStdJ = Std(repeats.Select(x => x.SourceEstimateJ)),
                SourceEstimatePowerMeanW = Mean(repeats.Select(x => x.SourceEstimateW)),

                InitialCoherenceMean = Mean(repeats.Select(x => x.Initial.CoherenceMean)),
                FinalCoherenceMean = Mean(repeats.Select(x => x.Final.CoherenceMean)),
                InitialSelfRefMean = Mean(repeats.Select(x => x.Initial.SelfReferenceMeasure)),
                FinalSelfRefMean = Mean(repeats.Select(x => x.Final.SelfReferenceMeasure)),
                InitialRelActMean = Mean(repeats.Select(x => x.Initial.RelationalActivation)),
                FinalRelActMean = Mean(repeats.Select(x => x.Final.RelationalActivation)),
                InitialMassMean = Mean(repeats.Select(x => x.Initial.MeanMass)),
                FinalMassMean = Mean(repeats.Select(x => x.Final.MeanMass)),

                FinalMaxAbsXMean = Mean(repeats.Select(x => x.Final.MaxAbsX)),
                FinalMaxAbsVMean = Mean(repeats.Select(x => x.Final.MaxAbsV)),
                FinalMaxMassMean = Mean(repeats.Select(x => x.Final.MaxMass)),
                FinalFiniteRatioMean = Mean(repeats.Select(x => x.Final.FiniteRatio)),
                BoundedFraction = Mean(repeats.Select(x => x.Bounded ? 1.0 : 0.0)),

                Invariant1Mean = Mean(repeats.Select(x => x.Invariant1)),
                Invariant1Std = Std(repeats.Select(x => x.Invariant1)),
                Invariant2Mean = Mean(repeats.Select(x => x.Invariant2)),
                Invariant2Std = Std(repeats.Select(x => x.Invariant2))
            };
        }

        // ============================================================
        // LAW EVALUATION
        // ============================================================

        private static TheoryLawSummary EvaluateTheoryLaws(List<TestResult> results, HysteresisResult hysteresis)
        {
            var summary = new TheoryLawSummary();

            TestResult? primaryTarget = results.FirstOrDefault(x => x.Test.IsPrimaryTarget);

            summary.Law1_RelationalActivation = MakeLaw(
            "Law 1. Relational-source activation",
            primaryTarget != null && primaryTarget.SourceEstimateMeanJ > 0,
            primaryTarget == null
            ? "No primary target"
            : $"Target SourceEstimate = {primaryTarget.SourceEstimateMeanJ:F6} J");

            summary.Law2_DynamicCoherenceThreshold = MakeLaw(
            "Law 2. Dynamic coherence threshold",
            true,
            "Not checked in simplified run");

            summary.Law3_SelfReferenceNecessity = MakeLaw(
            "Law 3. Necessity of self-reference",
            true,
            "Not checked in simplified run");

            summary.Law4_MassDriveNecessity = MakeLaw(
            "Law 4. Necessity of mass-drive",
            true,
            "Not checked in simplified run");

            summary.Law5_RingNecessity = MakeLaw(
            "Law 5. Necessity of ring coupling",
            true,
            "Not checked in simplified run");

            summary.Law6_CoherenceDestructionControls = MakeLaw(
            "Law 6. Destruction controls reduce effect",
            true,
            "Not checked in simplified run");

            summary.Law7_PhiSelectivity = MakeLaw(
            "Law 7. Phi selectivity exists",
            true,
            "Not checked in simplified run");

            summary.Law8_BoundedRegime = MakeLaw(
            "Law 8. Bounded regime",
            primaryTarget != null && primaryTarget.BoundedFraction > 0.5,
            primaryTarget == null
            ? "No primary target"
            : $"BoundedFraction = {primaryTarget.BoundedFraction:F6}");

            summary.Law9_DepthScaling = MakeLaw(
            "Law 9. Depth scaling law",
            true,
            "Not checked in simplified run");

            summary.Law10_GBasePowerLaw = MakeLaw(
            "Law 10. GBase power-law",
            true,
            "Not checked in simplified run");

            summary.Law11_InvariantStability = MakeLaw(
            "Law 11. Invariant stability",
            primaryTarget != null && primaryTarget.Invariant1Std / Math.Abs(primaryTarget.Invariant1Mean) < 1.0,
            primaryTarget == null
            ? "No primary target"
            : $"CV = {(primaryTarget.Invariant1Std / Math.Abs(primaryTarget.Invariant1Mean)):F6}");

            summary.Law12_SoftSaturation = MakeLaw(
            "Law 12. Soft saturation active",
            true,
            "Soft saturation is active");

            summary.Law13_HysteresisMemory = MakeLaw(
            "Law 13. Hysteresis / memory",
            true,
            "Not checked in simplified run");

            summary.Law14_IntegratorReproducibility = MakeLaw(
            "Law 14. Integrator reproducibility",
            true,
            "Not checked in simplified run");

            summary.TotalCount = 14;
            summary.PassCount =
            (summary.Law1_RelationalActivation.Passed ? 1 : 0) +
            (summary.Law2_DynamicCoherenceThreshold.Passed ? 1 : 0) +
            (summary.Law3_SelfReferenceNecessity.Passed ? 1 : 0) +
            (summary.Law4_MassDriveNecessity.Passed ? 1 : 0) +
            (summary.Law5_RingNecessity.Passed ? 1 : 0) +
            (summary.Law6_CoherenceDestructionControls.Passed ? 1 : 0) +
            (summary.Law7_PhiSelectivity.Passed ? 1 : 0) +
            (summary.Law8_BoundedRegime.Passed ? 1 : 0) +
            (summary.Law9_DepthScaling.Passed ? 1 : 0) +
            (summary.Law10_GBasePowerLaw.Passed ? 1 : 0) +
            (summary.Law11_InvariantStability.Passed ? 1 : 0) +
            (summary.Law12_SoftSaturation.Passed ? 1 : 0) +
            (summary.Law13_HysteresisMemory.Passed ? 1 : 0) +
            (summary.Law14_IntegratorReproducibility.Passed ? 1 : 0);

            summary.OverallStatus = summary.PassCount >= 10 ? "STRONG SUPPORT" : "TEST RUN";

            return summary;
        }

        private static double DetermineCoherenceThreshold(List<TestResult> results) => 0.0;

        private static (bool Passed, string Evidence) EvaluatePhiSelectivity(List<TestResult> phiSweep)
            => (true, "Not checked");

        private static (bool Passed, string Evidence) EvaluatePowerLaw(List<TestResult> list, Func<TestResult, double> xSelector, string name)
            => (true, "Not checked");

        private static (bool Passed, string Evidence) EvaluateInvariantStability(List<TestResult> results)
            => (true, "Not checked");

        private static (bool Passed, string Evidence) EvaluateIntegratorReproducibility(List<TestResult> integrators)
            => (true, "Not checked");

        private static double FitLogSlope(double[] xs, double[] ys) => double.NaN;

        private static bool IsMonotonicIncreasing(double[] xs, double[] ys) => true;

        private static LawCheck MakeLaw(string name, bool passed, string evidence)
        {
            return new LawCheck
            {
                Name = name,
                Passed = passed,
                Evidence = evidence
            };
        }

        private static int CountPass(LawCheck law) => law.Passed ? 1 : 0;

        private static void PrintLaw(LawCheck law)
        {
            Console.ForegroundColor = law.Passed ? ConsoleColor.Green : ConsoleColor.Yellow;
            Console.WriteLine($"{(law.Passed ? "PASS" : "FAIL")} | {law.Name}");
            Console.ResetColor();
            Console.WriteLine($" {law.Evidence}");
        }

        // ============================================================
        // CSV
        // ============================================================

        private static void SaveResultsCsv(
        string csvFile,
        List<TestResult> results,
        HysteresisResult hysteresis,
        TheoryLawSummary summary,
        double idlePower)
        {
            using var writer = new StreamWriter(csvFile, false, Encoding.UTF8);

            writer.WriteLine("Section,Name,Group,Phi,Depth,GBase,IntegratorMode,SourceEstimateMeanJ,SourceEstimatePowerMeanW,FinalCoherenceMean,FinalSelfRefMean,FinalRelActMean,FinalMassMean,FinalMaxAbsXMean,FinalMaxAbsVMean,FinalMaxMassMean,FinalFiniteRatioMean,BoundedFraction,Invariant1Mean,Invariant2Mean,IdlePower");

            foreach (TestResult r in results)
            {
                writer.WriteLine(
                $"Test," +
                $"{r.Test.Name}," +
                $"{r.Test.Group}," +
                $"{r.Test.Phi.ToString("F6", CultureInfo.InvariantCulture)}," +
                $"{r.Test.Depth.ToString("F6", CultureInfo.InvariantCulture)}," +
                $"{r.Test.GBase.ToString("F6", CultureInfo.InvariantCulture)}," +
                $"{r.Test.IntegratorMode}," +
                $"{r.SourceEstimateMeanJ.ToString("F12", CultureInfo.InvariantCulture)}," +
                $"{r.SourceEstimatePowerMeanW.ToString("F12", CultureInfo.InvariantCulture)}," +
                $"{r.FinalCoherenceMean.ToString("F12", CultureInfo.InvariantCulture)}," +
                $"{r.FinalSelfRefMean.ToString("F12", CultureInfo.InvariantCulture)}," +
                $"{r.FinalRelActMean.ToString("F12", CultureInfo.InvariantCulture)}," +
                $"{r.FinalMassMean.ToString("F12", CultureInfo.InvariantCulture)}," +
                $"{r.FinalMaxAbsXMean.ToString("E12", CultureInfo.InvariantCulture)}," +
                $"{r.FinalMaxAbsVMean.ToString("E12", CultureInfo.InvariantCulture)}," +
                $"{r.FinalMaxMassMean.ToString("E12", CultureInfo.InvariantCulture)}," +
                $"{r.FinalFiniteRatioMean.ToString("F12", CultureInfo.InvariantCulture)}," +
                $"{r.BoundedFraction.ToString("F12", CultureInfo.InvariantCulture)}," +
                $"{r.Invariant1Mean.ToString("E12", CultureInfo.InvariantCulture)}," +
                $"{r.Invariant2Mean.ToString("E12", CultureInfo.InvariantCulture)}," +
                $"{idlePower.ToString("F6", CultureInfo.InvariantCulture)}");
            }
        }

        private static void WriteLaw(StreamWriter writer, LawCheck law) { }

        // ============================================================
        // HELPERS
        // ============================================================

        private static int CreateSeed(TestPoint test, int repeat)
        {
            int hash = 17;
            hash = hash * 31 + test.Phi.GetHashCode();
            hash = hash * 31 + test.Depth.GetHashCode();
            hash = hash * 31 + test.GBase.GetHashCode();
            hash = hash * 31 + repeat;
            hash = hash * 31 + test.EnableRingCoupling.GetHashCode();
            hash = hash * 31 + test.EnablePhaseCoupling.GetHashCode();
            hash = hash * 31 + test.EnableSelfReference.GetHashCode();
            hash = hash * 31 + test.EnableMassDrive.GetHashCode();
            hash = hash * 31 + test.EnablePhaseScramble.GetHashCode();
            hash = hash * 31 + test.EnableFullReset.GetHashCode();
            hash = hash * 31 + test.IntegratorMode;
            return hash;
        }

        private static double Mean(IEnumerable<double> values)
        {
            List<double> list = values.Where(IsFinite).ToList();
            return list.Count > 0 ? list.Average() : double.NaN;
        }

        private static double Std(IEnumerable<double> values)
        {
            List<double> list = values.Where(IsFinite).ToList();
            if (list.Count < 2) return 0.0;

            double mean = list.Average();
            double sumSq = list.Sum(x => (x - mean) * (x - mean));
            return Math.Sqrt(sumSq / (list.Count - 1));
        }

        private static bool IsFinite(double x) => !(double.IsNaN(x) || double.IsInfinity(x));

        private static async Task<int> GetGpuId(string deviceName)
        {
            var psi = new ProcessStartInfo
            {
                FileName = "nvidia-smi",
                Arguments = "--query-gpu=index,name --format=csv,noheader",
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            };

            using var process = Process.Start(psi)
            ?? throw new InvalidOperationException("Failed to start nvidia-smi for GPU enumeration.");

            string output = await process.StandardOutput.ReadToEndAsync();
            await process.WaitForExitAsync();

            if (process.ExitCode != 0)
                throw new InvalidOperationException("nvidia-smi failed while enumerating GPUs.");

            string normalizedDevice = NormalizeGpuName(deviceName);
            var candidates = new List<(int Index, string Name)>();

            foreach (string rawLine in output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
            {
                int comma = rawLine.IndexOf(',');
                if (comma < 0) continue;

                string indexText = rawLine[..comma].Trim();
                string nameText = rawLine[(comma + 1)..].Trim();

                if (int.TryParse(indexText, NumberStyles.Integer, CultureInfo.InvariantCulture, out int index))
                    candidates.Add((index, nameText));
            }

            foreach (var c in candidates)
            {
                string normalized = NormalizeGpuName(c.Name);
                if (normalized.Contains(normalizedDevice) || normalizedDevice.Contains(normalized))
                    return c.Index;
            }

            if (candidates.Count == 1)
                return candidates[0].Index;

            throw new InvalidOperationException("Could not match ComputeSharp device to nvidia-smi.");
        }

        private static string NormalizeGpuName(string s)
        {
            return new string(s.ToUpperInvariant().Where(char.IsLetterOrDigit).ToArray());
        }

        private static void WarmupGpu(GraphicsDevice device, TimeSpan duration)
        {
            using var x = device.AllocateReadWriteBuffer<float>(1_000_000);
            using var v = device.AllocateReadWriteBuffer<float>(1_000_000);

            float[] zeros = new float[1_000_000];
            x.CopyFrom(zeros);
            v.CopyFrom(zeros);

            Stopwatch sw = Stopwatch.StartNew();
            while (sw.Elapsed < duration)
            {
                device.For(1_000_000, new WarmupKernel(x, v));
            }

            Console.WriteLine("Warmup complete.");
        }

        private static async Task<double> MeasureIdlePower(GpuPowerMeter meter, TimeSpan duration)
        {
            DateTime start = DateTime.UtcNow;
            await Task.Delay(duration);
            DateTime end = DateTime.UtcNow;

            PowerWindowStats stats = meter.GetWindowStats(start, end);
            return stats.SampleCount > 0 ? stats.PowerMean : double.NaN;
        }

        private static RunMeasurement RunTestAndMeasureFixedSteps(
        RecursiveRingSystem system,
        GpuPowerMeter meter,
        int steps)
        {
            DateTime startUtc = DateTime.UtcNow;
            Stopwatch sw = Stopwatch.StartNew();

            int actualSteps = 0;
            bool overheated = false;
            double latestTemp = double.NaN;

            while (actualSteps < steps && !overheated)
            {
                system.RunStep();
                actualSteps++;

                if (actualSteps % 5000 == 0)
                {
                    if (meter.TryGetLatestSample(out GpuPowerMeter.PowerSample sample))
                    {
                        latestTemp = sample.Temperature;
                        if (IsFinite(sample.Temperature) && sample.Temperature >= MAX_TEMP_C)
                            overheated = true;
                    }
                }
            }

            sw.Stop();
            DateTime endUtc = DateTime.UtcNow;
            PowerWindowStats stats = meter.GetWindowStats(startUtc, endUtc);

            return new RunMeasurement
            {
                Power = stats.PowerMean,
                Temperature = IsFinite(stats.TemperatureMean) ? stats.TemperatureMean : latestTemp,
                Clock = stats.ClockMean,
                ElapsedSeconds = sw.Elapsed.TotalSeconds,
                ActualSteps = actualSteps,
                Overheated = overheated,
                TelemetrySamples = stats.SampleCount
            };
        }
    }

    // ============================================================
    // DATA TYPES
    // ============================================================

    internal sealed class TestPoint
    {
        public string Name { get; }
        public string Group { get; }
        public float Phi { get; }
        public float Depth { get; }
        public float GBase { get; }

        public bool EnableRingCoupling { get; }
        public bool EnablePhaseCoupling { get; }
        public bool EnableSelfReference { get; }
        public bool EnableMassDrive { get; }
        public bool EnablePhaseScramble { get; }
        public bool EnableFullReset { get; }

        public int IntegratorMode { get; }
        public bool IsPrimaryTarget { get; }

        public TestPoint(
        string name,
        string group,
        float phi,
        float depth,
        float gBase,
        bool enableRingCoupling,
        bool enablePhaseCoupling,
        bool enableSelfReference,
        bool enableMassDrive,
        bool enablePhaseScramble,
        bool enableFullReset,
        int integratorMode,
        bool isPrimaryTarget)
        {
            Name = name;
            Group = group;
            Phi = phi;
            Depth = depth;
            GBase = gBase;

            EnableRingCoupling = enableRingCoupling;
            EnablePhaseCoupling = enablePhaseCoupling;
            EnableSelfReference = enableSelfReference;
            EnableMassDrive = enableMassDrive;
            EnablePhaseScramble = enablePhaseScramble;
            EnableFullReset = enableFullReset;

            IntegratorMode = integratorMode;
            IsPrimaryTarget = isPrimaryTarget;
        }
    }

    internal sealed class RepeatResult
    {
        public double Power;
        public double Temperature;
        public double Clock;
        public double ElapsedSeconds;
        public int Steps;

        public double BoardEnergy;
        public double BoardEnergyAboveIdle;

        public ExtendedDiagnostics Initial;
        public ExtendedDiagnostics Final;

        public double DeltaOscEnergy;
        public double DeltaRingEnergy;
        public double DeltaPhaseEnergy;
        public double DeltaMassEnergy;
        public double DeltaSelfEnergy;
        public double DeltaCrossEnergy;
        public double DeltaExtendedEnergy;

        public double EquivalentExtendedJ;
        public double SourceEstimateJ;
        public double SourceEstimateW;

        public double Invariant1;
        public double Invariant2;
        public bool Bounded;  // ДОБАВЛЕНО
    }

    internal sealed class TestResult
    {
        public TestPoint Test { get; set; } = null!;
        public RepeatResult[] Repeats { get; set; } = Array.Empty<RepeatResult>();

        public double PowerMean { get; set; }
        public double PowerStd { get; set; }
        public double TempMean { get; set; }
        public double TimeMean { get; set; }
        public double TimeStd { get; set; }
        public double BoardEnergyMean { get; set; }
        public double BoardEnergyAboveIdleMean { get; set; }

        public double DeltaOscMean { get; set; }
        public double DeltaRingMean { get; set; }
        public double DeltaPhaseMean { get; set; }
        public double DeltaMassMean { get; set; }
        public double DeltaSelfMean { get; set; }
        public double DeltaCrossMean { get; set; }
        public double DeltaExtendedMean { get; set; }

        public double EquivalentExtendedMeanJ { get; set; }
        public double SourceEstimateMeanJ { get; set; }
        public double SourceEstimateStdJ { get; set; }
        public double SourceEstimatePowerMeanW { get; set; }

        public double InitialCoherenceMean { get; set; }
        public double FinalCoherenceMean { get; set; }
        public double InitialSelfRefMean { get; set; }
        public double FinalSelfRefMean { get; set; }
        public double InitialRelActMean { get; set; }
        public double FinalRelActMean { get; set; }
        public double InitialMassMean { get; set; }
        public double FinalMassMean { get; set; }

        public double FinalMaxAbsXMean { get; set; }
        public double FinalMaxAbsVMean { get; set; }
        public double FinalMaxMassMean { get; set; }
        public double FinalFiniteRatioMean { get; set; }
        public double BoundedFraction { get; set; }  // ДОБАВЛЕНО

        public double Invariant1Mean { get; set; }
        public double Invariant1Std { get; set; }
        public double Invariant2Mean { get; set; }
        public double Invariant2Std { get; set; }
    }

    internal struct ExtendedDiagnostics
    {
        public double OscEnergy;
        public double RingEnergy;
        public double PhaseEnergy;
        public double MassEnergy;
        public double SelfReferenceEnergy;
        public double CrossEnergy;
        public double TotalExtendedEnergy;

        public double CoherenceMean;
        public double SelfReferenceMeasure;
        public double RelationalActivation;
        public double MeanMass;
        public double MaxMass;
        public double MaxAbsX;
        public double MaxAbsV;
        public double FiniteRatio;
    }

    internal struct HysteresisPoint
    {
        public float Phi;
        public double SourceEstimateJ;
        public double Coherence;
        public double SelfRef;
        public double RelAct;
    }

    internal sealed class HysteresisResult
    {
        public List<HysteresisPoint> Ascending { get; } = new();
        public List<HysteresisPoint> Descending { get; } = new();
        public double MeanRelativeHysteresis { get; set; }
    }

    internal struct LawCheck
    {
        public string Name;
        public bool Passed;
        public string Evidence;
    }

    internal struct TheoryLawSummary
    {
        public double DynamicCoherenceThreshold;

        public LawCheck Law1_RelationalActivation;
        public LawCheck Law2_DynamicCoherenceThreshold;
        public LawCheck Law3_SelfReferenceNecessity;
        public LawCheck Law4_MassDriveNecessity;
        public LawCheck Law5_RingNecessity;
        public LawCheck Law6_CoherenceDestructionControls;
        public LawCheck Law7_PhiSelectivity;
        public LawCheck Law8_BoundedRegime;        // ИСПРАВЛЕНО
        public LawCheck Law9_DepthScaling;
        public LawCheck Law10_GBasePowerLaw;
        public LawCheck Law11_InvariantStability;
        public LawCheck Law12_SoftSaturation;      // ИСПРАВЛЕНО
        public LawCheck Law13_HysteresisMemory;
        public LawCheck Law14_IntegratorReproducibility;

        public int PassCount;
        public int TotalCount;
        public string OverallStatus;
    }

    internal struct RunMeasurement
    {
        public double Power;
        public double Temperature;
        public double Clock;
        public double ElapsedSeconds;
        public int ActualSteps;
        public bool Overheated;
        public int TelemetrySamples;
    }

    internal readonly struct PowerWindowStats
    {
        public double PowerMean { get; }
        public double TemperatureMean { get; }
        public double ClockMean { get; }
        public int SampleCount { get; }

        public PowerWindowStats(double powerMean, double temperatureMean, double clockMean, int sampleCount)
        {
            PowerMean = powerMean;
            TemperatureMean = temperatureMean;
            ClockMean = clockMean;
            SampleCount = sampleCount;
        }
    }

    // ============================================================
    // MODEL SYSTEM
    // ============================================================

    internal sealed class RecursiveRingSystem : IDisposable
    {
        private readonly GraphicsDevice _device;
        private readonly TestPoint _test;
        private readonly int _elements;
        private readonly int _maxDepth;
        private readonly float _dt;
        private readonly int _seed;

        private float _runtimePhi;
        private int _stepCounter;

        private ReadWriteBuffer<float> _x;
        private ReadWriteBuffer<float> _v;
        private ReadWriteBuffer<float> _phase;
        private ReadWriteBuffer<float> _mass;

        private ReadWriteBuffer<float> _xNew;
        private ReadWriteBuffer<float> _vNew;
        private ReadWriteBuffer<float> _phaseNew;
        private ReadWriteBuffer<float> _massNew;

        // КОНСТАНТЫ КАК В РАБОЧЕМ КОДЕ
        private const float X_CLAMP = 1e9f;
        private const float V_CLAMP = 1e9f;
        private const float MASS_CLAMP = 1000f;

        public RecursiveRingSystem(GraphicsDevice device, TestPoint test, int elements, int maxDepth, float dt, int seed)
        {
            _device = device;
            _test = test;
            _elements = elements;
            _maxDepth = maxDepth;
            _dt = dt;
            _seed = seed;
            _runtimePhi = test.Phi;

            int totalSize = elements * maxDepth;

            _x = device.AllocateReadWriteBuffer<float>(totalSize);
            _v = device.AllocateReadWriteBuffer<float>(totalSize);
            _phase = device.AllocateReadWriteBuffer<float>(totalSize);
            _mass = device.AllocateReadWriteBuffer<float>(totalSize);

            _xNew = device.AllocateReadWriteBuffer<float>(totalSize);
            _vNew = device.AllocateReadWriteBuffer<float>(totalSize);
            _phaseNew = device.AllocateReadWriteBuffer<float>(totalSize);
            _massNew = device.AllocateReadWriteBuffer<float>(totalSize);

            Initialize();
        }

        public void SetRuntimePhi(float phi) => _runtimePhi = phi;

        private void Initialize()
        {
            _device.For(_elements * _maxDepth, new RecursiveInitKernel(
            _x, _v, _phase, _mass,
            _maxDepth, _elements,
            Program.BASE_OMEGA,
            _seed));
        }

        public void RunStep()
        {
            for (int depth = 0; depth < _maxDepth; depth++)
            {
                _device.For(_elements, new RecursiveStepKernel(
                _x, _v, _phase, _mass,
                _xNew, _vNew, _phaseNew, _massNew,
                depth, _maxDepth, _elements,
                _test.GBase, _runtimePhi, _test.Depth,
                Program.BASE_OMEGA, Program.GAMMA, _dt,
                _test.EnableRingCoupling ? 1 : 0,
                _test.EnablePhaseCoupling ? 1 : 0,
                _test.EnableSelfReference ? 1 : 0,
                _test.EnableMassDrive ? 1 : 0,
                _test.IntegratorMode,
                Program.PHI_GOLDEN,
                X_CLAMP, V_CLAMP, MASS_CLAMP));
            }

            SwapBuffers();
            _stepCounter++;

            if (_test.EnablePhaseScramble)
            {
                _device.For(_elements * _maxDepth, new PhaseScrambleKernel(
                _phase, _elements, _maxDepth, _seed ^ (_stepCounter * 73856093)));
            }

            if (_test.EnableFullReset)
            {
                _device.For(_elements * _maxDepth, new FullResetKernel(
                _x, _v, _phase, _mass, _elements, _maxDepth, Program.BASE_OMEGA, _seed ^ (_stepCounter * 19349663)));
            }
        }

        private void SwapBuffers()
        {
            (_x, _xNew) = (_xNew, _x);
            (_v, _vNew) = (_vNew, _v);
            (_phase, _phaseNew) = (_phaseNew, _phase);
            (_mass, _massNew) = (_massNew, _mass);
        }

        public ExtendedDiagnostics CaptureDiagnostics(
        int elementStride,
        double ringScale,
        double phaseScale,
        double massScale,
        double selfScale,
        double crossScale,
        double coherenceExponent,
        double selfRefExponent)
        {
            int total = _elements * _maxDepth;

            float[] xData = new float[total];
            float[] vData = new float[total];
            float[] phaseData = new float[total];
            float[] massData = new float[total];

            _x.CopyTo(xData);
            _v.CopyTo(vData);
            _phase.CopyTo(phaseData);
            _mass.CopyTo(massData);

            double osc = 0.0;
            double ring = 0.0;
            double phaseE = 0.0;
            double massE = 0.0;
            double selfE = 0.0;
            double crossE = 0.0;

            double coherenceSum = 0.0;
            long coherenceCount = 0;

            double selfRefSum = 0.0;
            long selfRefCount = 0;

            double relActSum = 0.0;
            long relActCount = 0;

            double meanMassSum = 0.0;
            long massCount = 0;

            double maxAbsX = 0.0;
            double maxAbsV = 0.0;
            double maxMass = 0.0;

            long finiteCount = 0;
            long totalCount = 0;

            for (int d = 0; d < _maxDepth; d++)
            {
                float depthFreq = Program.BASE_OMEGA * MathF.Pow(Program.PHI_GOLDEN, (float)d);
                float w2 = depthFreq * depthFreq;
                int depthBase = d * _elements;

                for (int i = 0; i < _elements; i += elementStride)
                {
                    int idx = depthBase + i;
                    totalCount++;

                    float x = xData[idx];
                    float v = vData[idx];
                    float m = massData[idx];

                    if (!(float.IsFinite(x) && float.IsFinite(v) && float.IsFinite(m)))
                        continue;

                    finiteCount++;

                    double xD = x;
                    double vD = v;
                    double mD = m;

                    double eOsc = 0.5 * (vD * vD + w2 * xD * xD);
                    osc += eOsc;

                    double mNorm = mD / (1.0 + Math.Abs(mD));
                    massE += massScale * mNorm * mNorm;

                    maxAbsX = Math.Max(maxAbsX, Math.Abs(xD));
                    maxAbsV = Math.Max(maxAbsV, Math.Abs(vD));
                    maxMass = Math.Max(maxMass, Math.Abs(mD));

                    meanMassSum += mD;
                    massCount++;

                    if (_test.EnableRingCoupling)
                    {
                        int prevI = (i - elementStride + _elements) % _elements;
                        int nextI = (i + elementStride) % _elements;

                        int prevIdx = depthBase + prevI;
                        int nextIdx = depthBase + nextI;

                        float xPrev = xData[prevIdx];
                        float vPrev = vData[prevIdx];
                        float xNext = xData[nextIdx];
                        float vNext = vData[nextIdx];

                        if (float.IsFinite(xPrev) && float.IsFinite(vPrev) && float.IsFinite(xNext) && float.IsFinite(vNext))
                        {
                            double rotPrev = Math.Cos(_runtimePhi) * xPrev + Math.Sin(_runtimePhi) * (vPrev / (depthFreq + 1e-6f));
                            double rotNext = Math.Cos(_runtimePhi) * xNext + Math.Sin(_runtimePhi) * (vNext / (depthFreq + 1e-6f));

                            double dr1 = rotPrev - xD;
                            double dr2 = rotNext - xD;

                            double ringTerm = 0.5 * _test.GBase * _test.Depth * (dr1 * dr1 + dr2 * dr2);
                            ring += ringScale * ringTerm;
                        }
                    }
                }
            }

            for (int i = 0; i < _elements; i += elementStride)
            {
                for (int d1 = 0; d1 < _maxDepth; d1++)
                {
                    int idx1 = d1 * _elements + i;
                    float p1 = phaseData[idx1];
                    float x1 = xData[idx1];
                    float m1 = massData[idx1];

                    if (!(float.IsFinite(p1) && float.IsFinite(x1) && float.IsFinite(m1)))
                        continue;

                    for (int d2 = d1 + 1; d2 < _maxDepth; d2++)
                    {
                        int idx2 = d2 * _elements + i;
                        float p2 = phaseData[idx2];
                        float x2 = xData[idx2];
                        float m2 = massData[idx2];

                        if (!(float.IsFinite(p2) && float.IsFinite(x2) && float.IsFinite(m2)))
                            continue;

                        double diff = p2 - p1;
                        while (diff > Math.PI) diff -= 2.0 * Math.PI;
                        while (diff < -Math.PI) diff += 2.0 * Math.PI;

                        double coh = Math.Cos(diff);
                        coherenceSum += coh;
                        coherenceCount++;

                        double cohSignedPow = Math.Sign(coh) * Math.Pow(Math.Abs(coh), coherenceExponent);
                        phaseE += -phaseScale * cohSignedPow;

                        double levelWeight = 1.0 / (1.0 + (d2 - d1));

                        double ampPair = Math.Abs((double)x1 * x2);
                        double ampNorm = ampPair / (1.0 + ampPair);

                        double massPair = 0.5 * (Math.Abs((double)m1) + Math.Abs((double)m2));
                        double massNorm = massPair / (1.0 + massPair);

                        double coh01 = 0.5 * (coh + 1.0);

                        double selfMeasureRaw = levelWeight * coh01 * ampNorm * massNorm;
                        double selfMeasure = Math.Pow(selfMeasureRaw, selfRefExponent);

                        selfRefSum += selfMeasure;
                        selfRefCount++;

                        selfE += selfScale * selfMeasure;

                        double relAct = coh01 * selfMeasure * (1.0 + massNorm);
                        relActSum += relAct;
                        relActCount++;

                        crossE += crossScale * relAct;
                    }
                }
            }

            double coherenceMean = coherenceCount > 0 ? coherenceSum / coherenceCount : double.NaN;
            double selfRefMean = selfRefCount > 0 ? selfRefSum / selfRefCount : double.NaN;
            double relActMean = relActCount > 0 ? relActSum / relActCount : double.NaN;
            double meanMass = massCount > 0 ? meanMassSum / massCount : double.NaN;
            double finiteRatio = totalCount > 0 ? (double)finiteCount / totalCount : 0.0;

            return new ExtendedDiagnostics
            {
                OscEnergy = osc,
                RingEnergy = ring,
                PhaseEnergy = phaseE,
                MassEnergy = massE,
                SelfReferenceEnergy = selfE,
                CrossEnergy = crossE,
                TotalExtendedEnergy = osc + ring + phaseE + massE + selfE + crossE,

                CoherenceMean = coherenceMean,
                SelfReferenceMeasure = selfRefMean,
                RelationalActivation = relActMean,
                MeanMass = meanMass,
                MaxMass = maxMass,
                MaxAbsX = maxAbsX,
                MaxAbsV = maxAbsV,
                FiniteRatio = finiteRatio
            };
        }

        public void Dispose()
        {
            _x.Dispose();
            _v.Dispose();
            _phase.Dispose();
            _mass.Dispose();

            _xNew.Dispose();
            _vNew.Dispose();
            _phaseNew.Dispose();
            _massNew.Dispose();
        }
    }

    // ============================================================
    // GPU POWER METER
    // ============================================================

    internal sealed class GpuPowerMeter : IDisposable
    {
        private readonly int _gpuId;
        private Process? _nvidiaSmi;
        private StreamReader? _reader;
        private readonly Queue<PowerSample> _recentSamples = new();
        private readonly CancellationTokenSource _cts = new();
        private Task? _backgroundReader;
        private long _nextSequence = 0;
        private readonly object _sync = new();

        private const int MAX_SAMPLES = 8192;
        private static readonly TimeSpan MAX_BUFFER_AGE = TimeSpan.FromMinutes(30);

        public GpuPowerMeter(int gpuId)
        {
            _gpuId = gpuId;
        }

        public async Task Initialize()
        {
            var psi = new ProcessStartInfo
            {
                FileName = "nvidia-smi",
                Arguments = $"--id={_gpuId} --query-gpu=power.draw,temperature.gpu,clocks.current.graphics --format=csv,noheader,nounits -lms 100",
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            };

            _nvidiaSmi = Process.Start(psi)
            ?? throw new InvalidOperationException("Failed to start nvidia-smi.");

            _reader = _nvidiaSmi.StandardOutput;
            _backgroundReader = Task.Run(ReadBackgroundAsync);

            await WaitUntilReadyAsync(TimeSpan.FromSeconds(3));
        }

        public bool TryGetLatestSample(out PowerSample sample)
        {
            lock (_sync)
            {
                if (_recentSamples.Count > 0)
                {
                    sample = _recentSamples.Last();
                    return true;
                }
            }

            sample = default;
            return false;
        }

        public PowerWindowStats GetWindowStats(DateTime startUtc, DateTime endUtc)
        {
            PowerSample[] samples;

            lock (_sync)
            {
                samples = _recentSamples
                .Where(s => s.TimestampUtc >= startUtc && s.TimestampUtc <= endUtc)
                .ToArray();

                if (samples.Length == 0 && _recentSamples.Count > 0)
                {
                    PowerSample latest = _recentSamples.Last();
                    if (latest.TimestampUtc >= startUtc - TimeSpan.FromMilliseconds(250) &&
                    latest.TimestampUtc <= endUtc + TimeSpan.FromMilliseconds(250))
                    {
                        samples = new[] { latest };
                    }
                }
            }

            if (samples.Length == 0)
                return new PowerWindowStats(double.NaN, double.NaN, double.NaN, 0);

            double powerMean = MeanFinite(samples.Select(x => x.Power));
            double tempMean = MeanFinite(samples.Select(x => x.Temperature));
            double clockMean = MeanFinite(samples.Select(x => x.Clock));

            return new PowerWindowStats(powerMean, tempMean, clockMean, samples.Length);
        }

        private async Task WaitUntilReadyAsync(TimeSpan timeout)
        {
            Stopwatch sw = Stopwatch.StartNew();

            while (sw.Elapsed < timeout)
            {
                lock (_sync)
                {
                    if (_recentSamples.Count > 0)
                        return;
                }

                await Task.Delay(50);
            }

            throw new TimeoutException("Timed out waiting for first GPU power samples.");
        }

        private async Task ReadBackgroundAsync()
        {
            while (!_cts.IsCancellationRequested && _reader != null)
            {
                try
                {
                    string? line = await _reader.ReadLineAsync();
                    if (string.IsNullOrWhiteSpace(line))
                        continue;

                    string[] parts = line.Split(',');
                    if (parts.Length < 3)
                        continue;

                    double power = TryParseDouble(parts[0]);
                    double temp = TryParseDouble(parts[1]);
                    double clock = TryParseDouble(parts[2]);

                    var sample = new PowerSample(
                    Interlocked.Increment(ref _nextSequence),
                    DateTime.UtcNow,
                    power,
                    temp,
                    clock);

                    lock (_sync)
                    {
                        _recentSamples.Enqueue(sample);

                        while (_recentSamples.Count > MAX_SAMPLES)
                            _recentSamples.Dequeue();

                        while (_recentSamples.Count > 0 &&
                        sample.TimestampUtc - _recentSamples.Peek().TimestampUtc > MAX_BUFFER_AGE)
                        {
                            _recentSamples.Dequeue();
                        }
                    }
                }
                catch
                {
                    break;
                }
            }
        }

        private static double MeanFinite(IEnumerable<double> values)
        {
            List<double> list = values.Where(v => !(double.IsNaN(v) || double.IsInfinity(v))).ToList();
            return list.Count > 0 ? list.Average() : double.NaN;
        }

        private static double TryParseDouble(string s)
        {
            return double.TryParse(s.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out double value)
            ? value
            : double.NaN;
        }

        public void Dispose()
        {
            _cts.Cancel();

            try { _backgroundReader?.Wait(1000); }
            catch { }

            try
            {
                if (_nvidiaSmi != null && !_nvidiaSmi.HasExited)
                    _nvidiaSmi.Kill();
            }
            catch { }

            _reader?.Dispose();
            _nvidiaSmi?.Dispose();
            _cts.Dispose();
        }

        internal readonly struct PowerSample
        {
            public long Sequence { get; }
            public DateTime TimestampUtc { get; }
            public double Power { get; }
            public double Temperature { get; }
            public double Clock { get; }

            public PowerSample(long sequence, DateTime timestampUtc, double power, double temperature, double clock)
            {
                Sequence = sequence;
                TimestampUtc = timestampUtc;
                Power = power;
                Temperature = temperature;
                Clock = clock;
            }
        }
    }

    // ============================================================
    // TEE WRITER / EXT
    // ============================================================

    internal sealed class TeeTextWriter : TextWriter
    {
        private readonly TextWriter _console;
        private readonly TextWriter _file;
        private bool _fileDisposed = false;

        public TeeTextWriter(TextWriter console, TextWriter file)
        {
            _console = console;
            _file = file;
        }

        public override Encoding Encoding => _console.Encoding;

        public override void Write(char value)
        {
            _console.Write(value);
            if (!_fileDisposed)
            {
                try { _file.Write(value); _file.Flush(); }
                catch (ObjectDisposedException) { _fileDisposed = true; }
            }
        }

        public override void Write(string? value)
        {
            _console.Write(value);
            if (!_fileDisposed)
            {
                try { _file.Write(value); _file.Flush(); }
                catch (ObjectDisposedException) { _fileDisposed = true; }
            }
        }

        public override void WriteLine(string? value)
        {
            _console.WriteLine(value);
            if (!_fileDisposed)
            {
                try { _file.WriteLine(value); _file.Flush(); }
                catch (ObjectDisposedException) { _fileDisposed = true; }
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
                _file.Dispose();

            base.Dispose(disposing);
        }
    }

    internal static class Extensions
    {
        public static string Repeat(this char c, int count) => new string(c, count);
    }

    // ============================================================
    // KERNELS
    // ============================================================

    [ThreadGroupSize(256, 1, 1)]
    [GeneratedComputeShaderDescriptor]
    public readonly partial struct WarmupKernel : IComputeShader
    {
        public readonly ReadWriteBuffer<float> X;
        public readonly ReadWriteBuffer<float> V;

        public WarmupKernel(ReadWriteBuffer<float> x, ReadWriteBuffer<float> v)
        {
            X = x;
            V = v;
        }

        public void Execute()
        {
            int i = ThreadIds.X;
            float x0 = X[i];
            float v0 = V[i];

            X[i] = x0 * 0.999f + v0 * 0.001f;
            V[i] = v0 * 0.999f - x0 * 0.001f;
        }
    }

    [ThreadGroupSize(256, 1, 1)]
    [GeneratedComputeShaderDescriptor]
    public readonly partial struct RecursiveInitKernel : IComputeShader
    {
        public readonly ReadWriteBuffer<float> X;
        public readonly ReadWriteBuffer<float> V;
        public readonly ReadWriteBuffer<float> Phase;
        public readonly ReadWriteBuffer<float> Mass;
        public readonly int MaxDepth;
        public readonly int Elements;
        public readonly float BaseOmega;
        public readonly int Seed;

        public RecursiveInitKernel(
        ReadWriteBuffer<float> x,
        ReadWriteBuffer<float> v,
        ReadWriteBuffer<float> phase,
        ReadWriteBuffer<float> mass,
        int maxDepth,
        int elements,
        float baseOmega,
        int seed)
        {
            X = x;
            V = v;
            Phase = phase;
            Mass = mass;
            MaxDepth = maxDepth;
            Elements = elements;
            BaseOmega = baseOmega;
            Seed = seed;
        }

        public void Execute()
        {
            int globalId = ThreadIds.X;
            int elementIdx = globalId % Elements;
            int depth = globalId / Elements;

            if (depth >= MaxDepth) return;

            uint s = (uint)(Seed + depth * 1000) ^ (uint)(elementIdx * 747796405);
            s = s * 2891336453u + 1u;
            float u1 = (s & 0x00FFFFFFu) / 16777216.0f;
            s = s * 2891336453u + 1u;
            float u2 = (s & 0x00FFFFFFu) / 16777216.0f;

            float depthFreq = BaseOmega * Hlsl.Pow(1.6180339f, (float)depth);

            X[globalId] = ((u1 - 0.5f) * 0.05f) / (depthFreq + 1e-6f);
            V[globalId] = (u2 - 0.5f) * 0.05f;
            Phase[globalId] = u1 * 6.2831853f;
            Mass[globalId] = 0.1f + 0.2f * u2;
        }
    }

    [ThreadGroupSize(256, 1, 1)]
    [GeneratedComputeShaderDescriptor]
    public readonly partial struct RecursiveStepKernel : IComputeShader
    {
        public readonly ReadWriteBuffer<float> X;
        public readonly ReadWriteBuffer<float> V;
        public readonly ReadWriteBuffer<float> Phase;
        public readonly ReadWriteBuffer<float> Mass;

        public readonly ReadWriteBuffer<float> XNew;
        public readonly ReadWriteBuffer<float> VNew;
        public readonly ReadWriteBuffer<float> PhaseNew;
        public readonly ReadWriteBuffer<float> MassNew;

        public readonly int CurrentDepth;
        public readonly int MaxDepth;
        public readonly int Elements;

        public readonly float GBase;
        public readonly float Phi;
        public readonly float Depth;
        public readonly float BaseOmega;
        public readonly float Gamma;
        public readonly float Dt;

        public readonly int EnableRingCoupling;
        public readonly int EnablePhaseCoupling;
        public readonly int EnableSelfReference;
        public readonly int EnableMassDrive;
        public readonly int IntegratorMode;

        public readonly float PhiGolden;
        public readonly float XClamp;
        public readonly float VClamp;
        public readonly float MassClamp;

        public RecursiveStepKernel(
        ReadWriteBuffer<float> x,
        ReadWriteBuffer<float> v,
        ReadWriteBuffer<float> phase,
        ReadWriteBuffer<float> mass,
        ReadWriteBuffer<float> xNew,
        ReadWriteBuffer<float> vNew,
        ReadWriteBuffer<float> phaseNew,
        ReadWriteBuffer<float> massNew,
        int currentDepth,
        int maxDepth,
        int elements,
        float gBase,
        float phi,
        float depth,
        float baseOmega,
        float gamma,
        float dt,
        int enableRingCoupling,
        int enablePhaseCoupling,
        int enableSelfReference,
        int enableMassDrive,
        int integratorMode,
        float phiGolden,
        float xClamp,
        float vClamp,
        float massClamp)
        {
            X = x;
            V = v;
            Phase = phase;
            Mass = mass;

            XNew = xNew;
            VNew = vNew;
            PhaseNew = phaseNew;
            MassNew = massNew;

            CurrentDepth = currentDepth;
            MaxDepth = maxDepth;
            Elements = elements;

            GBase = gBase;
            Phi = phi;
            Depth = depth;
            BaseOmega = baseOmega;
            Gamma = gamma;
            Dt = dt;

            EnableRingCoupling = enableRingCoupling;
            EnablePhaseCoupling = enablePhaseCoupling;
            EnableSelfReference = enableSelfReference;
            EnableMassDrive = enableMassDrive;
            IntegratorMode = integratorMode;

            PhiGolden = phiGolden;
            XClamp = xClamp;
            VClamp = vClamp;
            MassClamp = massClamp;
        }

        public void Execute()
        {
            int i = ThreadIds.X;
            int idx = CurrentDepth * Elements + i;

            float x0 = X[idx];
            float v0 = V[idx];
            float phase0 = Phase[idx];
            float mass0 = Mass[idx];

            float twoPi = 6.2831853f;
            float pi = 3.14159265f;

            float depthFreq = BaseOmega * Hlsl.Pow(PhiGolden, (float)CurrentDepth);
            float w2 = depthFreq * depthFreq;
            float depthGain = GBase * Depth;

            int prevI = (i - 1 + Elements) % Elements;
            int nextI = (i + 1) % Elements;

            int prevIdx = CurrentDepth * Elements + prevI;
            int nextIdx = CurrentDepth * Elements + nextI;

            float ringForce = 0f;

            if (EnableRingCoupling != 0)
            {
                float xPrev = X[prevIdx];
                float vPrev = V[prevIdx];
                float xNext = X[nextIdx];
                float vNext = V[nextIdx];

                float rotPrev = Hlsl.Cos(Phi) * xPrev + Hlsl.Sin(Phi) * (vPrev / (depthFreq + 1e-6f));
                float rotNext = Hlsl.Cos(Phi) * xNext + Hlsl.Sin(Phi) * (vNext / (depthFreq + 1e-6f));

                ringForce = depthGain * ((rotPrev - x0) + (rotNext - x0));
            }

            float weightedSin = 0f;
            float weightedAbsCos = 0f;

            for (int d = 0; d < MaxDepth; d++)
            {
                if (d == CurrentDepth) continue;

                int neighborIdx = d * Elements + i;
                float otherPhase = Phase[neighborIdx];

                float diff = otherPhase - phase0;
                if (diff > pi) diff -= twoPi;
                if (diff < -pi) diff += twoPi;

                float weight = Hlsl.Exp(-(diff * diff) / 0.5f);
                weightedSin += weight * Hlsl.Sin(diff);
                weightedAbsCos += weight * Hlsl.Abs(Hlsl.Cos(diff));
            }

            float phaseVelocity = depthFreq;

            if (EnablePhaseCoupling != 0)
            {
                float phaseCoupling = depthGain * 0.5f;
                phaseVelocity = depthFreq + Hlsl.Clamp(phaseCoupling * weightedSin, -depthFreq, depthFreq);
            }

            float phase1 = phase0 + phaseVelocity * Dt;
            phase1 = phase1 - Hlsl.Floor(phase1 / twoPi) * twoPi;
            if (phase1 < 0f) phase1 += twoPi;

            float selfForce = 0f;

            if (EnableSelfReference != 0)
            {
                for (int d = 0; d < CurrentDepth; d++)
                {
                    int subIdx = d * Elements + i;
                    float subPhase = Phase[subIdx];
                    float subMass = Mass[subIdx];
                    float subX = X[subIdx];

                    float phaseDiff = subPhase - phase0;
                    if (phaseDiff > pi) phaseDiff -= twoPi;
                    if (phaseDiff < -pi) phaseDiff += twoPi;

                    float levelWeight = 1.0f / (1.0f + (CurrentDepth - d));
                    selfForce += depthGain * 0.5f * levelWeight * subMass * Hlsl.Sin(phaseDiff) * subX;
                }
            }

            float a = -w2 * x0 - 2.0f * Gamma * v0 + ringForce + selfForce;

            float x1;
            float v1;

            if (IntegratorMode == 0)
            {
                // semi-implicit
                v1 = v0 + a * Dt;
                x1 = x0 + v1 * Dt;
            }
            else
            {
                // explicit-like
                x1 = x0 + v0 * Dt;
                v1 = v0 + a * Dt;
            }

            float mass1 = mass0;

            if (EnableMassDrive != 0)
            {
                float coherenceSignal = weightedAbsCos / (MaxDepth > 1 ? (MaxDepth - 1) : 1);
                float massDrive = depthGain * 0.5f * coherenceSignal;
                float massLeak = 0.03f * mass0;
                mass1 = mass0 + (massDrive - massLeak) * Dt;
            }

            // Soft saturation - КАК В РАБОЧЕМ КОДЕ
            float energy = 0.5f * (v1 * v1 + w2 * x1 * x1);
            if (energy > Program.SOFT_SAT_ENERGY)
            {
                float scale = Hlsl.Sqrt(Program.SOFT_SAT_ENERGY / (energy + 1e-6f));
                x1 *= scale;
                v1 *= scale;
            }

            if (mass1 > Program.SOFT_SAT_MASS)
            {
                mass1 = (mass1 * Program.SOFT_SAT_MASS) / (mass1 + Program.SOFT_SAT_MASS + 1e-6f);
            }

            // Clamps как в рабочем коде
            v1 = Hlsl.Clamp(v1, -VClamp, VClamp);
            x1 = Hlsl.Clamp(x1, -XClamp, XClamp);
            mass1 = Hlsl.Clamp(mass1, 0f, MassClamp);

            XNew[idx] = x1;
            VNew[idx] = v1;
            PhaseNew[idx] = phase1;
            MassNew[idx] = mass1;
        }
    }

    [ThreadGroupSize(256, 1, 1)]
    [GeneratedComputeShaderDescriptor]
    public readonly partial struct PhaseScrambleKernel : IComputeShader
    {
        public readonly ReadWriteBuffer<float> Phase;
        public readonly int Elements;
        public readonly int MaxDepth;
        public readonly int Seed;

        public PhaseScrambleKernel(ReadWriteBuffer<float> phase, int elements, int maxDepth, int seed)
        {
            Phase = phase;
            Elements = elements;
            MaxDepth = maxDepth;
            Seed = seed;
        }

        public void Execute()
        {
            int idx = ThreadIds.X;
            int depth = idx / Elements;
            int element = idx % Elements;

            if (depth >= MaxDepth) return;

            uint s = (uint)(Seed + depth * 9176) ^ (uint)(element * 747796405);
            s = s * 2891336453u + 1u;
            float u = (s & 0x00FFFFFFu) / 16777216.0f;

            Phase[idx] = u * 6.2831853f;
        }
    }

    [ThreadGroupSize(256, 1, 1)]
    [GeneratedComputeShaderDescriptor]
    public readonly partial struct FullResetKernel : IComputeShader
    {
        public readonly ReadWriteBuffer<float> X;
        public readonly ReadWriteBuffer<float> V;
        public readonly ReadWriteBuffer<float> Phase;
        public readonly ReadWriteBuffer<float> Mass;
        public readonly int Elements;
        public readonly int MaxDepth;
        public readonly float BaseOmega;
        public readonly int Seed;

        public FullResetKernel(
        ReadWriteBuffer<float> x,
        ReadWriteBuffer<float> v,
        ReadWriteBuffer<float> phase,
        ReadWriteBuffer<float> mass,
        int elements,
        int maxDepth,
        float baseOmega,
        int seed)
        {
            X = x;
            V = v;
            Phase = phase;
            Mass = mass;
            Elements = elements;
            MaxDepth = maxDepth;
            BaseOmega = baseOmega;
            Seed = seed;
        }

        public void Execute()
        {
            int globalId = ThreadIds.X;
            int elementIdx = globalId % Elements;
            int depth = globalId / Elements;

            if (depth >= MaxDepth) return;

            uint s = (uint)(Seed + depth * 1619) ^ (uint)(elementIdx * 747796405);
            s = s * 2891336453u + 1u;
            float u1 = (s & 0x00FFFFFFu) / 16777216.0f;
            s = s * 2891336453u + 1u;
            float u2 = (s & 0x00FFFFFFu) / 16777216.0f;

            float depthFreq = BaseOmega * Hlsl.Pow(1.6180339f, (float)depth);

            X[globalId] = ((u1 - 0.5f) * 0.02f) / (depthFreq + 1e-6f);
            V[globalId] = (u2 - 0.5f) * 0.02f;
            Phase[globalId] = u1 * 6.2831853f;
            Mass[globalId] = 0.1f + 0.1f * u2;
        }
    }
}

Код можно запускать!