openspec: упразднена спека toolchain

- Инструментарий проекта спеками не нормируется: capability toolchain удалена,
  норму шага сверки версий Go держат его проверки в scripts.
- Перечень capability в архитектуре и ревью сокращён до четырёх, решение
  ADR-2026-08-12-spec-norms-build-toolchain помечено устаревшим.
This commit is contained in:
av
2026-08-13 16:36:22 +03:00
parent 6994feec55
commit 26256cdb06
7 changed files with 31 additions and 267 deletions
@@ -2,6 +2,9 @@
- **Дата:** 2026-08-12
- **Источник:** [openspec/changes/archive/2026-08-12-go-1-26-upgrade/design.md](../../openspec/changes/archive/2026-08-12-go-1-26-upgrade/design.md), раздел `Decisions`, Решение 2
- **Статус:** устарело — 2026-08-13 владелец решил обратное: инструментарию в
спеках не место. Capability `toolchain` упразднена, замены у неё нет, норму
шага держат его проверки в `scripts/check_go_version_test.go`
## Решение
@@ -10,8 +13,9 @@
собирают. Потребитель у неё другой: тот, кто собирает.
Требование о согласованности объявленной версии Go живёт нормой в
[openspec/specs/toolchain/spec.md](../../openspec/specs/toolchain/spec.md), а не
прозой в памятке.
`openspec/specs/toolchain/spec.md`, а не прозой в памятке. *Уточнено 2026-08-13:
файла по этому адресу больше нет, ссылка снята — capability упразднена, см.
статус записи.*
## Почему
+1 -1
View File
@@ -39,7 +39,7 @@
| 2026-08-12 | [Сессия живёт семь суток и не продлевает саму себя](ADR-2026-08-12-session-without-refresh.md) | |
| 2026-08-12 | [Кого пускать в сервис, решает правило провайдера, а не сервис](ADR-2026-08-12-access-delegated-to-provider.md) | |
| 2026-08-12 | [Код провайдера меняется на сессию вызовом собственного адреса хранилища внутри процесса](ADR-2026-08-12-oidc-exchange-via-own-route.md) | |
| 2026-08-12 | [Спекой нормируется и инструмент сборки, а не только поведение сервиса](ADR-2026-08-12-spec-norms-build-toolchain.md) | |
| 2026-08-12 | [Спекой нормируется и инструмент сборки, а не только поведение сервиса](ADR-2026-08-12-spec-norms-build-toolchain.md) | устарело |
| 2026-08-12 | [Объявленную версию Go шаг гейта читает из репозитория, а не спрашивает у инструмента](ADR-2026-08-12-version-read-from-repo-not-from-tool.md) | |
| 2026-08-12 | [Ссылка на файл открыта знанием записи, а защищает её отсутствие имени в журнале](ADR-2026-08-12-file-link-open-but-not-logged.md) | заменено на [ADR-2026-08-12-protected-file-behind-session](ADR-2026-08-12-protected-file-behind-session.md) |
| 2026-08-12 | [Каталог данных задаётся одним ключом `[storage] data_dir`](ADR-2026-08-12-single-data-dir-config-key.md) | |
+6 -8
View File
@@ -8,9 +8,11 @@
[passport.md](passport.md) и в [tasks/BACKLOG.md](../tasks/BACKLOG.md); что из
этого ещё не решено — в разделе «Открытые вопросы».
Заведены пять capability. Четыре первые нормируют **поведение сервиса** для его
потребителей; пятая — исключение из первого абзаца: она нормирует не сервис, а
инструмент, которым его собирают, и потребитель у неё другой — тот, кто собирает.
Заведены четыре capability, и все нормируют **поведение сервиса** для его
потребителей. Инструмент, которым сервис собирают, спеками не нормируется вовсе:
у набора проверок и сборки другой потребитель — тот, кто собирает, — и решением
от 2026-08-13 его нормы живут в самих шагах, их проверках и
[conventions/go-linters.md](conventions/go-linters.md).
- [intake](../openspec/specs/intake/spec.md) — **только приём по HTTP**: приём и
опрос за сессией, имя отправителя не доходит ни до хранилища, ни до журнала,
@@ -30,11 +32,7 @@
его дальше: вход через внешнего провайдера OIDC, чем предъявляется сессия, что
её прекращает и какие адреса остаются открытыми. Задача `oidc-login`
2026-08-12. Разграничения записей по владельцу здесь нет: всякий вошедший
видит всё, что видел прежде аноним;
- [toolchain](../openspec/specs/toolchain/spec.md) — каким инструментом и какой
его версии собирается сервис: одно число версии Go во всех местах, где она
названа, и шаг гейта, который это сверяет. Задача `go-1-26-upgrade`
2026-08-12.
видит всё, что видел прежде аноним.
Поведение прочих узлов, включая приём из Telegram, по-прежнему живёт только в
коде. Задача, которая его трогает, дописывает спеку своей capability.
+7 -7
View File
@@ -36,12 +36,12 @@ Go-проект как есть. Своё здесь — перечень пра
- **настройка конвейера ревью, вопросы по темам и журнал дефектов** —
[../review.md](../review.md). Перечень ниже говорит этим вопросам, чего
спрашивать уже не нужно;
- **поведение сервиса** — нормативные спеки `openspec/specs/`. У шага сверки
версий Go поведение нормировано отдельно, спекой
[toolchain](../../openspec/specs/toolchain/spec.md): это единственная проверка
проекта, у которой есть своя capability, и потому единственная, чьи сценарии
проверяются построчно (`scripts/check_go_version_test.go`). Второй самодельный
шаг — `migrations` — нормы не имеет: он проверен мутацией на трёх исходах
- **поведение сервиса** — нормативные спеки `openspec/specs/`. Шаги набора
проверок туда не входят: инструментарий спеками не нормируется, и спека
`toolchain`, заведённая под шаг сверки версий Go, упразднена 2026-08-13. Норму
этого шага держат его собственные проверки — двадцать сценариев в
`scripts/check_go_version_test.go`, и другого дома у неё нет. Второй самодельный
шаг — `migrations` — не проверен и ими: он прогнан мутацией на трёх исходах
(переписанный шаг, пустой каталог, чистое дерево), но регрессионных проверок у
него нет, и дрейф его собственного шаблона имени никто не поймает. Владелец
решил 2026-08-13 оставить это как есть: проверка над проверкой даёт много
@@ -147,7 +147,7 @@ Go-проект как есть. Своё здесь — перечень пра
| Правило | Где механизировано |
| --- | --- |
| Проверка судит ответ по готовому ответу (`Result()`), а не по живой карте заголовков обработчика | `.golangci.yml``forbidigo` с `analyze-types`, находки только в `*_test.go`. Судит по типу приёмника (`httptest.ResponseRecorder`), поэтому ловит любую форму: цепочкой, через переменную, по индексу карты, обходом, полем `HeaderMap`. Остаётся ревью проверка, идущая мимо recorder — через свой `http.ResponseWriter` |
| Каждый сценарий нормы шага сверки версий проверен мутацией, а не памятью | `scripts/check_go_version_test.go` — 20 сценариев спеки `toolchain` плюс два свойства самого шага: исход не зависит от установленного `go`, и шаг не зовёт ни `go`, ни `docker`, ни сеть |
| Каждый сценарий нормы шага сверки версий проверен мутацией, а не памятью | `scripts/check_go_version_test.go` — 20 сценариев шага плюс два его свойства: исход не зависит от установленного `go`, и шаг не зовёт ни `go`, ни `docker`, ни сеть |
| Форма утверждения в проверках: «ожидалось» и «получено» не перепутаны местами, отказ судится `NoError`, а не `Nil`, `require` не зовут из горутины | `.golangci.yml``testifylint` |
| Одновременный доступ проверен детектором, а не чтением кода | `Taskfile.yml` → шаг `tests` (`go test -race ./...`). Общее у воркеров — счётчики метрик, логгер и клиент бота; захват задачи в гонку не входит, он по построению её не даёт (одно состояние на воркер) — см. «Типовые ложноположительные» в [../review.md](../review.md). Что делает шаг без компилятора C и каким кодом краснеет — [CLAUDE.md](../../CLAUDE.md), «Гейт» |
| Строчное подавление называет линтер и причину, а протухшее краснеет | `.golangci.yml``nolintlint` (`require-explanation`, `require-specific`, `allow-unused: false`) |
+5 -3
View File
@@ -145,8 +145,8 @@
`createTranscribeJob` — сегодня через него идут оба входа
([architecture.md](architecture.md), «Единые точки проекта»).
- `architecture`: не поехало ли поведение в `architecture.md` вместо спеки —
заведены пять capability (`intake`, `pipeline`, `storage`, `access`,
`toolchain`), и первые две описаны частично. Поведение прочих узлов, включая
заведены четыре capability (`intake`, `pipeline`, `storage`, `access`), и
первые две описаны частично. Поведение прочих узлов, включая
приём из Telegram, живёт в обзоре под маркерами долга, а соблазн дописать туда
ещё — самый большой.
- `conventions`: новая колонка правится во всех четырёх местах репозитория
@@ -472,7 +472,9 @@ API и имя не откатываются обратной правкой по
(`scripts/check-go-version.sh`). Сверяются четыре места, а не два, — `go.mod`,
`Dockerfile`, `CLAUDE.md`, `README.md`: в этом дефекте трое из четырёх врали
согласованно, и парная сверка не увидела бы документ, разошедшийся с
согласованным кодом. Норма — capability `toolchain`.
согласованным кодом. Норму шага держат его собственные проверки
(`scripts/check_go_version_test.go`): спека `toolchain`, бывшая его домом,
упразднена 2026-08-13 — инструментарий спеками не нормируется.
## 2026-08-11 — норма требовала от сервиса недостижимого [пойман ревью]