Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .flangrc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ script.changelog:page = node scripts/site/build-changelog-page.mjs
script.changelog:page:check = node scripts/site/build-changelog-page.mjs --check
script.releases:page = bootstrap/flang io scripts/site/releases-page.fscript --max-steps 80000000 --на-веру
script.releases:page:check = bootstrap/flang io scripts/site/releases-page-verify.fscript --max-steps 80000000 --на-веру
script.registry:page = bootstrap/flang io scripts/site/registry-page.fscript --plan 'Напечатать страницу реестра'
script.registry:publish = bootstrap/flang io scripts/site/registry-page.fscript --plan 'Выложить ведомость'
script.reprint = sh scripts/bootstrap-reprint.sh
script.reprint:check = sh scripts/bootstrap-reprint.sh --check
script.bootstrap-point:check = bootstrap/flang io scripts/seed/bootstrap-point-by-binary.fscript --timeout 2400000 --на-веру
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ on:
- 'scripts/site/changelog.flang'
- 'scripts/site/releases.flang'
- 'scripts/site/releases-page.fscript'
- 'scripts/site/registry-page.fscript'
- 'scripts/registry-example/**'
- 'flang/stdlib/registry.flang'
- '.github/workflows/pages.yml'
# Подсветка блоков кода красит НАСТОЯЩИМ лексером языка, а он живёт в
# двоичном компиляторе: правка точки раскрутки или двери к двоичному
Expand Down Expand Up @@ -135,6 +138,53 @@ jobs:
- name: Rebuild releases page
run: LC_ALL=C.UTF-8 bootstrap/flang io scripts/site/releases-page.fscript --на-веру --max-steps 80000000

# ПО ТОЙ ЖЕ ПРИЧИНЕ — И РЯДОМ С ЕЩЁ ОДНОЙ. Страница реестра печатается из
# ведомости `scripts/registry-example/registry.list`, и между правкой
# ведомости и перепечаткой она отстаёт; здесь она печатается заново, и
# опубликованное всегда свежее. Дерево при этом не правится.
#
# ВТОРОЕ, ЧТО ДЕЛАЕТ ЭТОТ ШАГ, И ОНО ГЛАВНОЕ: прогон пересчитывает sha256
# каждого адреса ведомости и сличает с полем «отпечаток». Разошёлся знак —
# страница не печатается, прогон отвечает кодом 1, и сборка сайта краснеет
# ЗДЕСЬ, с именем записи и обоими отпечатками. До этого шага реестр не
# звала ни одна работа CI, и отпечатки примера гнили молча (задача 4909).
- name: Rebuild registry page
run: LC_ALL=C.UTF-8 bootstrap/flang run-script registry:page

# ПРОБА: сверка отпечатков обязана покраснеть на подкрученном знаке.
# Иначе зелёный шаг выше неотличим от выключенного — ровно та беда, из-за
# которой отпечатки и прогнили. Портится ОДИН знак в ОДНОМ отпечатке
# ведомости; требуется код не 0 И имя подложенной записи в выводе
# (покраснеть по чужой причине — не довод); ведомость возвращается и
# сравнивается с копией побайтово.
- name: Probe registry fingerprint
run: |
vedomost=scripts/registry-example/registry.list
cp "$vedomost" "$RUNNER_TEMP/registry.list"
sed -i 's/^\(Списки | 1\.4\.2 | \)./\1X/' "$vedomost"
if cmp -s "$vedomost" "$RUNNER_TEMP/registry.list"; then
echo "ПОДЛОГ НЕ СОБРАЛСЯ: $vedomost не изменилась" >&2
exit 1
fi
if LC_ALL=C.UTF-8 bootstrap/flang run-script registry:page > "$RUNNER_TEMP/probe.out" 2>&1; then
cp "$RUNNER_TEMP/registry.list" "$vedomost"
echo "СВЕРКА ПРОМОЛЧАЛА: подкрученный отпечаток прошёл" >&2
exit 1
fi
cp "$RUNNER_TEMP/registry.list" "$vedomost"
if ! grep -F 'FLANG_REESTR_OTPECHATOK' "$RUNNER_TEMP/probe.out"; then
echo "ПОКРАСНЕЛО НЕ НА ОТПЕЧАТКЕ:" >&2
tail -20 "$RUNNER_TEMP/probe.out" >&2
exit 1
fi
if ! grep -F 'Списки 1.4.2' "$RUNNER_TEMP/probe.out"; then
echo "ОТКАЗ НЕ НАЗВАЛ ПОДЛОЖЕННУЮ ЗАПИСЬ:" >&2
tail -20 "$RUNNER_TEMP/probe.out" >&2
exit 1
fi
cmp "$vedomost" "$RUNNER_TEMP/registry.list"
LC_ALL=C.UTF-8 bootstrap/flang run-script registry:page

# Отдельным шагом до сборки: если ссылки битые, видно сразу и по имени,
# а не среди вывода сборки.
- name: Check links
Expand Down Expand Up @@ -175,6 +225,17 @@ jobs:
if: github.event_name != 'pull_request'
run: node docs/site/build.mjs

# ВЕДОМОСТЬ РАЗДАЁТСЯ ФАЙЛОМ, А НЕ КАРТИНКОЙ НА СТРАНИЦЕ. Решение ADR-0059:
# реестр — строчный файл, раздаваемый обычным HTTP, и отвечает он адресом.
# Шаг кладёт ведомость в корень собранного сайта под именем `registry.list`
# — тот самый адрес, который называет страница и который берёт поручение
# «Запросить». Стоит ПОСЛЕ сборки: `build.mjs` вычищает `docs/site/out`
# целиком, и положенное до него не доехало бы. Сличение отпечатков идёт и
# здесь: выложить ведомость с гнилым отпечатком нельзя.
- name: Publish the registry ledger
if: github.event_name != 'pull_request'
run: LC_ALL=C.UTF-8 bootstrap/flang run-script registry:publish

- if: github.event_name != 'pull_request'
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0

Expand Down
4 changes: 2 additions & 2 deletions docs/javascript-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ HTML, CSS, awk, Erlang, Java, C#, Elixir, Go, Rust, Lua, vimscript, Ruby —
долг вне JavaScript — **97 файлов, 18 427 строк при потолке 63**: храповик
красен, разбор — задачи 4838 и 7405). Там же названы 569 строк
JavaScript, лежащих ВНУТРИ файлов `.html`: счёт по именам файлов их не видит, и
22 660 строк этой описи — нижняя оценка.
<!-- СНЯТО 2026-10-04 строк-в *.js,*.mjs = 22660 (задачи 0049 и 5821: сняты flang/scripts/word-occupancy.mjs, scripts/seed/seed-freshness.sh и scripts/guards/version-derivations-guard.sh — у каждого двойник на flang доказан прогоном; до них 22965, снято 2026-10-04) (задача 0037: охват проверки английской пары распространён на всю карту и назван числом — 48 строк в docs/site/build.mjs и docs/site/sitemap.mjs; до неё 22917, снято 2026-09-17) (задача 4413: flang/scripts/proof-ledger.mjs и word-guard.mjs сняты — свод корпуса считает двойник на flang; до них 51 файл и 24 386 строк, снято 2026-09-17) (задача 1416: четырнадцать объявлений ярлыков заведены в скриптах и зов «Сбора» — в хуке; до них 24382, снято 2026-09-17) -->
22 665 строк этой описи — нижняя оценка.
<!-- СНЯТО 2026-10-04 строк-в *.js,*.mjs = 22665 (задача 4909: страница реестра встала в карту сайта — 5 строк в docs/site/sitemap.mjs; до неё 22660, снято 2026-10-04) (задачи 0049 и 5821: сняты flang/scripts/word-occupancy.mjs, scripts/seed/seed-freshness.sh и scripts/guards/version-derivations-guard.sh — у каждого двойник на flang доказан прогоном; до них 22965, снято 2026-10-04) (задача 0037: охват проверки английской пары распространён на всю карту и назван числом — 48 строк в docs/site/build.mjs и docs/site/sitemap.mjs; до неё 22917, снято 2026-09-17) (задача 4413: flang/scripts/proof-ledger.mjs и word-guard.mjs сняты — свод корпуса считает двойник на flang; до них 51 файл и 24 386 строк, снято 2026-09-17) (задача 1416: четырнадцать объявлений ярлыков заведены в скриптах и зов «Сбора» — в хуке; до них 24382, снято 2026-09-17) -->
(29 августа здесь стояло 25 527: за два дня прибавилось 2 313 строк. Ещё 64
строки прибавились 2 сентября: `scripts/latin-collision-guard.mjs` сравнивает
теперь ПРОСЬБЫ печати, а не объявленные имена, и довод к этому записан там же.)
Expand Down
10 changes: 6 additions & 4 deletions docs/site/packages.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Packages

A flang package is **one file** that holds a library together with everything
it imports. There is no registry and no package cache. To publish a package,
commit the file to git; to use it, put the file next to your program and write
one import line. Building on another machine needs only your program and the
package file, and never touches the network.
it imports. There is no package cache, and the registry is a
[ledger of names](registry.html), not a store of code: it has no command of the
binary and answers with an address. To publish a package, commit the file to
git; to use it, put the file next to your program and write one import line.
Building on another machine needs only your program and the package file, and
never touches the network.

Two commands of the `flang` binary do the work: `flang package` builds a
package, `flang lock` writes a lock file for a whole program. Both have
Expand Down
9 changes: 5 additions & 4 deletions docs/site/packages.ru.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Пакеты

Пакет flang — **один файл**, в котором лежит библиотека вместе со всем, что она
импортирует. Реестра и кеша пакетов нет. Чтобы опубликовать пакет, закоммитьте
файл в git; чтобы им пользоваться, положите файл рядом с программой и напишите
одну строку импорта. Для сборки на другой машине нужны только ваша программа и
файл пакета, в сеть сборка не ходит никогда.
импортирует. Кеша пакетов нет, а реестр — [ведомость имён](registry.html), а не
склад кода: команды двоичного у него нет, он отвечает адресом. Чтобы
опубликовать пакет, закоммитьте файл в git; чтобы им пользоваться, положите файл
рядом с программой и напишите одну строку импорта. Для сборки на другой машине
нужны только ваша программа и файл пакета, в сеть сборка не ходит никогда.

Работают две команды двоичного `flang`: `flang package` собирает пакет,
`flang lock` пишет lock-файл для всей программы. У обеих есть `--help`. Примеры
Expand Down
77 changes: 77 additions & 0 deletions docs/site/registry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# The package registry

The flang registry is a **ledger of names**, not a store of code. The ledger is
a line-based file: five fields per line separated by «|», and nothing else. Asked
which version of a package will do, the registry answers with an **address**
where the package lies, not with the package; a name gets a version here, in the
ledger, and nowhere else; the language gains no new word for any of it. No
server, no database and no accounts are needed — and by decision there are none.
The whole argument:
[ADR-0059](../adr/0059-the-registry-is-a-ledger-of-names-not-a-store-of-code.md).

## The ledger is a file at a stable address

```
https://digitable-lol.github.io/flang/registry.list
```

It is a plain file served over HTTP. A flang program fetches it with the order
the language already has — «Запросить»:

```
вариант «Запросить» с способ равным "GET"
и адрес равным "https://digitable-lol.github.io/flang/registry.list"
и тело равным ""
```

What the site serves is a copy of the ledger in the tree,
[`scripts/registry-example/registry.list`](../../scripts/registry-example/registry.list),
byte for byte — put there by the same build that prints this page.

## The five fields

| field | what is in it |
|---|---|
| name | the package name — what stands in `использует` |
| version | three numbers: major, minor, patch |
| fingerprint | `sha256` of the package file |
| address | where the package file lies |
| needs | what the package requires of other names; empty means nothing |

A need reads `name: range`, needs are separated by semicolons. There are four
ranges: `любая`, `ровно 1.2.3`, `не ниже 1.2.3`, `в пределах 1.x`. Parsing the
ledger and choosing a version are written and proved in
[`flang/stdlib/registry.flang`](../../flang/stdlib/registry.flang); the choice is
made by running a plan, not by a command of the binary.

## The records as they stand

The table below is printed **from the ledger** by
`flang run-script registry:page`; it is not edited by hand — an edit is lost at
the next printing.

| name | version | fingerprint | address | needs |
|---|---|---|---|---|
| Логика | 1.0.0 | `1dc6da94a777a731150d896e28d9b20ce0afd6ca876b0cafe1c0d0d3d0b4c864` | `registry-example/logic-1.0.0.flang-package` | |
| Логика | 1.2.0 | `b2bda19546f5cbb2b7642a80f54458197bca3dfde517983356080a11c62870d2` | `registry-example/logic-1.2.0.flang-package` | |
| Логика | 2.0.0 | `5374735fb59ebaf5e374ffa1e4a985a8b66616f35a45f4cd35244697ed91c965` | `registry-example/logic-2.0.0.flang-package` | |
| Списки | 1.4.2 | `802d716b62ea8918ded9cdda7ed2fd04c16aa97da4d519381e3c98e4e3f5ccc9` | `registry-example/lists-1.4.2.flang-package` | Логика: не ниже 1.0.0 |
| Множество строк | 1.0.0 | `cf3a1697ccc1e7c2fa4fd72b3210ad5372590c0844f13e07119fa290a1f69931` | `registry-example/sets-1.0.0.flang-package` | Логика: не ниже 1.0.0 |
| Множество строк | 1.1.0 | `a9a776e153d9789c7e29f8c66ad92df36a834f21630c6388b41ebd4f8d2effc2` | `registry-example/sets-1.1.0.flang-package` | Списки: в пределах 1.x; Логика: в пределах 1.x |
| Опциональное значение | 0.9.0 | `17eac86ce77be366094d22be0f537d4bab5bb00958fb41df3bd7353060957c7d` | `registry-example/optional-0.9.0.flang-package` | Логика: ровно 2.0.0 |

Records in the ledger: 7.

## The fingerprint is checked against the file as the page is printed

The fingerprint is the only thing trust in someone else's package rests on, and
it rots silently. So the same run that prints the table recomputes the `sha256`
of every address and compares it with the fingerprint field. One character apart
and the page is not printed at all: the run exits with 1 and
`FLANG_REESTR_OTPECHATOK`, names the record, both fingerprints and the address,
and the site build goes red on it instead of reaching the reader.

The check is not a precaution: the fingerprints of the example ledger did part
from the files once, and there was nobody to see it — no CI job called the
registry at all (task
[4909](../tasks/4909-the-registry-resolution-rule-has-no-guard-and-example-fingerprints-rotted.md)).
Loading
Loading