opencode-config/docs/decisions/079-pr-182-adr-numbering-collision.md
Sergey 0bf97cf1c5
fix(scripts): compute next ADR as max+1 not count+1 in scaffold (#182)
* fix(scripts): compute next ADR as max+1 not count+1 in scaffold

* docs(handoff): add handoff and ADR-079 for ADR numbering fix

* docs(handoff): set PR number

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-31 22:13:30 +03:00

2.1 KiB
Raw Permalink Blame History

ADR-079: ADR numbering = max(existing)+1, not count+1

Статус

Accepted (2026-07-31, PR#182)

Контекст

scaffold-handoff.sh вычислял номер следующего ADR как ls docs/decisions | grep -E '^[0-9]{3}-' | wc -l + 1. Это привело к коллизии: PR#174 и PR#175 оба создали ADR-073 (два файла 073-pr-174-*.md и 073-pr-175-*.md), так как оба запуска посчитали одинаковое количество файлов. Алгоритм count+1 неустойчив к гонкам, ручному добавлению ADR и «дырам» в нумерации (удалённые файлы оставляют пропуски, счётчик отстаёт от max).

Решение

Заменить count+1 на max(existing)+1: ls | grep -E '^[0-9]{3}-' | cut -c1-3 | sort -n | tail -n1 берёт максимальный существующий номер, +1 даёт следующий. Дополнительно:

  • 10#${MAX_N:-0} — base-10 forcing (номера вида 078 невалидны в bash octal arithmetic).
  • || true на grep pipeline — нейтрализует exit 1 при пустой директории (set -euo pipefail).
  • Guard loop — если вычисленный NN уже занят (residual race: файл создан между max-read и write), инкремент до свободного слота.

Альтернативы

  • Atomic file lock (flock) — отвергнут: избыточно для git-репозитория, где commits серийные; guard loop покрывает residual window.
  • Проверка только существования файла перед записью (без max+1) — отвергнута: не решает «дыры» в нумерации и не дает детерминированный следующий номер.
  • Переименование существующих ADR-073 — вне scope (ломает ссылки в memory/handoff/AGENTS.md, issue #176 явно исключает).