<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
    <title>Notes &amp; Insights - software-engineering</title>
    <subtitle>Блог об архитектуре систем, AI-агентах, распределенных системах и алгоритмическом трейдинге.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://xsa-dev.github.io/tags/software-engineering/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://xsa-dev.github.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-10-09T00:00:00+00:00</updated>
    <id>https://xsa-dev.github.io/tags/software-engineering/atom.xml</id>
    <entry xml:lang="ru">
        <title>Бюджет и риск-гейты для DCA-позиций: расчёт до запуска бота</title>
        <published>2026-10-09T00:00:00+00:00</published>
        <updated>2026-10-09T00:00:00+00:00</updated>
        
        <author>
          <name>Alexei Savin</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://xsa-dev.github.io/posts/dca-martingale-capital-budget-risk-gates/"/>
        <id>https://xsa-dev.github.io/posts/dca-martingale-capital-budget-risk-gates/</id>
        
        <content type="html" xml:base="https://xsa-dev.github.io/posts/dca-martingale-capital-budget-risk-gates/">&lt;p&gt;Усреднение снижает цену безубыточности, но одновременно увеличивает сумму под риском. &lt;strong&gt;Высокий риск · образовательный разбор.&lt;/strong&gt; Это не инвестиционная рекомендация и не инструкция к запуску торгового бота. Если в отчёте DCA-бота показан только процент прибыльных сделок, главный вопрос остаётся без ответа: &lt;strong&gt;сколько капитала потребует серия покупок, если отскока не будет?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Повод для разбора — видео &lt;a rel=&quot;external&quot; href=&quot;https://youtu.be/M1036x1Hobg&quot;&gt;DCA Martingale Trading Bot Explained&lt;/a&gt;. Рыночный бэктест в рамках этой статьи не проводился.&lt;/p&gt;
&lt;h2 id=&quot;dca-ne-obiazatel-no-martingeil&quot;&gt;DCA — не обязательно мартингейл&lt;/h2&gt;
&lt;p&gt;В этой статье DCA означает дополнительные покупки при снижении цены внутри одной сделки. Это не регулярное долгосрочное инвестирование фиксированной суммы.&lt;/p&gt;
&lt;p&gt;Различать стоит три независимых правила:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Триггер:&lt;/strong&gt; на каком снижении разрешена дополнительная покупка.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Размер:&lt;/strong&gt; сколько денег выделяется каждой покупке.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Остановка:&lt;/strong&gt; когда новые покупки запрещаются и что происходит с уже открытой позицией.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Постоянный размер покупки не является классическим мартингейлом. Геометрическое увеличение размера похоже на него по нагрузке на капитал, но само по себе не гарантирует компенсацию прошлых потерь. Термин «контролируемый» здесь не используется как оценка качества: он имеет смысл только вместе с явными лимитами.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Почему мартингейл опасен.&lt;/strong&gt; Увеличение каждой следующей покупки наращивает экспозицию именно тогда, когда цена движется против позиции. При удвоении номиналов серия 100 → 200 → 400 → 800 требует уже 1500 единиц капитала, а следующая покупка — ещё 1600; это без комиссий. Конечный бюджет не позволяет продолжать такую последовательность бесконечно, а восстановление цены не гарантировано. На споте без заёмных средств можно потерять почти всю стоимость позиции; с плечом ликвидация может наступить ещё до запланированного уровня усреднения. Лимит покупок ограничивает выделяемый капитал, но не делает стратегию прибыльной и не гарантирует выход по заданной цене при разрыве котировок или недостаточной ликвидности. Приведённые ниже расчёты служат для анализа этих ограничений, а не являются торговой идеей, призывом запускать бота или инвестиционной рекомендацией.&lt;/p&gt;
&lt;h2 id=&quot;snachala-biudzhet-zatem-signal&quot;&gt;Сначала бюджет, затем сигнал&lt;/h2&gt;
&lt;p&gt;Пусть B — сумма базовой покупки в валюте котировки, S — сумма первой дополнительной покупки, m — множитель следующих покупок, N — максимальное число дополнительных покупок. Плеча нет; все суммы — номиналы покупок без комиссий.&lt;/p&gt;
&lt;p&gt;$$
C = B + S\sum_{k=0}^{N-1}m^k
$$&lt;/p&gt;
&lt;p&gt;При m ≠ 1:&lt;/p&gt;
&lt;p&gt;$$
C = B + S\frac{m^N-1}{m-1}
$$&lt;/p&gt;
&lt;p&gt;При m = 1 бюджет равен B + NS. Нулевая величина N означает отсутствие дополнительных покупок.&lt;/p&gt;
&lt;p&gt;Например, B = 100, S = 100, m = 2 и N = 4 требуют &lt;strong&gt;1600 единиц капитала&lt;/strong&gt;, хотя стартовая покупка составляет только 100. Для пяти одновременно заполненных серий потребуется 8000 — до комиссий и запаса ликвидности. Это арифметический сценарий, не прогноз рынка.&lt;/p&gt;
&lt;p&gt;Если предполагается реинвестирование прибыли, план нужно пересчитывать при каждом изменении базового размера. Иначе однажды проверенный лимит перестанет соответствовать реальной экспозиции.&lt;/p&gt;
&lt;h3 id=&quot;tri-nezavisimykh-limita&quot;&gt;Три независимых лимита&lt;/h3&gt;
&lt;p&gt;Бюджет серии &lt;code&gt;C&lt;/code&gt; — только номинал покупок. Для рабочего риск-гейта нужны ещё два ограничения:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Лимит серии:&lt;/strong&gt; &lt;code&gt;C &amp;lt;= C_series&lt;/code&gt;, где &lt;code&gt;C_series&lt;/code&gt; включает все дополнительные покупки, разрешённые одной позиции.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Лимит портфеля:&lt;/strong&gt; &lt;code&gt;R_reserved = Σ C_j &amp;lt;= R_portfolio&lt;/code&gt; для всех серий &lt;code&gt;j&lt;/code&gt;, которые могут быть заполнены одновременно.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Лимит ликвидности:&lt;/strong&gt; каждая заявка должна удовлетворять минимальному размеру, шагу количества и доступной глубине; остаток &lt;code&gt;R_portfolio - R_reserved&lt;/code&gt; не следует считать свободным для другой стратегии без общего резервного реестра.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Если вероятность одновременного заполнения неизвестна, для консервативного гейта используют сумму полных бюджетов, а не среднее историческое заполнение. &lt;code&gt;R_reserved&lt;/code&gt; включает quote cash, зарезервированные под незаполненную часть активных заявок; фактически исполненный notional учитывается отдельно. При частичном исполнении резерв уменьшают только после отмены остатка и подтверждённого terminal status (&lt;code&gt;canceled&lt;/code&gt;/&lt;code&gt;closed&lt;/code&gt;), а не сразу после получения частичного fill. Таймаут или перезапуск процесса не являются основанием считать резерв свободным.&lt;/p&gt;
&lt;p&gt;Важно: &lt;code&gt;C&lt;/code&gt; — бюджет покупок в quote currency без комиссий, а не максимальный убыток. Фактический убыток зависит от цены выхода, комиссий, проскальзывания, гэпа и ликвидности; для деривативов добавляется риск ликвидации. Даже полностью зарезервированный бюджет не задаёт нижнюю границу потерь.&lt;/p&gt;
&lt;p&gt;Для оценки чувствительности удобно считать прирост очередного ордера отдельно: &lt;code&gt;ΔC_k = S m^k&lt;/code&gt;. При &lt;code&gt;m &amp;gt; 1&lt;/code&gt; последний разрешённый ордер доминирует в бюджете; поэтому изменение &lt;code&gt;N&lt;/code&gt; на единицу часто опаснее, чем небольшая поправка расстояния между уровнями. Этот расчёт не содержит предположений о вероятности отскока.&lt;/p&gt;
&lt;h2 id=&quot;pochemu-sredniaia-tsena-ne-srednee-tsen-orderov&quot;&gt;Почему средняя цена — не среднее цен ордеров&lt;/h2&gt;
&lt;p&gt;При расходах c и ценах исполнения p количество купленного актива равно расходам, делённым на цену. Поэтому средняя цена взвешивается количествами, а не числом заявок:&lt;/p&gt;
&lt;p&gt;$$
Q = \sum_{i=0}^{N}\frac{c_i}{p_i},\qquad
\bar{p}=\frac{\sum_{i=0}^{N}c_i}{Q}
$$&lt;/p&gt;
&lt;p&gt;Рассмотрим только три исполненные покупки, не весь максимальный план:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Покупка&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Расход&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Цена&lt;/th&gt;&lt;th style=&quot;text-align: right&quot;&gt;Количество&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Базовая&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Дополнительная 1&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;90&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;1,111111&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Дополнительная 2&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;200&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;80&lt;/td&gt;&lt;td style=&quot;text-align: right&quot;&gt;2,5&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Всего потрачено 400, куплено примерно 4,611111 единицы, средняя цена — &lt;strong&gt;86,746988&lt;/strong&gt;. Чтобы вернуться от 80 к этой цене, нужен рост примерно на 8,43%. Без комиссий это цена безубыточности, а не целевая прибыль.&lt;/p&gt;
&lt;p&gt;Если комиссия каждой покупки уплачена дополнительно в валюте котировки с долей f, а при продаже удерживается такая же доля выручки, цена безубыточности будет:&lt;/p&gt;
&lt;p&gt;$$
p_{BE}=\bar{p}\frac{1+f}{1-f}
$$&lt;/p&gt;
&lt;p&gt;При f = 0,001 получаем около 86,920656. Если комиссия удерживается в базовом активе или отдельном токене, формула учёта меняется. Проскальзывание учитывается фактическими ценами исполнения, а не обещанными уровнями сетки.&lt;/p&gt;
&lt;p&gt;При падении до 60 стоимость позиции составит около 276,67, а нереализованный убыток — 123,33 без комиссий. Средняя цена действительно снизилась; абсолютный риск при этом вырос.&lt;/p&gt;
&lt;h2 id=&quot;proveriaemyi-kal-kuliator-na-python&quot;&gt;Проверяемый калькулятор на Python&lt;/h2&gt;
&lt;p&gt;Код ниже не отправляет заявки и не является стратегией Freqtrade. Он проверяет арифметику плана и трёх гипотетических исполнений. Нужен только Python 3 со стандартной библиотекой.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;from&lt;/span&gt;&lt;span&gt; decimal&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; import&lt;/span&gt;&lt;span&gt; Decimal&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; as&lt;/span&gt;&lt;span&gt; D&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;base&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; first&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; multiplier&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; count&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; type&lt;/span&gt;&lt;span&gt;(count)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; is not&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; int&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; or not&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span&gt; count&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;count must be an integer from 0 to 100&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    values&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; tuple&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt;str&lt;/span&gt;&lt;span&gt;(x))&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; (base&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; first&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; multiplier))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; any&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;not&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_finite&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; or&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; values)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;sizes and multiplier must be finite and positive&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    base&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; first&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; multiplier&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; values&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; base&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; sum&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (first&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; *&lt;/span&gt;&lt;span&gt; multiplier&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; **&lt;/span&gt;&lt;span&gt; k&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; k&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; range&lt;/span&gt;&lt;span&gt;(count))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1600&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;500&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;for&lt;/span&gt;&lt;span&gt; bad&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 1.5&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; True&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 101&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;        capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; bad)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    except&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        pass&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    else&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; AssertionError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;invalid count accepted&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; breakeven_price&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;average&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; fee&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    average&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; fee&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt;str&lt;/span&gt;&lt;span&gt;(average))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt;str&lt;/span&gt;&lt;span&gt;(fee))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; not&lt;/span&gt;&lt;span&gt; average&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_finite&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; or&lt;/span&gt;&lt;span&gt; average&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;average must be finite and positive&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; not&lt;/span&gt;&lt;span&gt; fee&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_finite&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; or not&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span&gt; fee&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        raise&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; ValueError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;fee must be finite and in [0, 1)&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; average&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; *&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +&lt;/span&gt;&lt;span&gt; fee)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; /&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span&gt; fee)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; breakeven_price&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;100&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;100&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; breakeven_price&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;86.7469879518&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0.001&amp;quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;86.7469879518&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fills&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; [(&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;90&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;200&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;80&lt;/span&gt;&lt;span&gt;))]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cost&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; sum&lt;/span&gt;&lt;span&gt;((cash&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; cash&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; fills)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;quantity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; sum&lt;/span&gt;&lt;span&gt;((cash&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; /&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; for&lt;/span&gt;&lt;span&gt; cash&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; price&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; in&lt;/span&gt;&lt;span&gt; fills)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;average&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; cost&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; /&lt;/span&gt;&lt;span&gt; quantity&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fee&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0.001&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;breakeven&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; breakeven_price&lt;/span&gt;&lt;span&gt;(average&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; fee)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; abs&lt;/span&gt;&lt;span&gt;(average&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;86.7469879518&amp;quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0.000000001&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;assert&lt;/span&gt;&lt;span style=&quot;color: #F07178;&quot;&gt; abs&lt;/span&gt;&lt;span&gt;(breakeven&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;86.9206555953&amp;quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;0.000000001&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F07178;&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;capital=&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;capital_plan&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F07178;&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;average=&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;{&lt;/span&gt;&lt;span&gt;average&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;:.6f&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;; breakeven=&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;{&lt;/span&gt;&lt;span&gt;breakeven&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;:.6f&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Этот тест не проверяет исторические котировки, ликвидность или доходность. Он нужен для более узкого инварианта: риск-менеджер и стратегия должны одинаково понимать размер запланированной серии.&lt;/p&gt;
&lt;h2 id=&quot;kontur-ispolneniia-limit-do-dopolnitel-noi-pokupki&quot;&gt;Контур исполнения: лимит — до дополнительной покупки&lt;/h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;flowchart&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    A&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Новый закрытый бар&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;] --&amp;gt;&lt;/span&gt;&lt;span&gt; B&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Сверка позиций и заявок&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    B &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; C&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Есть неопределённое исполнение?&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    C &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Да&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; D&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Пауза и повторная сверка&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    C &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Нет&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; E&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Проверка уровня и номера покупки&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    E &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; F&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Хватает лимита серии и портфеля?&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    F &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Нет&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; G&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Запрет увеличения позиции&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    F &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Да&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; H&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Резервирование бюджета и заявка&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    H &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; I&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Запись фактического исполнения&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Здесь нужны два лимита: на отдельную серию и на весь портфель. Остаток свободных денег сам по себе не заменяет резерв: несколько ботов могут одновременно считать одни и те же средства доступными.&lt;/p&gt;
&lt;p&gt;Минимальная запись состояния содержит идентификатор серии, номер дополнительной покупки, уже исполненный объём, зарезервированную сумму и идентификатор заявки. После таймаута сначала выясняют судьбу заявки, а не немедленно отправляют новую. Частичное исполнение учитывают по фактическому объёму; перезапуск процесса не должен обнулять счётчик покупок.&lt;/p&gt;
&lt;p&gt;В Freqtrade увеличение позиции реализуется через &lt;code&gt;adjust_trade_position()&lt;/code&gt;. Это callback именно для position adjustment; его частота вызовов и поведение в live/dry-run отличаются от бэктеста. Условие вроде «цена ниже уровня» остаётся истинным несколько итераций подряд: без проверки состояния оно способно породить повторные покупки. Возвращаемые значения (stake/amount), ограничения биржи и конфигурационные лимиты зависят от установленной версии Freqtrade, поэтому implementation contract нужно сверять с документацией конкретной версии, а не только со stable-ссылкой. Точные параметры callback и ограничения числа дополнительных входов проверяйте по документации установленной версии.&lt;/p&gt;
&lt;p&gt;Отказ от дальнейшего усреднения &lt;strong&gt;не закрывает существующий риск&lt;/strong&gt;. Отдельная политика должна описывать выход, максимальную длительность сделки и аварийное отключение. Стоп-заявка тоже не гарантирует цену исполнения при гэпе. Здесь рассматривается спот без плеча; для деривативов дополнительно необходимы модель маржи, funding и риск ликвидации.&lt;/p&gt;
&lt;h2 id=&quot;kak-proveriat-strategiiu-a-ne-krasivuiu-krivuiu&quot;&gt;Как проверять стратегию, а не красивую кривую&lt;/h2&gt;
&lt;p&gt;До перебора параметров задайте протокол:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Разделите время.&lt;/strong&gt; Подбор параметров — на тренировочном периоде; выбор варианта — на валидационном; финальная проверка — на отдельном, ранее не использованном периоде. Повторный подбор по финальному отчёту превращает его в тренировочный.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Сравните одинаковый капитал.&lt;/strong&gt; Покупка на 100 с резервом 1500 и buy-and-hold на 1600 — разные режимы экспозиции. Покажите доходность на весь выделенный капитал, а не только на первую покупку.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Проверьте открытые позиции.&lt;/strong&gt; Высокая доля выигрышных закрытых сделок может соседствовать с большой плавающей просадкой. Нужна equity с переоценкой открытых позиций, а не только баланс завершённых циклов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Учтите издержки.&lt;/strong&gt; Комиссии, спред, ограничения минимального ордера и шаг количества; отдельно — стрессовое проскальзывание и пропущенные исполнения.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Испытайте одновременное падение активов.&lt;/strong&gt; Число разных тикеров не гарантирует диверсификацию: в стрессовом режиме они могут одновременно запросить полный резерв.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Проверьте утечку будущего.&lt;/strong&gt; &lt;code&gt;lookahead-analysis&lt;/code&gt; в Freqtrade помогает обнаруживать часть подобных ошибок, но не доказывает прибыльность или отсутствие всех видов смещения. После него нужны обычный бэктест с реальными лимитами и dry-run.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Для итогового отчёта полезнее одного win rate четыре числа: максимальная просадка equity, максимальная занятость капитала, длительность самой долгой серии и результат на всём выделенном капитале после издержек. Добавьте число серий: редкие завершения дают мало независимых наблюдений.&lt;/p&gt;
&lt;h2 id=&quot;kliuchevye-vyvody&quot;&gt;Ключевые выводы&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Геометрическое увеличение покупок требует заранее посчитанного бюджета, даже если первая заявка мала.&lt;/li&gt;
&lt;li&gt;Снижение средней цены не означает снижения денежного риска.&lt;/li&gt;
&lt;li&gt;Ограничение количества покупок — не замена выходу и портфельному лимиту.&lt;/li&gt;
&lt;li&gt;Арифметический тест, исторический бэктест и dry-run отвечают на разные вопросы; ни один не гарантирует будущую прибыль.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Практический первый шаг — выписать B, S, m и N из своего исследовательского конфига и сравнить полный бюджет с доступным резервом при одновременном заполнении всех серий. Это материал об инженерной проверке рисков, а не рекомендация запускать усреднение на реальном счёте.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;pervoistochniki-i-materialy&quot;&gt;Первоисточники и материалы&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Оригинальное видео:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://youtu.be/M1036x1Hobg&quot;&gt;DCA Martingale Trading Bot Explained — Risk Controls + Out-of-Sample Backtest&lt;/a&gt;. Результаты стратегии независимо не воспроизводились.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Документация callback:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://www.freqtrade.io/en/stable/strategy-callbacks/#adjust-trade-position&quot;&gt;Freqtrade — Adjust trade position&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Проверка утечки будущего:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://www.freqtrade.io/en/stable/lookahead-analysis/&quot;&gt;Freqtrade — Lookahead analysis&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Инженерные наработки:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://github.com/xsa-dev&quot;&gt;github.com/xsa-dev&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ru">
        <title>Автоматическая миграция C/C++ на Rust: 3-этапный пайплайн Google, Gemini 4 Argon и дифференциальный фаззинг</title>
        <published>2026-10-08T00:00:00+00:00</published>
        <updated>2026-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>Alexei Savin</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://xsa-dev.github.io/posts/cpp-to-rust-ai-migration-google-pipeline/"/>
        <id>https://xsa-dev.github.io/posts/cpp-to-rust-ai-migration-google-pipeline/</id>
        
        <content type="html" xml:base="https://xsa-dev.github.io/posts/cpp-to-rust-ai-migration-google-pipeline/">&lt;p&gt;Проблема безопасности памяти (Memory Safety) в системном программировании давно перешла из теоретических дискуссий в категорию критических инфраструктурных рисков. По данным многолетних отчетов безопасности Google и Microsoft, около &lt;strong&gt;70% всех критических уязвимостей&lt;/strong&gt; нулевого дня (Zero-Day CVE) в масштабных кодовых базах на C и C++ (таких как Chromium, ядра ОС, медиадекодеры и сетевые стеки) вызваны ошибками работы с памятью: Use-After-Free, Out-of-Bounds Write, Double Free и Data Races.&lt;/p&gt;
&lt;p&gt;Переписывание сотен миллионов строк унаследованного C/C++ кода вручную силами инженеров требует десятилетий и сопряжено с колоссальными затратами. Инженерные команды Google перешли к индустриальному решению задачи: автоматизированному конвейеру миграции на базе специализированных AI-агентов (Gemini 4 Argon), строгой верификации через дифференциальный фаззинг и компиляторной оптимизации.&lt;/p&gt;
&lt;p&gt;В этой статье разобран 3-этапный пайплайн миграции Google, физика работы дифференциального фаззинга, специфика генерации безопасных FFI-границ и реальные результаты переноса критических проектов (&lt;code&gt;giflib&lt;/code&gt;, &lt;code&gt;libgav1&lt;/code&gt; и микроядра Zircon).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;1-arkhitektura-3-etapnogo-konveiera-migratsii&quot;&gt;1. Архитектура 3-этапного конвейера миграции&lt;/h2&gt;
&lt;p&gt;Главный барьер при автоматической генерации системного кода нейросетями — риск внесения скрытых семантических расхождений и тонких регрессий, которые не ловятся обычными юнит-тестами.&lt;/p&gt;
&lt;p&gt;Чтобы исключить галлюцинации и гарантировать 100% эквивалентность логики, в Google реализовали замкнутый контур с автоматической обратной связью:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;flowchart&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    A&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Legacy C/C++ Codebase&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;] --&amp;gt;&lt;/span&gt;&lt;span&gt; B&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;1. Трансляция кода - Gemini 4 Argon&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    B &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; C&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;2. Выделение FFI и Safe Wrappers&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    C &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; D&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Сборка Shared Objects - lib_legacy.so vs lib_rust.so&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    D &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; E&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;3. Дифференциальный фаззинг - LibAFL / AFL++&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    E &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; F&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Обнаружены дельты в поведении?&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    F &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Да: расхождение вывода или краш&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; G&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Генерация контрпримера и отчета&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    G &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; B&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    F &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Нет: миллиарды итераций пройдены&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; H&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Верифицированный Rust Crate&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    H &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; I&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Интеграция в Production&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;etap-1-semanticheskaia-transliatsiia-c-c-v-rust&quot;&gt;Этап 1: Семантическая трансляция C/C++ в Rust&lt;/h3&gt;
&lt;p&gt;Модель не просто переводит синтаксис строчка в строчку. Ее задача — выделить логические структуры данных, определить границы владения объектами и транслировать императивный процедурный код в идиоматический Rust с минимально необходимым объемом &lt;code&gt;unsafe&lt;/code&gt;-блоков. При этом сохраняется полная совместимость с внешним C-ABI: экспортируемые сигнатуры функций и структуры данных сохраняют исходный layout.&lt;/p&gt;
&lt;h3 id=&quot;etap-2-izoliatsiia-ffi-i-generatsiia-safe-wrappers&quot;&gt;Этап 2: Изоляция FFI и генерация Safe Wrappers&lt;/h3&gt;
&lt;p&gt;Любой переносимый модуль должен бесшовно встраиваться в существующую экосистему без необходимости перекомпиляции зависимых сервисов. На границе FFI генерируется безопасный фасад:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Сырые указатели (&lt;code&gt;*mut T&lt;/code&gt;, &lt;code&gt;*const T&lt;/code&gt;) оборачиваются в &lt;code&gt;Option&amp;lt;NonNull&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Проверяются инварианты выравнивания и валидности переданных буферов.&lt;/li&gt;
&lt;li&gt;Жизненный цикл ресурсов инкапсулируется через типаж &lt;code&gt;Drop&lt;/code&gt; (RAII), исключая утечки памяти.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;etap-3-differentsial-nyi-fazzing-s-obratnoi-sviaz-iu&quot;&gt;Этап 3: Дифференциальный фаззинг с обратной связью&lt;/h3&gt;
&lt;p&gt;Оригинальная C-библиотека и сгенерированная Rust-библиотека компилируются как взаимозаменяемые динамические библиотеки (&lt;code&gt;.so&lt;/code&gt;). Специализированный фаззер генерирует миллионы мутированных входных потоков байтов, подавая их параллельно в обе реализации. Если поведение Rust-модуля расходится с C хотя бы на 1 бит (или одна из версий завершается паникой/крашем), формируется минимизированный контрпример, который отправляется в контекст AI-агента для локализации бага.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;2-sravnenie-podkhodov-ruchnaia-migratsiia-vs-ai-fazzing-kontur&quot;&gt;2. Сравнение подходов: Ручная миграция vs AI-фаззинг контур&lt;/h2&gt;
&lt;p&gt;Ниже приведено структурное сравнение ключевых характеристик различных подходов к обеспечению memory safety в production:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Параметр&lt;/th&gt;&lt;th&gt;Ручной перенос на Rust&lt;/th&gt;&lt;th&gt;Статический анализ C/C++&lt;/th&gt;&lt;th&gt;Конвейер Google (AI + Фаззинг)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Скорость миграции&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;100–300 строк/день на инженера&lt;/td&gt;&lt;td&gt;Мгновенно (без миграции)&lt;/td&gt;&lt;td&gt;10 000+ строк/день на агентный кластер&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Гарантии Memory Safety&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Высокие (после ревью)&lt;/td&gt;&lt;td&gt;Низкие (много false negatives)&lt;/td&gt;&lt;td&gt;Абсолютные на уровне &lt;code&gt;rustc&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Семантическая точность&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Человеческий фактор&lt;/td&gt;&lt;td&gt;Не применимо&lt;/td&gt;&lt;td&gt;Проверена миллиардами фаззинг-мутаций&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Сохранение C-ABI&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Трудоемко вручную&lt;/td&gt;&lt;td&gt;Сохраняется C-код&lt;/td&gt;&lt;td&gt;Автоматическая генерация &lt;code&gt;#[no_mangle]&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Устранение Legacy 0-day&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Редко&lt;/td&gt;&lt;td&gt;Частично&lt;/td&gt;&lt;td&gt;Выявляются попутно в процессе фаззинга&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;3-inzheneriia-bezopasnykh-ffi-granits-i-upravlenie-resursami&quot;&gt;3. Инженерия безопасных FFI-границ и управление ресурсами&lt;/h2&gt;
&lt;p&gt;Рассмотрим конкретный пример: трансляция низкоуровневого буфера данных с ручным управлением памятью в C в безопасную абстракцию на Rust с сохранением ABI.&lt;/p&gt;
&lt;h3 id=&quot;iskhodnyi-c-kod-legacy-interfeis-s-riskami-uaf&quot;&gt;Исходный C-код (Legacy-интерфейс с рисками UAF)&lt;/h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; &amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; &amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; &amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;typedef&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;    uint8_t&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span&gt; data&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;    size_t&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;    size_t&lt;/span&gt;&lt;span&gt; capacity&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} ByteBuffer&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ByteBuffer&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; byte_buffer_create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;size_t&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; initial_capacity&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ByteBuffer&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span&gt; buf &lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;=&lt;/span&gt;&lt;span&gt; (ByteBuffer&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;sizeof&lt;/span&gt;&lt;span&gt;(ByteBuffer))&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;!&lt;/span&gt;&lt;span&gt;buf)&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; NULL&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;uint8_t&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;malloc&lt;/span&gt;&lt;span&gt;(initial_capacity)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;!&lt;/span&gt;&lt;span&gt;buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;data) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;        free&lt;/span&gt;&lt;span&gt;(buf)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; NULL&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;capacity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; initial_capacity&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; byte_buffer_append&lt;/span&gt;&lt;span&gt;(ByteBuffer&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; uint8_t&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; size_t&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; len&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;!&lt;/span&gt;&lt;span&gt;buf &lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;|| !&lt;/span&gt;&lt;span&gt;src)&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +&lt;/span&gt;&lt;span&gt; len &lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;capacity) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;        size_t&lt;/span&gt;&lt;span&gt; new_cap &lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;=&lt;/span&gt;&lt;span&gt; (buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;capacity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +&lt;/span&gt;&lt;span&gt; len)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ?&lt;/span&gt;&lt;span&gt; buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;capacity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; :&lt;/span&gt;&lt;span&gt; buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;        uint8_t&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span&gt; new_data &lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;uint8_t&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;realloc&lt;/span&gt;&lt;span&gt;(buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; new_cap)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;!&lt;/span&gt;&lt;span&gt;new_data)&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; new_data&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;capacity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; new_cap&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;    memcpy&lt;/span&gt;&lt;span&gt;(buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +&lt;/span&gt;&lt;span&gt; buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; len)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; +=&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; byte_buffer_free&lt;/span&gt;&lt;span&gt;(ByteBuffer&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; buf&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (buf) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;data)&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; free&lt;/span&gt;&lt;span&gt;(buf&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;data)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;        free&lt;/span&gt;&lt;span&gt;(buf)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;sgenerirovannyi-rust-modul-s-bezopasnoi-inkapsuliatsiei-i-c-abi&quot;&gt;Сгенерированный Rust-модуль с безопасной инкапсуляцией и C-ABI&lt;/h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;ptr&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;NonNull&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span&gt;slice;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[repr(&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;C&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;pub struct&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; ByteBufferFFI&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    data&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    size&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    capacity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #5A6673;font-style: italic;&quot;&gt;// Внутренняя безопасная структура с авто-освобождением через RAII&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;pub struct&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; SafeByteBuffer&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inner&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; Vec&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; SafeByteBuffer&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    pub fn&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; with_capacity&lt;/span&gt;&lt;span&gt;(cap&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; usize&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;font-style: italic;&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #39BAE6;font-style: italic;&quot;&gt;        Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            inner&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;with_capacity&lt;/span&gt;&lt;span&gt;(cap),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    pub fn&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; append&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;font-style: italic;&quot;&gt; self&lt;/span&gt;&lt;span&gt;, src&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;: &amp;amp;&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;u8&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;(), ()&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #39BAE6;font-style: italic;&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;inner&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;extend_from_slice&lt;/span&gt;&lt;span&gt;(src);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;        Ok&lt;/span&gt;&lt;span&gt;(())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[no_mangle]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;pub unsafe extern&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; &amp;quot;C&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; byte_buffer_create&lt;/span&gt;&lt;span&gt;(initial_capacity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; usize&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&amp;gt; *&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; ByteBufferFFI&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    let mut&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;with_capacity&lt;/span&gt;&lt;span&gt;(initial_capacity);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; raw_ptr&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;as_mut_ptr&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; cap&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;capacity&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;    std&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;mem&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;forget&lt;/span&gt;&lt;span&gt;(vec);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; boxed&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;ByteBufferFFI&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        data&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span&gt; raw_ptr,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        size&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        capacity&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span&gt; cap,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;    Box&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;into_raw&lt;/span&gt;&lt;span&gt;(boxed)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[no_mangle]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;pub unsafe extern&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; &amp;quot;C&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; byte_buffer_append&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buf&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; ByteBufferFFI&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    src&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    len&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; buf&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_null&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ||&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_null&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; buf_ref&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; = &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; *&lt;/span&gt;&lt;span&gt;buf;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    let&lt;/span&gt;&lt;span&gt; input_slice&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; slice&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;from_raw_parts&lt;/span&gt;&lt;span&gt;(src, len);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #5A6673;font-style: italic;&quot;&gt;    // Восстанавливаем Vec для безопасного реаллоцирования&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    let mut&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;from_raw_parts&lt;/span&gt;&lt;span&gt;(buf_ref&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;data, buf_ref&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;size, buf_ref&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;capacity);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;extend_from_slice&lt;/span&gt;&lt;span&gt;(input_slice);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #5A6673;font-style: italic;&quot;&gt;    // Обновляем FFI-структуру&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buf_ref&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;data &lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;=&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;as_mut_ptr&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buf_ref&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;size &lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;=&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;len&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    buf_ref&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;capacity &lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;=&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;capacity&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;    std&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt;mem&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;forget&lt;/span&gt;&lt;span&gt;(vec);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;    0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[no_mangle]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;pub unsafe extern&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; &amp;quot;C&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; byte_buffer_free&lt;/span&gt;&lt;span&gt;(buf&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;mut&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; ByteBufferFFI&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; !&lt;/span&gt;&lt;span&gt;buf&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_null&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        let&lt;/span&gt;&lt;span&gt; boxed&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;from_raw&lt;/span&gt;&lt;span&gt;(buf);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; !&lt;/span&gt;&lt;span&gt;boxed&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;is_null&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;            let&lt;/span&gt;&lt;span&gt; _&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #59C2FF;&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;from_raw_parts&lt;/span&gt;&lt;span&gt;(boxed&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;data, boxed&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;size, boxed&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;.&lt;/span&gt;&lt;span&gt;capacity);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Благодаря &lt;code&gt;#[repr(C)]&lt;/code&gt; и &lt;code&gt;#[no_mangle]&lt;/code&gt; скомпилированная Rust-библиотека подменяет оригинальный &lt;code&gt;.so&lt;/code&gt; файл без перекомпиляции зависимых C/C++ приложений.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;4-matematicheskaia-model-differentsial-nogo-fazzinga&quot;&gt;4. Математическая модель дифференциального фаззинга&lt;/h2&gt;
&lt;p&gt;При дифференциальном фаззинге проверяется гипотеза о тождественности функций $f_{\text{C}}(x)$ и $f_{\text{Rust}}(x)$ на всем пространстве допустимых и недопустимых входных данных $x \in \mathcal{X}$.&lt;/p&gt;
&lt;p&gt;Пусть в кодовой базе существует скрытый дефект с вероятностью проявления $p_k$ на одной итерации случайной мутации входного вектора. При независимой генерации $N$ тест-кейсов вероятность обнаружения расхождения $P_{\text{detect}}$ выражается как:&lt;/p&gt;
&lt;p&gt;$$P_{\text{detect}}(N) = 1 - \prod_{k=1}^{M} \left(1 - p_k\right)^{N_k}$$&lt;/p&gt;
&lt;p&gt;Где:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$M$ — число потенциальных пограничных состояний в графе потока управления (CFG);&lt;/li&gt;
&lt;li&gt;$N_k$ — количество сгенерированных мутаций, покрывающих ветвь $k$;&lt;/li&gt;
&lt;li&gt;$p_k$ — вероятность расхождения семантики при исполнении ветви $k$.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;В конвейере Google фаззер использует покрытие кода (Coverage-Guided Differential Fuzzing). Когда мутатор находит вход $x^*$, приводящий к:&lt;/p&gt;
&lt;p&gt;$$\Delta(x^&lt;em&gt;) = \left| f_{\text{C}}(x^&lt;/em&gt;) - f_{\text{Rust}}(x^&lt;em&gt;) \right| &amp;gt; 0 \quad \lor \quad \text{Status}_{\text{C}}(x^&lt;/em&gt;) \neq \text{Status}_{\text{Rust}}(x^*)$$&lt;/p&gt;
&lt;p&gt;Контрпример немедленно сохраняется в виде минимального байтового среза (minimization corpus) и передается в prompt-контекст агента Gemini 4 Argon с трассировкой стека вызовов.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;5-rezul-taty-real-nykh-keisov-giflib-libgav1-i-zircon&quot;&gt;5. Результаты реальных кейсов: giflib, libgav1 и Zircon&lt;/h2&gt;
&lt;p&gt;Практическая апробация 3-этапного пайплайна в инфраструктуре Google показала неожиданные эффекты не только в области надежности, но и в производительности.&lt;/p&gt;
&lt;h3 id=&quot;rezul-taty-migratsii-kliuchevykh-proektov&quot;&gt;Результаты миграции ключевых проектов&lt;/h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Проект&lt;/th&gt;&lt;th&gt;Объем / Архитектура&lt;/th&gt;&lt;th&gt;Результат миграции на Rust&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;giflib&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;~3 000 строк C&lt;/td&gt;&lt;td&gt;100% ABI-совместимость. Попутно обнаружена и закрыта Zero-Day уязвимость &lt;code&gt;CVE-2026-26740&lt;/code&gt; (out-of-bounds heap write) в оригинальном C-коде.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;libgav1&lt;/strong&gt; (AV1 декодер)&lt;/td&gt;&lt;td&gt;32 000 строк C + Hand-written SIMD&lt;/td&gt;&lt;td&gt;Полный отказ от ассемблерных вставок в пользу Safe Rust. Ускорение декодирования в &lt;strong&gt;2.7 раза&lt;/strong&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Fuchsia Zircon Kernel&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;800 000+ строк C/C++&lt;/td&gt;&lt;td&gt;Модульная миграция подсистем ядра ОС без деградации IPC-латентности.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;pochemu-safe-rust-v-libgav1-obognal-32k-strok-ruchnogo-simd&quot;&gt;Почему Safe Rust в libgav1 обогнал 32k строк ручного SIMD?&lt;/h3&gt;
&lt;p&gt;Один из главных мифов системной разработки гласит: &lt;em&gt;«Ручные SIMD-интринсики на C всегда быстрее безопасного кода»&lt;/em&gt;. Кейс &lt;code&gt;libgav1&lt;/code&gt; опроверг это на практике.&lt;/p&gt;
&lt;p&gt;Причина кроется в алиасинге указателей (Pointer Aliasing). В языке C компилятор вынужден консервативно предполагать, что любые два указателя одного типа (&lt;code&gt;uint8_t* a&lt;/code&gt;, &lt;code&gt;uint8_t* b&lt;/code&gt;) могут указывать на перекрывающиеся области памяти (если не указано ключевое слово &lt;code&gt;restrict&lt;/code&gt;, которое разработчики часто забывают). Это блокирует автоматическую векторизацию циклов компилятором LLVM.&lt;/p&gt;
&lt;p&gt;В Rust модель владения гарантирует:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ссылка &lt;code&gt;&amp;amp;mut T&lt;/code&gt; является &lt;strong&gt;строго уникальной&lt;/strong&gt; (no-alias invariant гарантирован на уровне семантики языка).&lt;/li&gt;
&lt;li&gt;Ссылки &lt;code&gt;&amp;amp;T&lt;/code&gt; гарантированно неизменяемы (immutable).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Получив чистый Rust-код без алиасинга, оптимизатор LLVM смог провести агрессивную векторизацию для инструкций AVX2 и AVX-512, выстроив конвейер вычислений эффективнее, чем 32 000 строк устаревшего ручного ассемблерного кода, написанного под специфические микроархитектуры прошлых поколений.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;6-chek-list-vnedreniia-ai-migratsii-v-inzhenernyi-kontur&quot;&gt;6. Чек-лист внедрения AI-миграции в инженерный контур&lt;/h2&gt;
&lt;p&gt;Для команд, планирующих перевод критических C/C++ библиотек на Rust:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Изолируйте C-ABI заголовок:&lt;/strong&gt; Сформируйте чистый заголовочный файл &lt;code&gt;.h&lt;/code&gt; со всеми экспортируемыми функциями и типами данных.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Сгенерируйте Rust FFI через bindgen / AI:&lt;/strong&gt; Обеспечьте точное соответствие структур с аннотацией &lt;code&gt;#[repr(C)]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Разверните дифференциальный фаззер (LibAFL):&lt;/strong&gt; Напишите harness, принимающий входной буфер &lt;code&gt;const uint8_t* data, size_t size&lt;/code&gt; и вызывающий обе библиотеки.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Задайте порог останова фаззинга:&lt;/strong&gt; Минимум $10^8$ итераций без единого расхождения вывода и без утечек памяти (проверяется через ASan/Valgrind).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Замените &lt;code&gt;.so&lt;/code&gt; в staging-окружении:&lt;/strong&gt; Проведите нагрузочное и регрессионное тестирование зависимых сервисов.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;kliuchevye-vyvody&quot;&gt;Ключевые выводы&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Автономная миграция стала индустриальным стандартом:&lt;/strong&gt; AI-агенты в связке со строгими компиляторными верификаторами и дифференциальным фаззингом способны переносить миллионы строк системного кода, устраняя 70% фундаментальных уязвимостей безопасности памяти.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Фаззинг — единственный надежный судья:&lt;/strong&gt; Любой сгенерированный LLM системный код требует дифференциального тестирования против оригинала на миллиардах мутированных входных векторов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Safe Rust не уступает в скорости:&lt;/strong&gt; Строгие гарантии уникальности ссылок (&lt;code&gt;&amp;amp;mut&lt;/code&gt;) в Rust дают компилятору LLVM свободу векторизации, превосходящую ручной legacy-ассемблер.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;pervoistochniki-i-materialy&quot;&gt;Первоисточники и материалы&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Оригинальное видео/статья:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://youtu.be/a3Aup1LwPhQ&quot;&gt;Let’s Get Rusty — Google Uses AI to Migrate C/C++ to Rust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Заметки и детальный конспект:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://github.com/xsa-dev/obsidian-vault/blob/main/YouTube/Google-AI-Migrating-Cpp-to-Rust-Gemini-Argon-2026.md&quot;&gt;Obsidian Vault (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Инженерные наработки:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://github.com/xsa-dev&quot;&gt;github.com/xsa-dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ru">
        <title>Self-Improving AI Software Factory: архитектура распределенной фабрики кода на базе LLM-агентов</title>
        <published>2026-10-08T00:00:00+00:00</published>
        <updated>2026-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>Alexei Savin</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://xsa-dev.github.io/posts/self-improving-ai-software-factory/"/>
        <id>https://xsa-dev.github.io/posts/self-improving-ai-software-factory/</id>
        
        <content type="html" xml:base="https://xsa-dev.github.io/posts/self-improving-ai-software-factory/">&lt;p&gt;Локальные инструменты агентного кодинга (Codex, Claude Code, Aider, OpenDevin) совершили революцию в индивидуальной разработке. Однако при попытке масштабировать этот подход на уровень команды или автоматизированного пайплайна инженеры неизбежно упираются в системный тупик:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Локальный хаос промптов и конфигураций:&lt;/strong&gt; у каждого разработчика свои настройки контекста, разные версии моделей и несогласованные правила форматирования.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Отсутствие воспроизводимости:&lt;/strong&gt; невозможно точно оценить, улучшило ли очередное изменение в системном промпте качество кодогенерации или сломало граничные кейсы.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Неэффективная трата токенов:&lt;/strong&gt; использование мощных LLM для механических задач (проверка синтаксиса, парсинг логов, поиск файлов) вместо детерминированных скриптов.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Решением становится переход от локальных CLI-утилит к &lt;strong&gt;AI Software Factory&lt;/strong&gt; — централизованной распределенной системе оркестрации агентных воркеров с замкнутым контуром самообучения (&lt;em&gt;Self-Improving Feedback Loop&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Разберем архитектуру такой фабрики (на примере системы &lt;em&gt;Machinist&lt;/em&gt;, исследованной Оуэйном Льюисом).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;1-arkhitektura-fabriki-control-plane-i-worker-pool&quot;&gt;1. Архитектура фабрики: Control Plane и Worker Pool&lt;/h2&gt;
&lt;p&gt;В основе промышленной фабрики кода лежит строгое разделение между уровнем управления (&lt;strong&gt;Control Plane&lt;/strong&gt;) и изолированными вычислительными узлами (&lt;strong&gt;Worker Pool&lt;/strong&gt;):&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;flowchart&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    subgraph&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; Triggers &lt;/span&gt;&lt;span&gt;[&amp;quot;⚡ Входной поток задач &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Triggers&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;)&lt;/span&gt;&lt;span&gt;&amp;quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        T1&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Webhooks / CI / Jira / CLI&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Triggers &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Новый тикет / запрос&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; CP&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    subgraph&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; CP &lt;/span&gt;&lt;span&gt;[&amp;quot;🎛️ CONTROL PLANE &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Machinist&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;)&lt;/span&gt;&lt;span&gt;&amp;quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        direction TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        DB&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Task Queue &amp;amp; Global State&amp;lt;br/&amp;gt;(SQLite / WAL)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Catalog&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Prompts &amp;amp; Skills Catalog&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Dashboard&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Web Dashboard &amp;amp; Traces&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        SSHGate&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;SSH Tunnel Gateway&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    CP &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;==&amp;gt;|&lt;/span&gt;&lt;span&gt;🔒&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; Dispatches jobs over SSH tunnel&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; WP&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    subgraph&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; WP &lt;/span&gt;&lt;span&gt;[&amp;quot;☁️ WORKER POOL &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Hetzner / Cloud VMs&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;)&lt;/span&gt;&lt;span&gt;&amp;quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        direction TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Foreman&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;👑 1. Foreman Agent&amp;lt;br/&amp;gt;(Планирование и декомпозиция)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        SubAgents&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;🤖 2. Sub-Agents Swarm&amp;lt;br/&amp;gt;(Claude Coder / Codex / PyTest)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Audit&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;🛡️ 3. Audit Agent + Deterministic Evals&amp;lt;br/&amp;gt;(mypy, pytest, 3-Agent Review)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Foreman &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Делегирование подзадач&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; SubAgents&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        SubAgents &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Код, патчи и артефакты&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; Audit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;preimushchestva-takoi-topologii&quot;&gt;Преимущества такой топологии:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Изоляция окружения:&lt;/strong&gt; агенты выполняют сборку, запуск тестов и системные команды на недорогих облачных серверах (например, Hetzner Cloud VM с 16–32 GB RAM), не засоряя локальную машину разработчика.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Очередь задач с лимитом параллелизма:&lt;/strong&gt; Control Plane контролирует лимиты API (&lt;code&gt;max_concurrent_jobs&lt;/code&gt;) и защищает от исчерпания рейтов LLM-провайдеров.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;2-ierarkhiia-agentnykh-rolei-foreman-sub-agents-audit&quot;&gt;2. Иерархия агентных ролей: Foreman → Sub-agents → Audit&lt;/h2&gt;
&lt;p&gt;Монолитный агент, пытающийся одновременно планировать архитектуру, писать код, ставить зависимости и проверять тесты, быстро теряет фокус из-за раздувания контекстного окна (&lt;em&gt;Context Rotting&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;В фабрике реализовано четкое разделение ответственности:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Роль&lt;/th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Зона ответственности&lt;/th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Инструменты&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Foreman (Прораб)&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Принимает высокоуровневый тикет, исследует кодовую базу, формирует план и распределяет подзадачи.&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;search_files&lt;/code&gt;, &lt;code&gt;read_file&lt;/code&gt;, &lt;code&gt;delegate_task&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Sub-Agent (Кодер)&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Выполняет строго одну изолированную задачу в конкретном модуле (написание функции, рефакторинг, фикс бага).&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;patch&lt;/code&gt;, &lt;code&gt;write_file&lt;/code&gt;, &lt;code&gt;terminal&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Audit Agent (Аудитор)&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Проверяет соответствие критериям приемки, соответствие стилю и отсутствие побочных регрессий.&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;pytest&lt;/code&gt;, &lt;code&gt;cargo test&lt;/code&gt;, &lt;code&gt;git diff&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;3-determinirovannye-evals-vmesto-lishnikh-llm-vyzovov&quot;&gt;3. Детерминированные Evals вместо лишних LLM-вызовов&lt;/h2&gt;
&lt;p&gt;Одна из главных ошибок при проектировании AI-фабрик — попытка решать все задачи через промпты нейросетей.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Золотое правило:&lt;/strong&gt; если задачу можно надежно и дешево решить регулярным выражением, статическим анализатором или bash-скриптом — &lt;strong&gt;не отправляйте ее в LLM&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #5A6673;font-style: italic;&quot;&gt;# Пример детерминированного гейта качества без участия нейросети&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;import&lt;/span&gt;&lt;span&gt; subprocess&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;import&lt;/span&gt;&lt;span&gt; sys&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; verify_code_artifact&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;repo_path&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; str&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #39BAE6;&quot;&gt; bool&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #5A6673;font-style: italic;&quot;&gt;    # 1. Синтаксический анализ и типы&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    typecheck&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; subprocess&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;run&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;mypy&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; repo_path]&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; capture_output&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;True&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; typecheck&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span&gt;returncode&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F07178;&quot;&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;[FAIL] Typecheck errors:&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;\n{&lt;/span&gt;&lt;span&gt;typecheck&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span&gt;stdout&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;decode&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; False&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #5A6673;font-style: italic;&quot;&gt;    # 2. Модульные тесты&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tests&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; =&lt;/span&gt;&lt;span&gt; subprocess&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;run&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;pytest&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; &amp;quot;-q&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;{&lt;/span&gt;&lt;span&gt;repo_path&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;/tests&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;,&lt;/span&gt;&lt;span&gt; capture_output&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;True&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span&gt; tests&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span&gt;returncode&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F07178;&quot;&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;[FAIL] Unit tests broken:&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;\n{&lt;/span&gt;&lt;span&gt;tests&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span&gt;stdout&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;decode&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #95E6CB;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; False&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt; True&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;if&lt;/span&gt;&lt;span&gt; __name__&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt; &amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color: #F29668;&quot;&gt; not&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; verify_code_artifact&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sys&lt;/span&gt;&lt;span style=&quot;color: #BFBDB6B3;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt;exit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #D2A6FF;&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Детерминированные скрипты дают &lt;strong&gt;100% стабильный результат&lt;/strong&gt;, выполняются за миллисекунды и экономят тысячи долларов на API-токенах.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;4-self-improving-feedback-loop-obuchenie-na-treisakh&quot;&gt;4. Self-Improving Feedback Loop: обучение на трейсах&lt;/h2&gt;
&lt;p&gt;Почему фабрика называется &lt;em&gt;самообучающейся&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;Агентная фабрика не просто исполняет задачи, она непрерывно накапливает базу знаний об ошибках:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #BFBDB6; background-color: #0D1017;&quot; &gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;flowchart&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Fail&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;❌ Неудачный запуск / Broken Build&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;] --&amp;gt;&lt;/span&gt;&lt;span&gt; Trace&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;📋 Трейс выполнения: логи + контекст&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    subgraph&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; RootCause &lt;/span&gt;&lt;span&gt;[&amp;quot;🔍 Автоматический анализ узкого места&amp;quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        direction TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        P1&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Неточная инструкция в системном промпте?&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        P2&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Недостаточный контекст из документации?&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        P3&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;Сбойный вспомогательный скрипт?&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Trace &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span&gt; RootCause&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    subgraph&lt;/span&gt;&lt;span style=&quot;color: #FFB454;&quot;&gt; KnowledgeUpdate &lt;/span&gt;&lt;span&gt;[&amp;quot;🚀 Обновление фабрики &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Feedback Loop&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;)&lt;/span&gt;&lt;span&gt;&amp;quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        direction TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        K1&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;1. Обновление каталога Skills &amp;amp; Prompts&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        K2&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;&amp;quot;2. Создание нового синтетического Eval-теста&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        K1 &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;&amp;lt;--&amp;gt;&lt;/span&gt;&lt;span&gt; K2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    RootCause &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;==&amp;gt;&lt;/span&gt;&lt;span&gt; KnowledgeUpdate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    KnowledgeUpdate &lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;-.-&amp;gt;|&lt;/span&gt;&lt;span style=&quot;color: #AAD94C;&quot;&gt;Внедрение в воркеры&lt;/span&gt;&lt;span style=&quot;color: #FF8F40;&quot;&gt;|&lt;/span&gt;&lt;span&gt; Fail&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Когда один агент находит решение сложной проблемы или совершает ошибку, исправление вносится в &lt;strong&gt;централизованный репозиторий промптов и скиллов&lt;/strong&gt;. В следующий раз все воркеры фабрики автоматически получают обновленную базу знаний.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;kliuchevye-vyvody&quot;&gt;Ключевые выводы&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Централизация побеждает локальный хаос:&lt;/strong&gt; единый Control Plane с версионированием промптов и очереди задач обеспечивает воспроизводимость.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Разделение труда (Foreman / Sub-agents / Audit):&lt;/strong&gt; узкоспециализированные агенты с компактным контекстом работают надежнее и дешевле монолитов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Детерминизм во главе угла:&lt;/strong&gt; используйте классические линтеры, компиляторы и тесты вместо LLM-судей везде, где это возможно.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Контур обратной связи (Evals Loop):&lt;/strong&gt; каждый упавший трейс превращается в синтетический тест для предотвращения будущих регрессий.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;pervoistochniki-i-materialy&quot;&gt;Первоисточники и материалы&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Оригинальное видео и автор:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://youtu.com/ZDOTYfJBuLw&quot;&gt;Owain Lewis — I Built A Self-Improving AI Software Factory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Детальный структурированный конспект:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://github.com/xsa-dev/obsidian-vault/blob/main/YouTube/Owain-Lewis-Self-Improving-AI-Software-Factory-2026.md&quot;&gt;Obsidian Vault: Owain Lewis Software Factory (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Инженерные наработки:&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://github.com/xsa-dev&quot;&gt;github.com/xsa-dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
</feed>
