ревью: детерминированный гейт task gate и карта проекта для архитектурного прохода

scripts/gate.sh гонит всё, у чего есть объективный оракул (build, vet, lint,
gofmt, тесты, повтор на флаки, -race, покрытие изменённых строк, миграции,
ER-схема по диффу, gitleaks, govulncheck), не останавливаясь на первом отказе:
ревью нужна полная картина. Пропущенный шаг попадает в сводку — молча
пропущенная проверка даёт ложное ощущение проверенности.

scripts/diff-coverage.py считает покрытие именно изменённых строк: общий
процент по пакету для ревью бесполезен.

scripts/review-context.sh собирает вход, которого нет в диффе — пакеты с
назначением, граф внутренних зависимостей, публичную поверхность и инвентарь
концепций. Агент, видящий только дифф, не знает словаря проекта и потому не
может судить об архитектуре.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
av
2026-07-23 18:17:28 +03:00
co-authored by Claude Opus 4.8
parent 1d6f8f3449
commit 6792f7082a
4 changed files with 355 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# Вход для архитектурного прохода ревью: то, чего нет в диффе.
#
# Агент, видящий только `git diff`, физически не может судить об архитектуре —
# он не знает, какие понятия в проекте уже есть и как они называются. Скрипт
# собирает дерево пакетов с назначением, публичную поверхность, граф внутренних
# зависимостей и инвентарь существующих концепций.
#
# Использование: scripts/review-context.sh [> tmp/review-context.md]
set -eu
MOD="$(awk '/^module /{print $2}' go.mod)"
PKGS="$(go list ./... | grep -v '/migrations$')"
echo "# Контекст проекта для архитектурного ревью"
echo
echo "Сгенерировано \`scripts/review-context.sh\`. Модуль: \`$MOD\`."
echo
echo "## Пакеты и назначение"
echo
echo '```'
go list -f '{{.ImportPath}}|{{.Doc}}' ./... | sed "s|^$MOD/||" |
awk -F'|' '{printf "%-34s %s\n", $1, ($2 == "" ? "— (нет doc-комментария пакета)" : $2)}'
echo '```'
echo
echo "## Граф внутренних зависимостей"
echo
echo "Только импорты внутри модуля. Стрелка A -> B означает «A зависит от B»."
echo
echo '```'
for p in $PKGS; do
deps="$(go list -f '{{range .Imports}}{{.}}
{{end}}' "$p" | grep "^$MOD/" | sed "s|^$MOD/||" | sort -u | tr '\n' ' ')"
[ -n "$deps" ] && echo "${p#"$MOD"/} -> $deps"
done
echo '```'
echo
echo "## Публичная поверхность пакетов"
echo
echo "Экспортированные типы, интерфейсы и функции — то, чем пакеты договариваются."
echo
for p in $PKGS; do
short="${p#"$MOD"/}"
body="$(go doc -short "$p" 2>/dev/null | grep -v '^$' || true)"
[ -z "$body" ] && continue
echo "### $short"
echo '```go'
echo "$body"
echo '```'
echo
done
echo "## Инвентарь концепций"
echo
echo "Как в проекте уже называются вещи. Новое понятие вводим, только убедившись,"
echo "что его нельзя выразить существующими."
echo
echo "### Доменные ошибки (sentinel)"
echo '```'
grep -rhn "^var Err[A-Za-z]* = errors.New" --include='*.go' internal/ |
sed 's/^[0-9]*://' | sort -u
echo '```'
echo
echo "### Состояния загрузки"
echo '```'
grep -rh "State[A-Za-z]* *State *= " --include='*.go' internal/store/ | sed 's/^\s*//' | sort -u
echo '```'
echo
echo "### Секции конфигурации"
echo '```'
grep -rh 'toml:"' --include='*.go' internal/config/ | sed 's/^\s*//' | sort -u
echo '```'
echo
echo "### Публичные команды воркера (вызываются транспортами)"
echo '```'
grep -rhn "^func (w \*Worker) [A-Z]" --include='*.go' internal/worker/ | sed 's/^[0-9]*://' | sort -u
echo '```'
echo
echo "### Capabilities OpenSpec"
echo '```'
ls openspec/specs/
echo '```'