ADR 0187 — Автономный бинарник runner перестаёт обещать Windows
Статус
Accepted. Решено сопровождающим 2026-09-30 и подтверждено
2026-10-01 (AT-343). Следует образцу
ADR 0174, который убрал Mac Intel тем
же путём, и ссылается на
ADR 0112
(бинарник через bun build --compile),
ADR 0106 (пакет
npm, который становится путём для Windows) и
ADR 0150 (install.sh, который уже отвергал
Windows целиком). Не редактирует ни один из них.
Контекст
Со времён ADR 0174 матрица обещала четыре цели, а Release получал лишь
две Linux. У win32-x64 было исправление сборки в dev, ни разу не задействованное, и
репетиция через workflow_dispatch с пустым tag (режим, который ничего не прикрепляет)
его задействовала. Слои падали один за другим, и последний — не runner:
- Run
36775746724— бинарник СОБИРАЕТСЯ и завершается с кодом 1 при использовании без аргументов:ENOENTвrealpathSync. Runner распознавал только виртуальный путь скомпилированного бинарника Linux/macOS (/$bunfs/root/); у Windows этоB:/~BUN/root/. Исправлено (AT-343,apps/runner/src/binario-compilado.ts). - Run
36779817686— использование проходит, а--self-test-ptyпроваливается сCannot find package 'node-pty': загрузчик получал форму БЕЗ двоеточия (B/~BUN/root/) и падал в обычныйimport('node-pty'). Исправлено. В этом же rundarwin-arm64и две Linux ПРОШЛИ с собственным читателем PTY из AT-342 (RN-688). - Run
36780804339—node-ptyзагружается, а отcmd.exeприходят лишь начальные последовательности ConPTY (ESC[?9001h ESC[?1004h), даже без приглашения. Самотест получил ЗОНД, не зависящий от ввода, чтобы отделить ввод от чтения. - Run
36781729045— зонд решает:cmd.exe /c echoво втором PTY отдаёт 1 фрагмент (те же две последовательности), поток чтения даётend,close, и дочерний процесс завершается с-1073741510— 0xC000013A (STATUS_CONTROL_C_EXIT). Под Bunnet.Socketповерх именованного канала вывода ConPTY завершается после первого фрагмента;node-ptyсчитает конец канала концом терминала, закрывает псевдоконсоль, и Windows убивает дочерний процесс. Ввод не участвует — умирает даже команда, которая только пишет.
Это то же семейство, что oven-sh/bun#25822,
убравший Mac Intel: слой потоков Bun под node-pty. На Unix у него
был обход (fd мастера — обычный fd, и AT-342 читает его через
fs.read, ожидая на EAGAIN); в Windows сторона чтения — именованный канал,
открытый самим node-pty как net.Socket, и нет fd, который
runner мог бы читать снаружи, не переписывая Windows-половину node-pty. Под
Node тот же node-pty используется VS Code в Windows.
Решение
Платформа уходит. Автономный бинарник начинает обещать ТРИ цели
(linux-x64, linux-arm64, darwin-arm64), а Windows остаётся с путём через
npm — npm install -g @brabo/runner, под Node. Те же четыре места
ADR 0174 меняются вместе:
build-runner-binaries.ymlубираетwin32-x64из матрицы и изALVOS_ESPERADOS.checksums.txtобъявляет отсутствие только того, что является сбоем.- Прокси
GET /runner-releases/binaryпринимает три цели и отвергаетwin32-x64собственным 400 — называя этот ADR и команду npm, не обращаясь к GitHub, — в ТОЙ ЖЕ таблице, что и отказ дляdarwin-x64(SEM_BINARIO_POR_DECISAO, читаемое имя и ADR на платформу). install.shуже отвергал Windows целиком до любой загрузки (ADR 0150) и продолжает: отказ начинает ГОВОРИТЬ также, что локальный агент там — это пакет npm, называя этот ADR.caseвinstalar_o_runnerникогда не имелwin32-x64и не получает его.- Браузер продолжает обнаруживать
win32-x64и не запрашивает загрузку: он попадает вSEM_BINARIO_PUBLICADO, который заранее падает и переходит к обычному best-effort (falhaDoBinario→ команда npm, RN-473). scripts/ci/alvos-do-runner.spec.tsсвязывает четыре места и начинает отклонятьwindows-latestв матрице.
Исправления для Windows, которые произвела репетиция (виртуальный путь в трёх
формах, загрузчик node-pty, cmd.exe в самотесте и зонд),
ОСТАЮТСЯ: они — отправная точка пути назад и ничего не стоят
другим целям.
Рассмотренные альтернативы
- Сохранить цель и публиковать бинарник, проваливающий терминал. Использование без аргументов проходит, но интерактивный терминал вкладки Code умирал бы на первом фрагменте вывода, с дочерним процессом, убитым Ctrl+C. Публиковать бинарник, о котором известно, что он сломан в функции, его оправдывающей, хуже, чем не публиковать.
- Читать канал ConPTY снаружи
node-pty, как AT-342 сделала на Unix. Потребовало бы переписать Windows-половинуnode-pty(канал открывается и подключается внутри него), а обход такого размера против открытой ошибки runtime — это долг без срока. - Сменить runtime бинарника (Node SEA) только для Windows. Изменило бы механизм распространения ADR 0112 для одной цели, со вторым путём сборки и доказательства. Это решение крупнее, чем это, и оно уместно в собственном ADR, если Bun не исправит.
Последствия
- Обещание автономного бинарника — три цели, и все три
ДОКАЗАНЫ на репетиции (runs
36779817686и36805241339, последний уже с матрицей из трёх). Release продолжает получать две, пока следующий финальный тег не задействуетdarwin-arm64. - Пользователю Windows нужен установленный Node, чтобы иметь локального агента, а
пользовательский сервис остаётся вне (ADR 0147, пункт 5). Панель браузера
говорит это текстом;
install.shтоже. - Путь назад: когда Bun исправит поток именованного канала в каком-либо
релизе, повторное включение цели — новый ADR, который вернёт
win32-x64/windows-latestв матрицу и в четыре места, связываемые spec, имена с.exeв прокси, и прогонит репетицию черезworkflow_dispatchс пустымtag— зонд--self-test-ptyсразу скажет, вернулось ли чтение.