ревью: детерминированный гейт 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:
Executable
+86
@@ -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 '```'
|
||||
Reference in New Issue
Block a user