From 7b37e696ca87c3b1956f0fcca9431264c715e056 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Thu, 8 Oct 2026 23:42:04 +0400 Subject: [PATCH] =?UTF-8?q?fix(dev):=20=D1=81=D0=BD=D0=B8=D0=BC=D0=BE?= =?UTF-8?q?=D0=BA=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D0=BD=D1=82=D1=83?= =?UTF-8?q?=D1=80=D0=B0=20=D0=B2=D1=8B=D1=80=D0=B5=D0=B7=D0=B0=D0=B5=D1=82?= =?UTF-8?q?=20=D0=B0=D1=80=D1=82=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D1=8B=20?= =?UTF-8?q?=D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0=20=D0=BD=D0=B0=20=D0=BB?= =?UTF-8?q?=D1=8E=D0=B1=D0=BE=D0=B9=20=D0=B3=D0=BB=D1=83=D0=B1=D0=B8=D0=BD?= =?UTF-8?q?=D0=B5=20(#75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Фронт перенесён в arm-core/web/ из arm-web вместе со своими .claude/, CLAUDE.md, openspec/config.yaml, docs/superpowers/ и .codegraph/. Скрипт удалял их только в корне, поэтому в arm-core их пришлось вычищать вручную (arm-core #73). - prepare-contour-snapshot.sh: удаление и проверка через find по всему дереву; опустевшие docs/ убираются; Dockerfile/.dockerignore — по-прежнему только корень - scripts/test_prepare_contour_snapshot.sh + make test-snapshot (входит в make check): синтетический arm-core с артефактами в корне и в web/ - dev/contour-transfer-guide.md §1–§3 и текст SNAPSHOT.md Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019qoydUVv8g1qHxc123u2RR --- Makefile | 8 +++- dev/contour-transfer-guide.md | 16 ++++--- scripts/prepare-contour-snapshot.sh | 18 +++++--- scripts/test_prepare_contour_snapshot.sh | 53 ++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 13 deletions(-) create mode 100755 scripts/test_prepare_contour_snapshot.sh diff --git a/Makefile b/Makefile index 2edef54..ebafae0 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ CHANGE ?= slice-0-skeleton # Текущая версия модели данных — по ней рисуются диаграммы (make diagrams) DBML ?= model/data-model-v5.17.dbml -.PHONY: venv validate-contracts validate-openspec check diagrams +.PHONY: venv validate-contracts validate-openspec test-snapshot check diagrams # Единственная зависимость скриптов проверки контракта — jsonschema venv: @@ -22,7 +22,11 @@ validate-contracts: validate-openspec: openspec validate $(CHANGE) --strict -check: validate-contracts validate-openspec +# Снимок для контура вырезает артефакты агента на любой глубине (dev/contour-transfer-guide.md §3); нужны git и bash +test-snapshot: + scripts/test_prepare_contour_snapshot.sh + +check: validate-contracts validate-openspec test-snapshot # Диаграммы model/diagrams/part01…09.{svg,png} из $(DBML); нужен npx (Node.js), зависимостей Python нет diagrams: diff --git a/dev/contour-transfer-guide.md b/dev/contour-transfer-guide.md index 1a7d81b..928f371 100644 --- a/dev/contour-transfer-guide.md +++ b/dev/contour-transfer-guide.md @@ -14,9 +14,9 @@ Gitea в контуре нет) | Что | В контур | Почему | |---|---|---| | `api/` (код, тесты, `contracts/`, `rules/`, `alembic/`, `scripts/`), `web/` (arm-core), `README.md`, `Makefile`, `setup/`, `raisa_config.yml`, `api/.env.example`, `api/.env.test` | да | это и есть сервис по шаблону платформы | -| `openspec/specs/`, `openspec/changes/archive/` | да | спецификация системы и журнал решений (`design.md`); без них код в контуре нечем объяснять | -| `.claude/`, `CLAUDE.md`, `openspec/config.yaml` | **нет** | инструкции и контекст AI-агента (в `config.yaml` — блоки `context`/`rules` с путями `../docs`, `../fixtures`), инструментарий внешней разработки; `openspec` CLI в контуре нет, `specs/` и `design.md` читаются без него | -| `docs/superpowers/` (планы, ledger) | **нет** | рабочие артефакты процесса, содержат локальные пути разработчика | +| `openspec/specs/`, `openspec/changes/archive/` (и `web/openspec/…` в arm-core) | да | спецификация системы и журнал решений (`design.md`); без них код в контуре нечем объяснять | +| `.claude/`, `.codegraph/`, `CLAUDE.md`, `openspec/config.yaml` — на любой глубине, в т.ч. `web/` arm-core | **нет** | инструкции и контекст AI-агента (в `config.yaml` — блоки `context`/`rules` с путями `../docs`, `../fixtures`), инструментарий внешней разработки; `openspec` CLI в контуре нет, `specs/` и `design.md` читаются без него | +| `docs/superpowers/` (планы, ledger) — на любой глубине | **нет** | рабочие артефакты процесса, содержат локальные пути разработчика | | `Dockerfile`, `.dockerignore` | **нет** | образ для локального `make check-full`; в контуре образ собирает платформа своим CI (шаблон держит `Dockerfile` в `.gitignore`) | | История коммитов | **нет** | снимок одним коммитом; в истории снаружи — трейлеры `Co-Authored-By: Claude …`, `Claude-Session`, ссылки на внешний Gitea | | Репозиторий `docs` | **нет** | контекст, модель, контракты, экспорт ТЗ — остаются снаружи; копия контракта лежит в `api/contracts/` каждого сервиса | @@ -36,7 +36,8 @@ Gitea в контуре нет) - `docs` и `fixtures` рядом с сервисом — тесты идентичности контракта и тесты на реальных данных пропускаются (раздел 5), сверка ORM с DBML (`make dbml-check` в arm-core) не выполняется. - `tea`, `codegraph`, `openspec` (CLI), хуки `.claude/hooks` — инструментарий процесса; его конфигурация - (`.claude/`, `CLAUDE.md`, `openspec/config.yaml`) вырезается. + (`.claude/`, `.codegraph/`, `CLAUDE.md`, `openspec/config.yaml`) вырезается на любой глубине — фронт в `arm-core/web/` + синхронизируется из arm-web вместе со своими копиями этих файлов, удалять их вручную не нужно. - Внешний Gitea `git.aepif.ru` — ссылки вида `https://git.aepif.ru/RSHB/arm-core/pulls/19` в архивах change'ей скрипт превращает в `RSHB/arm-core#19` (номера относятся к внешнему Gitea, в контуре их нет). @@ -64,16 +65,19 @@ docs/scripts/prepare-contour-snapshot.sh scan-gateway /tmp/contour Что делает скрипт (репозиторий-источник не меняется): 1. `git archive ` → `/tmp/contour//` — дерево коммита без `.git` и без игнорируемых файлов. -2. Удаляет `.claude/`, `CLAUDE.md`, `openspec/config.yaml`, `docs/superpowers/`, `Dockerfile`, `.dockerignore`. +2. Удаляет `.claude/`, `.codegraph/`, `CLAUDE.md`, `openspec/config.yaml`, `docs/superpowers/` на любой глубине (в т.ч. + `web/` arm-core; опустевший `docs/` тоже), `Dockerfile` и `.dockerignore` — в корне. 3. Правит `Makefile`: цель `venv` → `python3.11 -m venv` + `pip install -r requirements-dev.txt` с `setup/pip.conf` (переменная `PYTHON`, по умолчанию `python3.11`); удаляет цель `docker-build` и её упоминания в `check-full`, `.PHONY`, `help`. 4. Заменяет ссылки на внешний Gitea на `RSHB/#`. 5. Пишет `SNAPSHOT.md` (источник, хеш, дата, что вырезано). -6. Проверяет: нет `.claude`/`CLAUDE.md`/`openspec/config.yaml`/планов/`Dockerfile`, нет локальных путей (`/Users/…`, `/home/…`), нет `uv` и +6. Проверяет: нет `.claude`/`.codegraph`/`CLAUDE.md`/`openspec/config.yaml`/планов ни на какой глубине, нет `Dockerfile`, нет локальных путей (`/Users/…`, `/home/…`), нет `uv` и `git.aepif.ru`, на месте платформенные файлы (`raisa_config.yml`, `setup/`, `run_server.py`, `requirements.txt`, `.env.test`, `contracts/`). Любая проблема — код возврата 1 и список. +Тест скрипта — `make test-snapshot` (синтетический репозиторий с артефактами агента в корне и в `web/`). + Проверено 06.10.2026: снимки arm-core@1d7f2c8, tabular-parser@3b32462, scan-gateway@dffc18a проходят `make check` без `docs` и `fixtures` (1084 / 1087 / 726 passed, пропуски только по причинам из раздела 5). diff --git a/scripts/prepare-contour-snapshot.sh b/scripts/prepare-contour-snapshot.sh index e4285e9..3549ff4 100755 --- a/scripts/prepare-contour-snapshot.sh +++ b/scripts/prepare-contour-snapshot.sh @@ -44,8 +44,12 @@ git -C "$REPO" archive "$REF" | tar -x -C "$DEST" # ../docs и ../fixtures; openspec CLI в контуре нет, specs/ и design.md читаются без него); docs/superpowers/ — планы и # ledger (в них локальные пути); Dockerfile/.dockerignore — локальная сборка образа, платформа собирает образ своим CI. # openspec/specs/ и openspec/changes/archive/ остаются: это спецификация проекта и решения (design.md). -rm -rf "$DEST/.claude" "$DEST/CLAUDE.md" "$DEST/openspec/config.yaml" "$DEST/docs/superpowers" "$DEST/Dockerfile" "$DEST/.dockerignore" -rmdir "$DEST/docs" 2>/dev/null || true +# Артефакты агента вырезаются на любой глубине: фронт перенесён в arm-core/web/ из arm-web со своими .claude/, CLAUDE.md, +# openspec/config.yaml, docs/superpowers/ и .codegraph/. Dockerfile/.dockerignore — только в корне (образ сервиса). +rm -rf "$DEST/Dockerfile" "$DEST/.dockerignore" +find "$DEST" \( \( -type d \( -name .claude -o -name .codegraph -o -path '*/docs/superpowers' \) \) \ + -o \( -type f \( -name CLAUDE.md -o -path '*/openspec/config.yaml' \) \) \) -prune -exec rm -rf {} + +find "$DEST" -type d -name docs -empty -delete # --- 2. Makefile: venv через python -m venv + pip с Nexus, без uv; без docker-build -------------------------------- python3 -I - "$DEST/Makefile" <<'PY' @@ -132,8 +136,9 @@ cat > "$DEST/SNAPSHOT.md" <&2; fail=1; fi done +left=$(cd "$DEST" && find . \( -name .claude -o -name .codegraph -o -name CLAUDE.md -o -path '*/openspec/config.yaml' \ + -o -path '*/docs/superpowers' \) -print) +if [ -n "$left" ]; then echo "ошибка: в снимке остались артефакты агента:" >&2; echo "$left" >&2; fail=1; fi if grep -rIn "/Users/\|/home/[a-z]" "$DEST" >/dev/null 2>&1; then echo "ошибка: в снимке есть локальные пути:" >&2; grep -rIn "/Users/\|/home/[a-z]" "$DEST" >&2; fail=1 fi diff --git a/scripts/test_prepare_contour_snapshot.sh b/scripts/test_prepare_contour_snapshot.sh new file mode 100755 index 0000000..e27b150 --- /dev/null +++ b/scripts/test_prepare_contour_snapshot.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# Тест prepare-contour-snapshot.sh на синтетическом репозитории arm-core: артефакты агента вырезаются на любой глубине +# (в т.ч. во вложенном web/), спецификации и код остаются. Запуск: make test-snapshot (или напрямую из корня docs). +set -euo pipefail + +SCRIPT="$(cd "$(dirname "$0")" && pwd)/prepare-contour-snapshot.sh" +WORK=$(mktemp -d) +trap 'rm -rf "$WORK"' EXIT + +git init -q --bare "$WORK/origin.git" +git clone -q "$WORK/origin.git" "$WORK/src/arm-core" 2>/dev/null +R="$WORK/src/arm-core" + +put() { mkdir -p "$(dirname "$R/$1")"; printf '%s\n' "${2:-x}" > "$R/$1"; } + +# платформенные файлы, без которых проверка снимка падает +printf 'venv:\n\tuv venv api/.venv\n' > "$R/Makefile" +for p in raisa_config.yml setup/setup.sh setup/pip.conf api/run_server.py api/requirements.txt api/.env.test \ + api/contracts/schema.json; do put "$p"; done +# корень: артефакты агента и локальная сборка +for p in .claude/skills/a/SKILL.md CLAUDE.md openspec/config.yaml docs/superpowers/plans/p.md Dockerfile .dockerignore; do + put "$p" "/Users/someone/projects" +done +put openspec/specs/osv/spec.md +# вложенный фронт (как web/ из arm-web): те же артефакты на второй глубине +for p in web/.claude/commands/opsx/apply.md web/.codegraph/.gitignore web/CLAUDE.md web/openspec/config.yaml \ + web/docs/superpowers/plans/2026-10-08-demo.md; do + put "$p" "/Users/someone/projects" +done +put web/openspec/specs/osv-ui/spec.md +put web/openspec/changes/archive/2026-10-08-demo/design.md +put web/src/App.tsx +put web/docs/notes.md # прочее содержимое вложенного docs/ остаётся + +git -C "$R" add -A +git -C "$R" -c user.name=t -c user.email=t@t commit -qm init +git -C "$R" push -q origin HEAD:main 2>/dev/null +git -C "$R" fetch -q origin + +"$SCRIPT" "$R" "$WORK/out" origin/main >/dev/null +D="$WORK/out/arm-core" + +fail=0 +for p in .claude CLAUDE.md openspec/config.yaml docs Dockerfile .dockerignore \ + web/.claude web/.codegraph web/CLAUDE.md web/openspec/config.yaml web/docs/superpowers; do + if [ -e "$D/$p" ]; then echo "FAIL: в снимке остался $p" >&2; fail=1; fi +done +for p in openspec/specs/osv/spec.md web/openspec/specs/osv-ui/spec.md web/openspec/changes/archive/2026-10-08-demo/design.md \ + web/src/App.tsx web/docs/notes.md SNAPSHOT.md; do + if [ ! -e "$D/$p" ]; then echo "FAIL: из снимка пропал $p" >&2; fail=1; fi +done +[ "$fail" = 0 ] || exit 1 +echo "ok: prepare-contour-snapshot.sh вырезает артефакты агента на любой глубине" -- 2.47.2