diff --git a/docs/adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md b/docs/adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md new file mode 100644 index 000000000..e3a70da1f --- /dev/null +++ b/docs/adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md @@ -0,0 +1,423 @@ +# ADR-0067. Выпуск несёт готовые двоичные для четырёх троек из одного семени + +**Состояние:** предложено. Принимает владелец. Исходное решение владельца от +5 октября 2026: выпуск должен нести готовые двоичные под Linux и macOS, как у +`bootandy/dust`, с README, где перечислены все каналы установки, и с +публикацией во все пакетные менеджеры, куда дотягиваемся. Этот документ — +спецификация; кода в этой линии нет. +**Дата:** 5 октября 2026. +**Основание:** `.github/workflows/release.yml` (шапка несёт историю: npm убран +3 сентября 2026, с ним ушла установка под Windows и право `id-token: write`); +`.github/workflows/build-macos.yml`; `.github/workflows/install-path.yml`; +`.github/actions/release-archive/action.yml`; `packaging/homebrew/flang.rb`; +`packaging/asdf/bin/{download,install,list-all}`; `packaging/install-parity.flang`; +`README.md` «Install»; `docs/site/install.md`, `docs/site/install.ru.md`; +`flang/src/emit/c/flang_repl.c` (`FLANG_VERSION`, `FLANG_SHELL_ID`); +`scripts/seed-fingerprint`. +**Замер:** ветка `a/the-release-ships-binaries-for-four-triples` от `origin/dev` +`6b459ded0`. Двоичный `bootstrap/flang` 0.7.24, собранный в этом дереве +(`make -C bootstrap -j4`). Числа CI сняты 5 октября 2026 командами +`gh run view <прогон> --json jobs`, `gh release view v0.7.24 --json assets`, +`gh api repos/digitable-lol/flang/releases/tags/v0.7.24`. Сухого прогона матрицы +не было: линия не пушится, а `workflow_dispatch` без push не запустить. +**Рядом:** [ADR-0012](0012-trust-roots.md) — корни доверия: довод программы, а +не постоянная; пустой список корней — «не доверяем никому». +[ADR-0049](0049-short-commands-live-in-the-settings-file.md) — короткие команды в +`.flangrc`. Задача [7715](../tasks/7715-the-release-archive-is-not-reproducible-across-gzip-versions.md) +— архив не повторим между машинами, хеш только с раннера. +`docs/road-to-1-0.md`, раздел 1 — воспроизводимость семени. +Заметки: [[two-installs-answered-differently-on-54-calls-of-59]], +[[the-installed-binary-is-a-named-subset]], +[[a-feature-macro-that-opens-on-glibc-closes-on-darwin]], +[[a-packaging-copy-in-another-repository-drifts-both-ways]]. +**Задачи:** [7959](../tasks/7959-the-release-matrix-builds-four-binary-tarballs-and-one-sha256sums.md) +— матрица и вложения; [8128](../tasks/8128-the-readme-and-install-pages-carry-a-channel-table.md) +— README и страницы установки; [1710](../tasks/1710-asdf-and-homebrew-take-the-prebuilt-binary-and-fall-back-to-source.md) +— asdf и Homebrew на готовые двоичные; [1504](../tasks/1504-a-nix-flake-and-an-aur-pkgbuild-install-the-release.md) +— Nix и AUR; [1098](../tasks/1098-install-parity-covers-every-channel-with-one-instrument.md) +— паритет установки прибором. + +--- + +## 1. Что сегодня — замерено, не пересказано + +### 1.1 Вложения и каналы + +У выпуска v0.7.24 **одно вложение**: `flang-0.7.24-c.tar.gz`, 5 410 663 байт, +sha256 `9eb5a3be54b7b6e4c153a8ba885481619aa1482e13706a6d104f5b015bc3c0a6`, +65 скачиваний (снято 5 октября 2026, `gh api …/releases/tags/v0.7.24`). Внутри — +12 верхних имён: семь файлов C99 и заголовков семени, `Makefile`, `flang.1`, +`LICENSE`, `flangtutor`, каталоги `runtime/` (10 целей, 35 файлов) и `tutor/` +(снято `tar -tzf` того же архива). Двоичного файла в нём нет ни одного. + +Каналов три, и все три **собирают из исходников у человека**: + +| канал | что делает | источник | +|---|---|---| +| `brew install digitable-lol/tap/flang` | качает архив C, `make` с `-Werror`, ставит `bin`, `lib`, `include`, `share/flang/<цель>`, `man` | кран `digitable-lol/homebrew-tap`, сабмодуль `packaging/homebrew-tap` | +| `asdf install flang <версия>` | то же через `bin/download` + `bin/install` | плагин `digitable-lol/asdf-flang`, источник `packaging/asdf/` | +| клон + `make -C bootstrap install` | собирает семя, ставит `bin`, `lib`, `include`; `man` — нет; **`share/flang` — нет** | дерево | + +Третья строка — находка этого замера: поставленный из клона `flang emit` отвечает +кодом 2 «не найдены исходники рантайма C» на всех целях (снято 5 октября 2026: +`make -C bootstrap install PREFIX=<чистый>`, затем `emit … --target c` из другого +каталога). Страницы установки обещают «All three give the SAME binary» — двоичный +тот же, установка — нет. Это и есть то, что прибор паритета (раздел 5) обязан +ловить и чего сегодня никто не меряет. + +### 1.2 Что собирает CI и сколько это стоит + +| работа | раннер | что делает | длительность | +|---|---|---|---| +| `release.yml`, «Build bootstrap» | `ubuntu-latest` (x86_64, 4 ядра) | `make -C bootstrap -j4`, флаги семени с `-flto` | **6 мин 02 с** (прогон 37162267654, v0.7.24); 5 мин 58 с (прогон 37160518934) | +| `release.yml`, «Build release archive» | `ubuntu-latest` | печать компилятора в C99 + сборка напечатанного | 8 мин 08 с (прогон 37162267654) | +| `release.yml`, работа целиком | `ubuntu-latest` | | 30 мин 09 с | +| `build-macos.yml`, «Build bootstrap» | `macos-latest` (arm64, 3 ядра, 7 ГиБ) | `make -C bootstrap -j3` без `-flto` | **2 мин 38 с** (прогон 37371920145) | +| `install-path.yml`, «Build bootstrap binary» | `ubuntu-latest` / `macos-latest` | `bootstrap-reprint.sh --telo` + `make` | 6 мин 02 с / 8 мин 05 с (прогон 37302964624) | +| `install-path.yml`, работа `homebrew`, «Update formula» | `macos-latest` | `brew install --build-from-source` — то, что ждёт человека | **3 мин 29 с** (прогон 37302964624) | +| — | `ubuntu-24.04-arm` | семя не собиралось ни разу | **?** не мерено | +| — | `macos-15-intel` | семя не собиралось ни разу | **?** не мерено | + +На этой машине (gcc 15.2.0, 4 потока из 256 ядер, снято `/usr/bin/time` +5 октября 2026): `make -C bootstrap -j4` с флагами семени — 119,91 с, пик +2,0 ГиБ; с флагами формулы (без `-flto`) — 294,26 с, пик 2,8 ГиБ. Разница в +обратную сторону от замечания в `bootstrap/Makefile` («сборка дольше примерно +вдвое»): `-flto` у gcc 15 режет связывание на параллельные части и выигрывает на +многоядерной машине; на раннере с четырьмя ядрами верить надо числам раннера, а +не этим. + +### 1.3 Что двоичный знает о себе + +``` +$ bootstrap/flang --version +flang 0.7.24 +оболочка 9f361fce: правит строку (стрелки, слова, история, Tab), цвет digitable +``` + +Две строки: версия (`FLANG_VERSION`) и отпечаток оболочки (`FLANG_SHELL_ID` — +восемь знаков sha256 файла `flang_repl.c`). Оба — постоянные времени сборки, +одинаковые на любой тройке, собранной из одного семени; это уже даёт сверку +«одно ли семя» между четырьмя двоичными. **Отпечатка семени в двоичном нет:** +он лежит рядом, в `scripts/seed-fingerprint` — коммит печати `d5a0ea47`, хеши +входов печати и семи файлов тела (`bootstrap/*.c`, `*.h`, `Makefile`). Тройки +двоичный тоже не называет. `release.yml` уже сверяет первую строку с `.flangrc` +и тегом; вторую — никто. + +### 1.4 Размер и связывание (x86_64, эта машина, 5 октября 2026) + +| что | байт | +|---|---| +| `flang` с флагами семени (`-flto`), не очищенный | 24 864 648 | +| тот же, `strip` | 24 013 024 | +| тот же, `strip` + `gzip -9` | 7 419 090 | +| `flang` с флагами формулы (без `-flto`) | 25 170 608 | +| `libcompiler_flang.a` (с `-flto` / без) | 37 711 224 / 37 799 752 | +| `compiler_flang.h` + `flang_runtime.h` | 6 124 347 + 72 808 | +| архив из `flang` + `flang.1` + `LICENSE` + `runtime/` | 8 140 590 | +| архив полной раскладки (`bin`, `lib`, `include`, `share/man`, `share/flang`, `LICENSE`), сборка с `-flto` | 43 015 398 | +| тот же архив полной раскладки, сборка флагами формулы (без `-flto`) | **15 159 193** | +| тот же без `lib` и `include` (без `-flto`) | 7 693 285 | + +Разница между 43 и 15 МБ — объектный код с `-flto`: `libcompiler_flang.a` весит +одинаково в обоих случаях, но промежуточное представление gcc почти не +сжимается, а машинный код сжимается впятеро. + +`ldd`: двоичный связан динамически с `libm.so.6`, `libc.so.6`, +`ld-linux-x86-64.so.2` — и ни с чем больше. Собранный на glibc 2.39 (`ubuntu-24.04`) +не запустится на glibc 2.35 (`ubuntu-22.04`, Debian 12 с 2.36 запустится). +Статическое связывание (`LDLIBS='-lm -lpthread -static'`) **собирается и +работает** (`--version` отвечает теми же двумя строками; 24 556 208 байт, +очищенный и сжатый — 7 630 383), но компоновщик предупреждает: `getaddrinfo` в +статическом glibc требует на машине разделяемых библиотек той же версии glibc +— разрешение имён у исходящего соединения (ADR-0002) стало бы зависеть от чужой +машины молча. Статика через musl не пробовалась. + +### 1.5 Раннеры + +По таблице `actions/runner-images` (снято 5 октября 2026): `ubuntu-latest` = +Ubuntu 24.04 x64; `ubuntu-22.04`, `ubuntu-22.04-arm`, `ubuntu-24.04-arm` — GA; +`macos-latest` = macOS 26 arm64 (3 ядра, 7,00 ГиБ — замер в шапке +`build-macos.yml`); x86_64-macOS — `macos-15-intel` и `macos-26-intel` (GA). +**`macos-13` снят 4 декабря 2025** (GitHub Changelog, 19 сентября 2025) — в +матрице его быть не может; его место занимает `macos-15-intel`. + +### 1.6 Имя + +`flang` — это ещё и Фортран от LLVM: формула `flang` в `homebrew-core` (поэтому +кран зовётся полным именем), пакет `flang` в AUR. Каждый новый канал наследует +столкновение имени, и решать его придётся до первой публикации. + +### 1.7 Воспроизводимость хеша + +Задача 7715: тот же вход на раннере и на машине разработки даёт разный sha256 — +сжатие зависит от сборки `gzip`. Хеш архива можно получить только с раннера, и +`homebrew-formula:check` верно отвергает число, которое нечем подтвердить. +Двоичные это не чинят и не ухудшают: байты двоичного зависят ещё и от +компилятора раннера, то есть повторить их у себя нельзя заведомо. + +--- + +## 2. Решение + +### 2.1 Матрица выпуска: четыре тройки из одного семени + +Работа `release` в `release.yml` делится на **четыре работы матрицы и одну +сборочную**: + +| тройка | раннер | вложение | +|---|---|---| +| `linux-x86_64` | `ubuntu-22.04` | `flang-<версия>-linux-x86_64.tar.gz` | +| `linux-aarch64` | `ubuntu-22.04-arm` | `flang-<версия>-linux-aarch64.tar.gz` | +| `macos-aarch64` | `macos-latest`, `MACOSX_DEPLOYMENT_TARGET=13.0` | `flang-<версия>-macos-aarch64.tar.gz` | +| `macos-x86_64` | `macos-15-intel`, тот же `MACOSX_DEPLOYMENT_TARGET` | `flang-<версия>-macos-x86_64.tar.gz` | + +**Почему `ubuntu-22.04`, а не `ubuntu-latest`.** Динамический glibc-двоичный +запускается на glibc не старше той, с которой собран (раздел 1.4). Сборка на +22.04 даёт нижнюю границу 2.35 — Ubuntu 22.04+, Debian 12+, Fedora 36+; сборка +на 24.04 отрезала бы Debian 12 и Ubuntu 22.04 без единого слова. Статика +отвергнута из-за `getaddrinfo` (раздел 1.4); musl — не мерено, остаётся +названной возможностью. На macOS границу задаёт `MACOSX_DEPLOYMENT_TARGET`, а +не раннер, поэтому там берётся `macos-latest`. + +**Флаги — те же, что у формулы и плагина:** `-std=c99 -Wall -Wextra -Werror +-pedantic -O2`, без `-flto`. Довод не скорость, а паритет: brew и asdf уже +собирают так, и четыре двоичных должны отличаться от них только компилятором +раннера. `libcompiler_flang.a` без `-flto` связывает любой `cc` человека; с +`-flto` объектный файл несёт промежуточное представление ровно той версии gcc. +Цена названа в `bootstrap/Makefile`: работа медленнее в 1,1–1,6 раза; её платят +и сегодняшние brew- и asdf-пользователи. + +**Что внутри каждого архива — раскладка установки**, та же, что кладут формула и +плагин, под одним верхним каталогом `flang-<версия>-<ось>-<арх>/`: + +``` +bin/flang +lib/libcompiler_flang.a +include/compiler_flang.h include/flang_runtime.h +share/man/man1/flang.1 +share/flang/<цель>/… рантаймы всех целей печати, из архива C +LICENSE +seed-fingerprint.txt копия scripts/seed-fingerprint на теге +``` + +`tar -xzf flang-<версия>-<ось>-<арх>.tar.gz -C ~/.local --strip-components=1` — +установка одной командой; `bin/flang` находит `share/flang/<цель>` относительно +себя тем же правилом, что в brew и asdf (`flang_repl.c`, таблица целей). Архив +без `lib` и `include` весил бы 7,7 МБ против 15,2 (раздел 1.4, сборка флагами +формулы), но без них оболочка не вычисляет выражения (`bootstrap/Makefile`, +довод у `install`) — это был бы третий сорт установки под тем же именем, ровно +то, что отвергнуто в [[two-installs-answered-differently-on-54-calls-of-59]]. +Размер — цена, она названа: четыре архива по ≈15 МБ на выпуск (с `-flto` было +бы по 43 — ещё один довод за флаги формулы). Двоичный не очищается `strip`: он +остаётся тем, что произвёл `make`, и его можно сверить `cmp` с собственной +сборкой того же раннера. + +`tar` — повторимый, как в `release-archive` (`--sort=name --owner=0 --group=0 +--numeric-owner --mtime=@0 --mode=u=rwX,go=rX`, `gzip -9n`); на macOS — `gtar`. + +**Пятая работа** (`needs: [matrix]`) скачивает четыре артефакта, собирает архив C +тем же действием `release-archive`, пишет **один `SHA256SUMS`** на пять вложений +(`sha256sum`-формат, два пробела), сверяет хеш архива C с формулой и краном, как +сегодня, и выкладывает шесть файлов разом. Хеши — только с раннера (7715). Ни +одна работа матрицы не выкладывает сама: вложения появляются либо все, либо +никакие. + +**`workflow_dispatch` с ветки** остаётся сухим прогоном: четыре архива и +`SHA256SUMS` собираются, шаг выкладки `skipped`. Между выпусками он красен на +сверке хеша формулы (прогон 37160518934, 3 октября 2026) — это так и сегодня, и +решение этого не меняет. + +**Версия и отпечаток семени в двоичном — две ступени.** + +1. *Без перепечатки:* `seed-fingerprint.txt` в архиве; `SHA256SUMS` его не + отдельно не перечисляет — он внутри. Сверка «четыре двоичных из одного + семени» делается по второй строке `--version`: `оболочка ` обязана + совпасть на четырёх тройках знак в знак (это постоянная времени сборки из + одного файла). Шаг `release.yml` «Check binary version» исполняется в каждой + работе матрицы, а не в одной. +2. *С перепечаткой:* третья строка `--version` — `семя <8 знаков>: коммит + <7 знаков>, цель <ось>-<арх>`, где восемь знаков — sha256 тела семени из + `scripts/seed-fingerprint`, а тройка приходит ключом `-DFLANG_TARGET=…` из + матрицы (имя объявлено, не сделано: в исходниках его нет до работы 7959). Правка `flang/src/emit/c/flang_repl.c` доезжает до двоичного только + перепечаткой (шапка `release.yml`, шаг «Check binary version», и задачи 9959, + 9983) — поэтому ступень 2 не входит в задачу 7959 и ждёт ближайшей печати. + +### 2.2 Провенанс: аттестация GitHub — да, как ДОПОЛНИТЕЛЬНОЕ утверждение + +`actions/attest-build-provenance` на шесть вложений; права `id-token: write` и +`attestations: write`; проверка — `gh attestation verify <файл> --owner +digitable-lol`. + +Взвешено против ADR-0012. Тот ADR говорит: корни доверия — довод программы, а не +постоянная; и «пустой список корней — не доверяем никому». Здесь: + +- **корень, которому человек верит уже сегодня, — GitHub**: страница выпуска, + раннер, учётная запись владельца. `SHA256SUMS` рядом с вложением доказывает + только целостность переноса: хеш и файл лежат в одном месте и подменяются + вместе. Единственный хеш с другим корнем — тот, что владелец **коммитит в + кран** (`sha256` формулы): он говорит «владелец видел это число». Это и + остаётся корнем; аттестация его не заменяет; +- **аттестация добавляет второго свидетеля — Sigstore** (Fulcio, журнал Rekor) и + утверждение, которого хеш выразить не может: «этот файл собрала работа + `release.yml` репозитория `digitable-lol/flang` на теге `vX`». Доверие чужому? + Да — тому же чужому, что и раннер, плюс Sigstore. Корней в дерево это не + вносит: их несёт `gh` (TUF), и это довод программы проверки, не наша + постоянная — ровно по ADR-0012; +- **обязательной аттестация не делается ни для одного канала**: `gh` на машине + может не быть, и установка без него обязана работать. Прибор паритета + (раздел 5) зовёт `gh attestation verify`, где `gh` есть, и печатает `?`, где + нет. + +Что это стоит: `id-token: write` возвращается в `release.yml` — то самое право, +которое шапка файла сознательно сняла вместе с npm. **Это решение владельца**, +здесь оно только взвешено: доводы за записаны выше, довод против — одно лишнее +право у работы, которая и так пишет в `contents`. + +### 2.3 Homebrew: формула остаётся на исходниках; бутылки — ступень 2, решение владельца + +Три довода за бутылки: установка — секунды вместо 3 мин 29 с (раздел 1.2); +`brew` сам сверяет хеш бутылки; это «родной» двоичный канал Homebrew. Три против: + +- **доверие и воспроизводимость те же, что у архивов**: бутылка — тоже хеш с + раннера; ничего нового она не доказывает; +- **кран правится руками владельца** (AGENTS.md, «Релиз»): шесть выпусков подряд + ушли без крана. Блок `bottle do … end` — ещё два числа на тег ОС и ещё одно + вложение в выпуск КРАНА, то есть второй релизный поток в другом репозитории; +- **бутылка привязана к тегу ОС** (`arm64_sequoia`, `x86_64_linux`…). Homebrew + берёт бутылку старшей версии macOS на младшей (поведение `or_later` по + умолчанию), поэтому хватило бы одной бутылки на архитектуру с самого старого + доступного раннера; Linuxbrew — третья. Это не блокер, но третье место, где + число может отстать. + +**Решение:** ступень 1 — формула собирает из архива C, как сегодня; готовые +двоичные доступны тем же людям вложениями выпуска. Ступень 2 — бутылки, **после +двух выпусков с зелёной матрицей и по отдельному решению владельца**; тогда +`brew install --build-bottle` + `brew bottle --root-url` на двух раннерах macOS, +бутылки — во выпуск крана, блок `bottle` — в формулу дерева и крана, шаг «Check +Homebrew tap» сверяет и его. Записано в задаче 1710 второй половиной. + +### 2.4 asdf: качает двоичный под свою тройку, откат на исходники — названный + +`bin/download` узнаёт тройку (`uname -s`, `uname -m`; `arm64` → `aarch64`), +качает `flang-<версия>-<ось>-<арх>.tar.gz` и `SHA256SUMS` того же выпуска, +сверяет хеш, раскладывает. Откат на `flang-<версия>-c.tar.gz` + `make` — в трёх +случаях, каждый печатается: у выпуска нет вложения под тройку (все выпуски до +матрицы; чужие ОС и архитектуры); человек попросил сам +(`ASDF_FLANG_FROM_SOURCE=1` — имя объявлено, не сделано: плагин его не читает +до работы 1710); **хеш не сошёлся — это отказ, не откат**. Пробы +после установки не меняются: они спрашивают результат, а не дорогу. README +плагина перестаёт обещать `cc` и `make` всем — они нужны откату. + +### 2.5 Новые каналы + +| канал | решение | цена | +|---|---|---| +| **Nix (flake)** | **принят.** `flake.nix` в корне, пакет из архива C (`fetchurl` + sha256 из `SHA256SUMS`), раскладка формулы; `nix profile install github:digitable-lol/flang`. Из исходников нарочно: Nix и есть сборка из описания | `flake.lock` в дереве, обновляет `bump-version`; работа CI с установщиком Nix; имя внутри флейка — `flang`, столкновения нет | +| **AUR (PKGBUILD)** | **принят с условием:** имя пакета называет владелец (предложение — `flang-digitable`, `conflicts=('flang')`); источник — архив C; `.SRCINFO` сверяется в CI | учётная запись и ключ SSH владельца; автопубликация — отдельное решение; пакет `-bin` из двоичного — не сейчас | +| **Scoop / winget** | **вне рамок** — нет сборки под Windows | порт: 55 мест POSIX в `flang_repl.c`, 18 в `flang_runtime.c`, 13 заголовков POSIX (`termios`, `sys/wait`, `sys/socket`, `pthread`, `dirent`, `sys/ioctl`…; снято `grep` 5 октября 2026) под `#ifdef _WIN32`; раннер `windows-latest` с `msys2/setup-msys2`; пятое вложение `.zip`. Это отдельный ADR, не этот | +| **Docker-образ** | **отложен, названо.** `ghcr.io/digitable-lol/flang`: `FROM scratch` + статический двоичный; дал бы Windows путь через Docker Desktop | требует статики (раздел 1.4 — `getaddrinfo`) или образа с glibc; `packages: write`; многоархитектурный манифест; `docker` на машине разработки нет — проверять только в CI | + +### 2.6 README и страницы установки + +Таблица каналов по образцу `dust`: строка на канал — Homebrew, asdf, готовый +двоичный, из исходников, Nix, AUR (две последние — когда задача 1504 сделана); +столбцы — команда, что ставит, что нужно на машине, как проверить. Строка +готовых двоичных называет четыре имени вложений, нижнюю границу (glibc 2.35; +macOS по `MACOSX_DEPLOYMENT_TARGET`) и две команды: `sha256sum -c SHA256SUMS`, +`gh attestation verify … --owner digitable-lol`. Строка «из исходников» говорит +прямо: без `man` и без печати, пока `make install` не кладёт `share/flang` +(раздел 1.1). Обе страницы сайта — одним содержанием на двух языках; README — +английский. Жаргона в таблице нет: `jargon:check` стережёт. + +--- + +## 3. Что отвергнуто и почему + +| путь | почему не он | +|---|---| +| **npm** | отвергнут владельцем 3 сентября 2026 (шапка `release.yml`); с ним ушла единственная установка под Windows — названо там же; здесь не пересматривается | +| **«собери сам» как единственный путь** | это сегодняшнее состояние: 3 мин 29 с на M-серии, 6 мин на четырёх ядрах x86_64, отказ без `cc`, и `-Werror` ломается у человека на новом компиляторе (макрос Darwin, 19 августа 2026) — поломка доезжает до пользователя, а не до раннера | +| **`macos-13` для x86_64-macOS** | снят GitHub 4 декабря 2025; `macos-15-intel` GA | +| **`ubuntu-latest` для Linux** | нижняя граница glibc 2.39 отрезала бы Debian 12 и Ubuntu 22.04 (раздел 1.4) | +| **статическое связывание с glibc** | собирается и работает, но `getaddrinfo` зависит от разделяемого glibc той же версии на чужой машине — молчаливая зависимость хуже явной границы | +| **универсальный двоичный macOS (`lipo`) с одного раннера** | одно вложение вместо двух и без intel-раннера, но половина x86_64 собиралась бы кросс и проверялась под Rosetta — утверждение «собрано и запущено на своей тройке» ослабло бы; остаётся запасным путём, если intel-раннеры исчезнут | +| **кросс-сборка aarch64 на x86_64** | родной раннер `ubuntu-22.04-arm` есть и бесплатен для публичного репозитория | +| **бутылки Homebrew ступенью 1** | раздел 2.3: третье место для чисел в ручном кране до того, как матрица покажет себя | +| **архив из одного двоичного (без `lib`, `include`, `share/flang`)** | 7,7 МБ вместо 15,2, но третья разновидность установки под одним именем: без печати и без вычисления в оболочке | +| **флаги семени (`-flto`) для вложений** | архив 43 МБ вместо 15,2 (раздел 1.4), `libcompiler_flang.a` связывается только тем же gcc, и расхождение с brew и asdf, которые собирают без `-flto` | +| **`strip` двоичного** | экономит 851 624 байта из 24 МБ и лишает `cmp`-сверки с собственной сборкой раннера | + +--- + +## 4. Цена принятого решения + +1. **Размер выпуска:** четыре архива по ≈15 МБ плюс 5,4 МБ архива C — против + 5,4 МБ сегодня. Трафик GitHub Releases бесплатен, но страница выпуска станет + длиннее, а `bin/list-all` плагина обязан отбирать по-прежнему архив C + (его regex уже это делает: `flang-<версия>-c\.tar\.gz`). +2. **Время выпуска:** работы матрицы идут параллельно; критический путь — + самая долгая из них (ожидаемо `macos-15-intel` или `ubuntu-22.04-arm`, + **не мерено**) плюс сборочная работа. Минуты CI: для публичного репозитория + бесплатны; macOS считается с множителем только у частных. +3. **Два раннера без замера.** Ни `ubuntu-22.04-arm`, ни `macos-15-intel` семя + не собирали. Первый тег с матрицей и будет замером; красный там — не + отменить выпуск, а починить тройку (`fail-fast: false`). +4. **`id-token: write`** возвращается (раздел 2.2) — если владелец примет. +5. **Чисел для синхронизации не прибавляется** ступенью 1: формула несёт хеш + архива C, как сегодня; плагин ничего не закрепляет (`SHA256SUMS` на лету); + Nix и PKGBUILD несут хеш архива C — его поднимает `bump-version` тем же + прогоном, что формулу, и сторож по образцу `homebrew-formula:check` сверяет + три места. +6. **Отпечаток семени в двоичном** ждёт перепечатки; до неё — файл в архиве и + сверка по строке «оболочка». + +## Чего это решение НЕ даёт + +- **Повторимости хеша у себя.** Задача 7715 остаётся открытой; двоичные не + повторяются заведомо (компилятор раннера). +- **Подписи владельца.** Ни GPG, ни minisign; аттестация — свидетельство GitHub + и Sigstore, не владельца. +- **Windows.** Названа цена порта (раздел 2.5), решения нет. +- **Печати из клона.** `make -C bootstrap install` без `share/flang` — дефект + установки из исходников, замерен в разделе 1.1; чинит его не этот ADR, а + правка `bootstrap/Makefile` при перепечатке (задача 8128 называет это в + таблице, задача 1098 ловит прибором). + +--- + +## 5. Как проверять решение исполненным + +Все пять — числом, прогоном, не словом. + +1. `gh release view v --json assets --jq '.assets | length'` → **6**; имена — + четыре `flang--{linux,macos}-{x86_64,aarch64}.tar.gz`, `flang--c.tar.gz`, + `SHA256SUMS`. +2. `sha256sum -c SHA256SUMS` над пятью скачанными вложениями → **5 × OK**, код 0. +3. На каждой из четырёх троек `bin/flang --version | head -1` = `flang `; + вторая строка совпадает на четырёх **знак в знак** (одно семя — один + `FLANG_SHELL_ID`); после ступени 2 — третья строка называет семя и тройку. +4. **Паритет установки прибором** (задача 1098): `packaging/install-parity.flang` + читает N установок, сверяет каждую с первой тем же корпусом (60 вызовов) и + печатает `ИТОГ | установок N | вызовов 60 | расхождений 0`; на теге работа CI + гонит его на `ubuntu-latest` (asdf-двоичный, asdf-исходники, архив + `tar -xzf`, клон, Nix) и `macos-latest` (brew, asdf, архив, клон). Порог — + **0**; расхождение клона по `emit` снимается правкой `make install` или + названным исключением с причиной, не молча. Проба порчи: подменённый + двоичный другого выпуска → «не тот двоичный», код ненулевой. +5. `gh attestation verify flang--linux-x86_64.tar.gz --owner digitable-lol` → + код 0 — если аттестация принята; иначе строка `?` в отчёте прибора. +6. `asdf install flang ` на `macos-latest` — **без вызова `make`, не дольше + 60 с** (против 3 мин 29 с сборки формулы на том же раннере). + +--- + +## Нужно от владельца + +1. **Аттестация** (раздел 2.2): вернуть `id-token: write` в `release.yml` — да/нет. +2. **Бутылки Homebrew** (раздел 2.3): ступень 2 после двух зелёных выпусков — + да/нет/никогда. +3. **Имя пакета AUR** (раздел 2.5): `flang-digitable` или иное; кто держит + учётную запись AUR. +4. **Windows** (раздел 2.5): заводить ли ADR о порте под MSYS2 — цена названа. +5. **Раннеры Linux**: `ubuntu-22.04` ради glibc 2.35 вместо `ubuntu-latest` — + подтвердить. diff --git a/docs/tasks/1098-install-parity-covers-every-channel-with-one-instrument.md b/docs/tasks/1098-install-parity-covers-every-channel-with-one-instrument.md new file mode 100644 index 000000000..b5291ade3 --- /dev/null +++ b/docs/tasks/1098-install-parity-covers-every-channel-with-one-instrument.md @@ -0,0 +1,95 @@ +--- +номер: 1098 +заголовок: Прибор паритета установок знает ровно две установки и не зовётся ниоткуда; что все каналы ставят один двоичный с одним отпечатком, никто не меряет +статус: свободна +приоритет: P1 +исполнитель: — +ветка: — +команда: вторая +карта: Что мешает больше всего +рядом: 7959, 1710, 8128, 1504 +нужность: решение ADR-0067 считается исполненным только прибором: все каналы ставят тот же двоичный с тем же отпечатком; без прибора это слово, а не число +--- + +# 1098. Прибор паритета установок знает ровно две установки и не зовётся ниоткуда; что все каналы ставят один двоичный с одним отпечатком, никто не меряет + +Решение: [ADR-0067](../adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md), +раздел 5 — как проверять решение исполненным. + +## Шаги воспроизведения + +1. Сколько установок читает прибор: `grep -n 'sverka-nastroyka' packaging/install-parity.flang` + и пример настройки в функции «Поле настройки» (шесть строк: имя первой, + приставка первой, имя второй, приставка второй, корень, рабочий каталог). +2. Кто его зовёт: `grep -rc 'install-parity' .github/workflows/*.yml .flangrc | grep -v ':0'` +3. Разные ли установки сегодня: поставить из клона в чистый префикс и напечатать + из другого каталога (шаги задачи о таблице каналов) — `flang emit` отвечает + кодом 2, у установки brew или asdf того же выпуска — кодом 0. + +## Что происходит + +``` +$ grep -n 'sverka-nastroyka' packaging/install-parity.flang +397: ожидается вариант «Сделать» с поручение равным (вариант «Прочитать файл» с путь равным "sverka-nastroyka.txt") … +405: то вариант «Сделать» с поручение равным (вариант «Прочитать файл» с путь равным "sverka-nastroyka.txt") … + код 0 +$ grep -rc 'install-parity' .github/workflows/*.yml .flangrc | grep -v ':0' + код 1 +``` + +Прибор `packaging/install-parity.flang` (план «Сверка», корпус 60 вызовов, +сверка кода, вывода и потока ошибок) сравнивает РОВНО две установки из +настройки `sverka-nastroyka.txt` и не зовётся ни одной работой CI и ни одной +короткой командой `.flangrc`. Заведён он был для пары npm/brew +(`docs/zettel/two-installs-answered-differently-on-54-calls-of-59.md`); npm +ушёл, пара распалась, прибор остался без предмета. Между тем установка из клона +уже сегодня отвечает на десять вызовов `emit` корпуса иначе, чем brew и asdf +(рантайма нет), и этого не видит никто. + +Версия: `flang 0.7.24`, `оболочка 9f361fce`. Прогон 5 октября 2026. + +## Что должно быть + +Прибор читает настройку с N установок (N ≥ 2; первая — эталон, остальные +сверяются с ней попарно тем же корпусом), печатает по строке на пару и общий +итог `ИТОГ | установок N | вызовов 60 | расхождений 0`; расхождение в первых +двух строках `--version` (версия и отпечаток оболочки) называется отдельно — +это «не тот двоичный», а не «другой ответ». Каждая добавленная строка +`.flang` — не длиннее 120 знаков. Короткая команда `install-parity:check` в +`.flangrc`. Работа CI на теге (в `install-path.yml` или рядом): на +`ubuntu-latest` — установки asdf (двоичный), asdf (`FROM_SOURCE=1`), готовый +архив `tar -xzf`, клон `make install`, Nix (если принят); на `macos-latest` — +brew, asdf, готовый архив, клон. Порог — `расхождений 0`; расхождения клона по +`emit` снимаются либо правкой `make install` (класть `share/flang`), либо +названным исключением в настройке с причиной — молча не глотаются. + +## Обходной путь + +Запускать прибор руками на двух установках: написать `sverka-nastroyka.txt` из +шести строк и `bootstrap/flang io packaging/install-parity.flang --на-веру`. +Третью установку сверять вторым прогоном. + +## Когда задача сделана + +1. `bootstrap/flang io packaging/install-parity.flang --на-веру` на настройке из + четырёх установок печатает `ИТОГ | установок 4 | вызовов 60 | расхождений 0` + и завершается кодом 0. +2. Работа CI на теге зовёт `install-parity:check` на обоих раннерах; её имя + стоит в `docs/ci-inventory.md`, а не только в YAML. +3. Проба порчи: одна из установок подменена двоичным другого выпуска — + прибор печатает `не тот двоичный: --version разошёлся` и уходит ненулевым + кодом; вторая порча — у одной установки снят каталог `share/flang/js` — + прибор называет вызов `emit … --target js` и расходится ровно на нём. +4. `flang check packaging/install-parity.flang` зелен, примеры у новых функций + есть; длина добавленных строк не больше 120 знаков + (`awk 'length > 120' packaging/install-parity.flang` молчит). +5. Если двоичные всех четырёх троек собраны одним семенем, строка «оболочка …» + в `--version` совпадает на обеих платформах CI — прибор это печатает числом, + а не словами. + +## Где живёт правка + +`packaging/install-parity.flang` (настройка на N установок, попарная сверка, +отдельный отказ на `--version`), `.flangrc` (команда `install-parity:check`), +`.github/workflows/install-path.yml` (работа на теге), `docs/ci-inventory.md`. +Перепечатка не нужна: прибор исполняется `flang io`, а не живёт в семени. diff --git a/docs/tasks/1504-a-nix-flake-and-an-aur-pkgbuild-install-the-release.md b/docs/tasks/1504-a-nix-flake-and-an-aur-pkgbuild-install-the-release.md new file mode 100644 index 000000000..a5812a895 --- /dev/null +++ b/docs/tasks/1504-a-nix-flake-and-an-aur-pkgbuild-install-the-release.md @@ -0,0 +1,88 @@ +--- +номер: 1504 +заголовок: Ни Nix, ни Arch не ставят flang: в дереве нет flake.nix и PKGBUILD, а имя `flang` в AUR занято Фортраном от LLVM +статус: свободна +приоритет: P3 +исполнитель: — +ветка: — +команда: вторая +карта: Что мешает больше всего +рядом: 7959, 1098, 8128 +нужность: владелец решил публиковаться во все менеджеры, куда дотягиваемся без Windows; Nix и AUR дотягиваются из того же архива C и не требуют ни Node, ни своих раннеров +--- + +# 1504. Ни Nix, ни Arch не ставят flang: в дереве нет flake.nix и PKGBUILD, а имя `flang` в AUR занято Фортраном от LLVM + +Решение: [ADR-0067](../adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md), +раздел 2.5 — новые каналы. Делается ПОСЛЕ матрицы выпуска и после того, как +владелец назовёт имя пакета для AUR. + +## Шаги воспроизведения + +1. `ls flake.nix packaging/aur` +2. `command -v nix makepkg` — есть ли инструменты на машине разработки. +3. Открыть `https://aur.archlinux.org/packages/flang` — кто занимает имя. + +## Что происходит + +``` +$ ls flake.nix packaging/aur +ls: cannot access 'flake.nix': No such file or directory +ls: cannot access 'packaging/aur': No such file or directory код 2 +$ command -v nix makepkg + код 1 +``` + +Ни флейка, ни PKGBUILD в дереве нет; на машине разработки нет ни `nix`, ни +`makepkg`, то есть проверять оба канала можно только в CI (снято 5 октября +2026). В AUR пакет `flang` — «ground-up implementation of a Fortran front end +written in modern C++» (LLVM Flang); в `homebrew-core` имя `flang` занято им +же — потому наш кран и зовётся полным именем `digitable-lol/tap/flang`. + +Версия: `flang 0.7.24`, `оболочка 9f361fce`. Прогон 5 октября 2026. + +## Что должно быть + +**Nix.** `flake.nix` в корне дерева: пакет `flang` из архива C выпуска +(`fetchurl` с `sha256` из `SHA256SUMS`), сборка — `make` с флагами формулы, +установка — раскладка как у формулы (`bin`, `lib`, `include`, `share/flang`, +`share/man`). `nix profile install github:digitable-lol/flang` и `nix run` дают +`flang --version` = версия выпуска. `flake.lock` коммитится; обновляет его +`bump-version` вместе с версией и хешем. Сборка из исходников — нарочно: Nix +сам и есть сборка из описания, готовый двоичный ему чужероден. + +**AUR.** `packaging/aur/PKGBUILD` и `.SRCINFO` для пакета с именем, которое +назовёт владелец (предложение ADR: `flang-digitable`; `conflicts=('flang')`, +потому что исполняемый файл тот же `flang`), источник — архив C с `sha256sums`, +сборка — `make` с флагами формулы, `package()` — та же раскладка. Второй пакет +`-bin` из готового двоичного — не в этой задаче. Публикация в AUR требует +учётной записи и ключа SSH владельца; автоматика (`KSXGitHub/github-actions-deploy-aur` +с секретом) — отдельное решение владельца, до него `.SRCINFO` сверяется в CI, +а пушит владелец. + +## Обходной путь + +Пользователь Nix: `nix-shell -p gcc gnumake`, клон, `make -C bootstrap`. +Пользователь Arch: `base-devel`, то же. Оба — вручную, без менеджера. + +## Когда задача сделана + +1. Работа CI на `ubuntu-latest` с установщиком Nix: `nix build .#flang` и + `result/bin/flang --version | head -1` = `flang `; `nix flake check` зелен. +2. Работа CI в контейнере `archlinux:base-devel`: `makepkg -si --noconfirm` из + `packaging/aur`, `flang --version | head -1` = `flang `; + `makepkg --printsrcinfo` совпадает с `.SRCINFO` знак в знак (иначе — красное). +3. Прибор паритета (задача об install-parity) даёт `расхождений 0` между + установкой Nix и установкой из готового двоичного на `ubuntu-latest`. +4. Проба порчи: `sha256` в `flake.nix` или `sha256sums` в PKGBUILD с подменённым + знаком — сборка красная по хешу, не по компилятору. +5. `bump-version` поднимает версию и хеш в `flake.nix` и `PKGBUILD` тем же + прогоном, что в формуле; `homebrew-formula:check`-подобный сторож сверяет + три места. + +## Где живёт правка + +`flake.nix`, `flake.lock`, `packaging/aur/PKGBUILD`, `packaging/aur/.SRCINFO`, +`scripts/release/bump-version.fscript`, новая работа в `.github/workflows/` +(по образцу `install-path.yml`), страницы установки — строки Nix и AUR в +таблице каналов. Перепечатка не нужна. diff --git a/docs/tasks/1710-asdf-and-homebrew-take-the-prebuilt-binary-and-fall-back-to-source.md b/docs/tasks/1710-asdf-and-homebrew-take-the-prebuilt-binary-and-fall-back-to-source.md new file mode 100644 index 000000000..cc9d45e85 --- /dev/null +++ b/docs/tasks/1710-asdf-and-homebrew-take-the-prebuilt-binary-and-fall-back-to-source.md @@ -0,0 +1,97 @@ +--- +номер: 1710 +заголовок: Плагин asdf качает только архив C и собирает его сам; готового двоичного под свою тройку он не ищет, а формула Homebrew не знает бутылок +статус: свободна +приоритет: P2 +исполнитель: — +ветка: — +команда: вторая +карта: Что мешает больше всего +рядом: 7959, 1098 +нужность: установка через asdf — это 2–6 минут компиляции на машине человека и отказ там, где нет `cc`; с готовым двоичным она становится скачиванием +--- + +# 1710. Плагин asdf качает только архив C и собирает его сам; готового двоичного под свою тройку он не ищет, а формула Homebrew не знает бутылок + +Решение: [ADR-0067](../adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md), +разделы 2.3 (Homebrew) и 2.4 (asdf). Делается ПОСЛЕ задачи о матрице выпуска: +качать можно только то, что выпуск уже несёт. + +## Шаги воспроизведения + +1. Что плагин качает: `grep -n 'tar.gz' packaging/asdf/bin/download` +2. Знает ли он свою тройку: `grep -c 'uname' packaging/asdf/bin/download` +3. Знает ли формула бутылки: `grep -c 'bottle' packaging/homebrew/flang.rb` +4. Сколько стоит сборка формулы на раннере macOS: + `gh run view 37302964624 --json jobs --jq '.jobs[] | select(.name=="homebrew") | .steps[] | select(.name=="Update formula") | "\(.startedAt) \(.completedAt)"'` + +## Что происходит + +``` +$ grep -n 'tar.gz' packaging/asdf/bin/download +13:archive="flang-${version}-c.tar.gz" код 0 +$ grep -c 'uname' packaging/asdf/bin/download +0 код 1 +$ grep -c 'bottle' packaging/homebrew/flang.rb +0 код 1 +$ gh run view 37302964624 --json jobs --jq '…"Update formula"…' +2026-10-05T11:40:58Z 2026-10-05T11:44:27Z код 0 +``` + +Плагин знает одно имя архива и один путь — `make` с `-Werror`. Шаг «Update +formula» (это `brew install --build-from-source`) на `macos-latest` занял 3 мин +29 с; плюс `brew install gnu-tar` и скачивание. Формула не несёт блока `bottle`, +то есть `brew` собирает у каждого. + +Версия: `flang 0.7.24`, `оболочка 9f361fce`. Прогон 5 октября 2026. + +## Что должно быть + +**asdf (обязательная половина).** `bin/download` узнаёт тройку (`uname -s`, +`uname -m`; `arm64` → `aarch64`), качает `flang-<версия>-<ось>-<арх>.tar.gz` и +`SHA256SUMS` того же выпуска, сверяет хеш и раскладывает архив; `bin/install` +ставит из раскладки. Откат на архив C и `make` — в трёх случаях, каждый назван +в выводе: у выпуска нет вложения под тройку (выпуски до матрицы и чужие +тройки); хеш не сошёлся — это ОТКАЗ, не откат; человек попросил сам, +`ASDF_FLANG_FROM_SOURCE=1`. Пробы после установки (`--version`, «Число связанных +функций», печать во все цели) остаются теми же — они спрашивают результат, а не +дорогу. README плагина перестаёт обещать `cc` и `make` всем: они нужны откату. + +**Homebrew (вторая половина — только после решения владельца).** ADR-0067, +раздел 2.3, ступенью 1 оставляет формулу на исходниках и называет бутылки +решением владельца. Если владелец принимает бутылки: `brew install +--build-bottle` + `brew bottle --root-url` в работе выпуска на двух раннерах +macOS, бутылки — вложениями выпуска КРАНА, блок `bottle do … end` в +`packaging/homebrew/flang.rb` и в сабмодуле крана, шаг «Check Homebrew tap» +сверяет и его. Без решения владельца эту половину не делать. + +## Обходной путь + +`asdf install flang <версия>` собирает из исходников, как сегодня: `cc`, `make` +и 2–6 минут. Готовый двоичный можно взять руками со страницы выпуска, когда +матрица его положит. + +## Когда задача сделана + +1. На `macos-latest` и `ubuntu-latest` `asdf install flang ` печатает строку + «скачиваю flang--<ось>-<арх>.tar.gz», проходит без вызова `make` и + укладывается в 60 с от начала до конца (против 3 мин 29 с сборки формулы на + том же раннере). +2. `ASDF_FLANG_FROM_SOURCE=1 asdf install flang ` собирает из архива C, и + прибор паритета (задача об install-parity) даёт `расхождений 0` между + двумя установками одного выпуска. +3. `asdf install flang 0.7.24` (выпуск без двоичных) печатает названную причину + отката и ставит из исходников — старые выпуски не ломаются. +4. Проба порчи: строка `SHA256SUMS` с подменённым хешем — `bin/download` отвечает + отказом, а не откатом; сторож `asdf-plugin:check` по-прежнему зелен на + четырёх файлах. +5. Если бутылки приняты: `brew install digitable-lol/tap/flang` на + `macos-latest` пишет `Pouring flang--…bottle.tar.gz`, а не `Building`. + +## Где живёт правка + +`packaging/asdf/bin/download`, `packaging/asdf/bin/install`, +`packaging/asdf/README.md` и их копии в сабмодуле `packaging/asdf-plugin` +(коммит и push в `digitable-lol/asdf-flang` — руками владельца); при бутылках — +`packaging/homebrew/flang.rb`, сабмодуль `packaging/homebrew-tap`, +`.github/workflows/release.yml`. Перепечатка не нужна. diff --git a/docs/tasks/7959-the-release-matrix-builds-four-binary-tarballs-and-one-sha256sums.md b/docs/tasks/7959-the-release-matrix-builds-four-binary-tarballs-and-one-sha256sums.md new file mode 100644 index 000000000..f03d4e0f9 --- /dev/null +++ b/docs/tasks/7959-the-release-matrix-builds-four-binary-tarballs-and-one-sha256sums.md @@ -0,0 +1,101 @@ +--- +номер: 7959 +заголовок: Выпуск несёт одно вложение — архив исходников C; готовых двоичных под четыре тройки и файла SHA256SUMS у него нет +статус: свободна +приоритет: P1 +исполнитель: — +ветка: — +команда: вторая +карта: Что мешает больше всего +рядом: 7715, 1098, 1710, 8128, 1504 +нужность: решение владельца от 5 октября 2026 — выпуск несёт готовые двоичные под Linux и macOS, как у dust; без них три канала из трёх собирают из исходников по 2–6 минут +--- + +# 7959. Выпуск несёт одно вложение — архив исходников C; готовых двоичных под четыре тройки и файла SHA256SUMS у него нет + +Решение: [ADR-0067](../adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md), +раздел 2.1 — матрица выпуска. + +## Шаги воспроизведения + +1. Спросить у GitHub вложения последнего выпуска: + `gh release view v0.7.24 --json assets --jq '.assets[] | "\(.name) \(.size)"'` +2. Посчитать работы и раннеры в работе выпуска: + `grep -n 'runs-on' .github/workflows/release.yml` +3. Поискать общий файл хешей: `grep -c 'SHA256SUMS' .github/workflows/release.yml` +4. Спросить у собранного двоичного, что он знает о себе: `bootstrap/flang --version` + +## Что происходит + +``` +$ gh release view v0.7.24 --json assets --jq '.assets[] | "\(.name) \(.size)"' +flang-0.7.24-c.tar.gz 5410663 код 0 +$ grep -n 'runs-on' .github/workflows/release.yml +74: runs-on: ubuntu-latest код 0 +$ grep -c 'SHA256SUMS' .github/workflows/release.yml +0 код 1 +$ bootstrap/flang --version +flang 0.7.24 +оболочка 9f361fce: правит строку (стрелки, слова, история, Tab), цвет digitable + код 0 +``` + +Одно вложение, одна работа на одном раннере, файла хешей нет. Двоичный называет +версию и отпечаток оболочки (sha256 файла `flang_repl.c`), но не отпечаток семени +(`scripts/seed-fingerprint`, коммит `d5a0ea47`) и не свою тройку. + +Сборка семени на раннерах, по журналам CI (снято 5 октября 2026 командой +`gh run view <прогон> --json jobs`): `ubuntu-latest`, `make -C bootstrap -j4` — +6 мин 02 с (прогон 37162267654, выпуск v0.7.24, шаг «Build bootstrap»); +`macos-latest` (arm64, 3 ядра, без `-flto`) — 2 мин 38 с (прогон 37371920145, шаг +«Build bootstrap»). На `ubuntu-24.04-arm` и `macos-15-intel` семя не собиралось ни +разу — времени нет. + +Версия: `flang 0.7.24`, `оболочка 9f361fce`. Прогон 5 октября 2026. + +## Что должно быть + +ADR-0067, раздел 2.1: четыре работы матрицы — `linux-x86_64`, `linux-aarch64`, +`macos-aarch64`, `macos-x86_64` — каждая делает `make -C bootstrap` из ОДНОГО семени +с флагами формулы и плагина (`-std=c99 -Wall -Wextra -Werror -pedantic -O2`) и +кладёт `flang-<версия>-<ось>-<арх>.tar.gz` с раскладкой установки (`bin/flang`, +`lib/libcompiler_flang.a`, `include/*.h`, `share/man/man1/flang.1`, +`share/flang/<цель>/…`, `LICENSE`, `seed-fingerprint.txt`). Пятая работа собирает +`SHA256SUMS` по пяти вложениям (четыре двоичных + архив C) и выкладывает всё +разом; хеши — только с раннера (задача 7715: у себя они не повторяются). +`workflow_dispatch` с ветки собирает четыре архива и не выкладывает ничего — +как сегодня с архивом C (шаг «Upload release archive» идёт только на теге). + +Раннеры: `ubuntu-22.04`, `ubuntu-22.04-arm` (нижняя граница glibc 2.35 — довод в +ADR), `macos-latest` с `MACOSX_DEPLOYMENT_TARGET`, `macos-15-intel`. `macos-13` +снят GitHub 4 декабря 2025 — его в матрице быть не может. + +## Обходной путь + +Три канала собирают из исходников сами: `brew install digitable-lol/tap/flang` +(сборка 3 мин 29 с на `macos-latest`, прогон 37302964624, шаг «Update formula»), +`asdf install flang 0.7.24`, клон и `make -C bootstrap -j4` (119,91 с на этой +машине, 4 потока, gcc 15.2.0, снято 5 октября 2026 `/usr/bin/time`). + +## Когда задача сделана + +1. `gh release view v --json assets --jq '.assets | length'` отвечает `6`: + четыре `flang--{linux,macos}-{x86_64,aarch64}.tar.gz`, `flang--c.tar.gz`, + `SHA256SUMS`. +2. `sha256sum -c SHA256SUMS` над скачанными вложениями — пять строк `OK`, код 0. +3. На каждом из четырёх раннеров `bin/flang --version | head -1` равен + `flang `, а вторая строка («оболочка …») совпадает на всех четырёх знак в + знак — одно семя даёт один отпечаток. +4. Проба порчи: вложение, в котором подменён один байт, краснит шаг сверки + хешей ДО выкладки; шаг, который не краснеет на подлоге, не считается. +5. Сухой прогон `workflow_dispatch` с ветки: четыре архива собраны, шаг выкладки + `skipped`. + +## Где живёт правка + +`.github/workflows/release.yml` — работа `release` делится на матрицу и работу +сборки `SHA256SUMS`; `.github/actions/release-binary/` — составное действие по +образцу `release-archive` (раскладка, повторимый `tar`, хеш); `packaging/flang.1` +и `LICENSE` едут как есть. Перепечатка не нужна. Строка семени и тройки в +`flang --version` — отдельно (ADR-0067, раздел 2.1, ступень 2): правка +`flang/src/emit/c/flang_repl.c` доезжает до двоичного только перепечаткой. diff --git a/docs/tasks/8128-the-readme-and-install-pages-carry-a-channel-table.md b/docs/tasks/8128-the-readme-and-install-pages-carry-a-channel-table.md new file mode 100644 index 000000000..f2952b4cf --- /dev/null +++ b/docs/tasks/8128-the-readme-and-install-pages-carry-a-channel-table.md @@ -0,0 +1,90 @@ +--- +номер: 8128 +заголовок: README и страницы установки не несут таблицы каналов: три пути одним списком, готовых двоичных и SHA256SUMS на них нет +статус: свободна +приоритет: P2 +исполнитель: — +ветка: — +команда: вторая +карта: Что мешает больше всего +рядом: 7959, 1098 +нужность: человек с сайта должен за десять секунд выбрать канал и проверить хеш; сегодня страница обещает «все три дают ОДИН И ТОТ ЖЕ двоичный», а путь из клона печатать не умеет +--- + +# 8128. README и страницы установки не несут таблицы каналов: три пути одним списком, готовых двоичных и SHA256SUMS на них нет + +Решение: [ADR-0067](../adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md), +раздел 2.6 — README и страницы установки. + +## Шаги воспроизведения + +1. Посчитать строки таблиц в разделе «Install» README: + `awk '/^## Install/{p=1;next} /^## /{p=0} p' README.md | grep -c '^|'` +2. Поискать на трёх страницах установки готовые двоичные и файл хешей: + `grep -c 'tar\.gz\|SHA256SUMS' README.md docs/site/install.md docs/site/install.ru.md` +3. Поставить из клона в чистый префикс и напечатать из другого каталога: + `make -C bootstrap install PREFIX=/tmp/p >/dev/null; cd /tmp/w && /tmp/p/bin/flang emit проба.flang --target c --out out-c` + +## Что происходит + +``` +$ awk '/^## Install/{p=1;next} /^## /{p=0} p' README.md | grep -c '^|' +0 код 1 +$ grep -c 'tar\.gz\|SHA256SUMS' README.md docs/site/install.md docs/site/install.ru.md +README.md:0 +docs/site/install.md:0 +docs/site/install.ru.md:0 код 1 +$ cd /tmp/w && /tmp/p/bin/flang emit проба.flang --target c --out out-c +flang emit: не найдены исходники рантайма C — они уезжают в вывод ДОСЛОВНО, и +без них печать соврала бы. … код 2 +``` + +README перечисляет три пути одним блоком кода; `docs/site/install.md` и +`install.ru.md` несут таблицу из трёх строк (Homebrew, asdf, из исходников) и +обещают: «All three give the SAME binary» / «Все три дают ОДИН И ТОТ ЖЕ двоичный +файл». Двоичный тот же, установка — нет: `make -C bootstrap install` кладёт +`bin`, `lib`, `include` и `man` (если есть), но не `share/flang/<цель>`, и +поставленный из клона `flang emit` отказывает кодом 2 на всех целях. Страница +говорит об этом только про `man`. + +Версия: `flang 0.7.24`, `оболочка 9f361fce`. Прогон 5 октября 2026. + +## Что должно быть + +ADR-0067, раздел 2.6: в README и на обеих страницах установки — таблица каналов +по образцу `bootandy/dust`: строка на канал (Homebrew, asdf, готовый двоичный, +из исходников; Nix и AUR — если приняты задачей о них), столбцы «команда», «что +ставит», «что нужно на машине», «как проверить». Строка готовых двоичных +называет четыре имени `flang-<версия>-{linux,macos}-{x86_64,aarch64}.tar.gz`, +нижнюю границу (glibc 2.35, macOS по `MACOSX_DEPLOYMENT_TARGET`) и две команды +проверки: `sha256sum -c SHA256SUMS` и, если принята аттестация, +`gh attestation verify <файл> --owner digitable-lol`. Строка «из исходников» +говорит прямо: без `man` и без печати (`emit`), пока `make install` не кладёт +`share/flang`. Обе страницы — на двух языках, одним содержанием; версия берётся +подстановкой `{{выпуск.версия}}`, как сегодня. + +## Обходной путь + +Читать `docs/site/install.md` и `release.yml` целиком; про печать из клона +узнавать первым запуском. + +## Когда задача сделана + +1. `awk '/^## Install/{p=1;next} /^## /{p=0} p' README.md | grep -c '^|'` — не + меньше 6 (шапка, разделитель, четыре канала). +2. `grep -c 'SHA256SUMS' README.md docs/site/install.md docs/site/install.ru.md` + — по 1 и больше на каждом из трёх файлов. +3. Имена вложений в таблице совпадают с именами из `SHA256SUMS` последнего + выпуска знак в знак — сверяет прибор в `scripts/site/` по образцу + `releases-page-verify.fscript`, и он зовётся из `pages.yml`. +4. `bootstrap/flang run-script jargon:check` зелен: таблица — наружу, жаргона в + ней нет. +5. Строка «из исходников» называет отсутствие печати; когда `make install` + научится класть `share/flang`, строку правит та работа, и прибор из пункта 3 + краснеет на устаревшем обещании. + +## Где живёт правка + +`README.md` (раздел «Install»), `docs/site/install.md`, `docs/site/install.ru.md`; +прибор сверки имён — `scripts/site/`, вызов — `.github/workflows/pages.yml`. +Перепечатка не нужна. diff --git a/flang/scripts/code-guard.fscript b/flang/scripts/code-guard.fscript index 02f3db820..83e6e2747 100644 --- a/flang/scripts/code-guard.fscript +++ b/flang/scripts/code-guard.fscript @@ -207,7 +207,7 @@ тотальная функция «Объявлено, не сделано» возвращает список «Отсрочка» - пример «Записей тринадцать: пять отвергнутых кодов, шесть снятых и два обещанных» + пример «Записей пятнадцать: пять отвергнутых кодов, шесть снятых и четыре обещанных» ожидается [ (запись «Отсрочка» с «код» равным "FLANG_NODE_DEAD" и «род» равным "отвергнут" и «где» равным [ "docs/flang/concurrency/DISTRIBUTED.md"] и «почему» равным [ @@ -295,7 +295,18 @@ "целиком, и ни один пример корпуса «вне среза» не отвечает — значит и код ни разу не срабатывал. В ", "исходниках он жил только в комментарии flang/self/interpret.flang, обещавшем, что код «остался заведённым и ", "проверяемым»; комментарии ушли в 0.7.24, и обещание осталось без кода. Появится вместе с формой вне среза — ", - "тогда запись снимут"]) + "тогда запись снимут"]), + (запись «Отсрочка» с «код» равным "FLANG_TARGET" и «род» равным "обещан" и «где» равным [ + "docs/adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md"] и «почему» равным [ + "не код отказа, а ключ препроцессора из решения ADR-0067 §4: матрица выпуска передаёт тройку в двоичный ", + "как -DFLANG_TARGET, и третья строка --version печатает её. Решение предложено, работа 7959 не начата, ", + "release.yml матрицы не знает. Появится в flang/src/emit/c/flang_repl.c — снять запись"]), + (запись «Отсрочка» с «код» равным "FLANG_FROM_SOURCE" и «род» равным "обещан" и «где» равным [ + "docs/adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md", + "docs/tasks/1710-asdf-and-homebrew-take-the-prebuilt-binary-and-fall-back-to-source.md"] и «почему» равным [ + "не код отказа, а хвост переменной среды ASDF_FLANG_FROM_SOURCE из решения ADR-0067 §6: человек просит плагин ", + "asdf собрать из архива C, а не взять готовый двоичный. Плагин сегодня собирает из архива всегда и переменной ", + "не читает; работа 1710 не начата. Появится в packaging/asdf — снять запись"]) ] [ (запись «Отсрочка» с «код» равным "FLANG_NODE_DEAD" и «род» равным "отвергнут" и «где» равным [ @@ -384,15 +395,27 @@ "целиком, и ни один пример корпуса «вне среза» не отвечает — значит и код ни разу не срабатывал. В ", "исходниках он жил только в комментарии flang/self/interpret.flang, обещавшем, что код «остался заведённым и ", "проверяемым»; комментарии ушли в 0.7.24, и обещание осталось без кода. Появится вместе с формой вне среза — ", - "тогда запись снимут"]) + "тогда запись снимут"]), + (запись «Отсрочка» с «код» равным "FLANG_TARGET" и «род» равным "обещан" и «где» равным [ + "docs/adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md"] и «почему» равным [ + "не код отказа, а ключ препроцессора из решения ADR-0067 §4: матрица выпуска передаёт тройку в двоичный ", + "как -DFLANG_TARGET, и третья строка --version печатает её. Решение предложено, работа 7959 не начата, ", + "release.yml матрицы не знает. Появится в flang/src/emit/c/flang_repl.c — снять запись"]), + (запись «Отсрочка» с «код» равным "FLANG_FROM_SOURCE" и «род» равным "обещан" и «где» равным [ + "docs/adr/0067-the-release-ships-binaries-for-four-triples-from-one-seed.md", + "docs/tasks/1710-asdf-and-homebrew-take-the-prebuilt-binary-and-fall-back-to-source.md"] и «почему» равным [ + "не код отказа, а хвост переменной среды ASDF_FLANG_FROM_SOURCE из решения ADR-0067 §6: человек просит плагин ", + "asdf собрать из архива C, а не взять готовый двоичный. Плагин сегодня собирает из архива всегда и переменной ", + "не читает; работа 1710 не начата. Появится в packaging/asdf — снять запись"]) ] тотальная функция «Отсроченные имена» возвращает список строки - пример «Тринадцать имён» + пример «Пятнадцать имён» ожидается ["FLANG_NODE_DEAD", "FLANG_CACHE", "FLANG_UNCOVERED_OUTCOME", "FLANG_TOCHKA_DVOICHNYM", "FLANG_SKIP_RELEASE_CHECK", "FLANG_ZAMER", "FLANG_PROBE_MAX_DEPTH", "FLANG_CHARGE_OUT", "FLANG_MESSAGE_DIR", - "FLANG_WASM_PAMYAT", "FLANG_SLOVO_PUSTOTA", "FLANG_IO_UNSUPPORTED", "FLANG_SELF_EVAL_UNSUPPORTED"] + "FLANG_WASM_PAMYAT", "FLANG_SLOVO_PUSTOTA", "FLANG_IO_UNSUPPORTED", "FLANG_SELF_EVAL_UNSUPPORTED", + "FLANG_TARGET", "FLANG_FROM_SOURCE"] отобразить («Объявлено, не сделано») как отсрочка → (отсрочка.«код») тотальная функция «Файл места» diff --git a/scripts/ledgers/file-name-words.txt b/scripts/ledgers/file-name-words.txt index f97ddeec1..f2cb43ac5 100644 --- a/scripts/ledgers/file-name-words.txt +++ b/scripts/ledgers/file-name-words.txt @@ -1986,3 +1986,16 @@ oao particular s wanted +aur +binaries +channel +flake +matrix +nix +parity +pkgbuild +prebuilt +sha256sums +ships +tarballs +triples