Перейти к основному содержимому

AGENTS.md — Правила разработки GWPTD (ЧИТАТЬ ПЕРВЫМ, до любого действия)

Для любого агента (Claude Code, Codex, новая сессия после компрессии). Эти правила имеют приоритет. Если сомневаешься — спроси владельца, не действуй.

Иерархия системы описана в docs/README.md, раздел «Система сверху вниз»: стратегический → функциональный → описательный. Этот файл — границы и что заморожено; своей карты системы здесь больше нет.

0.0. ПЕРВЫМ ДЕЛОМ — проверить Телеграм-сообщения владельцу

Ты не видишь Телеграм. Но каждое сообщение, которое уходит владельцу от системы, пишется строкой в журнал на S3. В начале КАЖДОЙ сессии читай его:

ssh s3-int tail -30 /var/log/gwptd-telegram-sent.log

Это показывает последние 30 сообщений: что система сообщала владельцу за последние часы. Там могут быть:

  • протухшие сборы (сторож свежести, ежечасно);
  • упавший kernel (пересчёт данных, раз в день);
  • упавший сервис (critical-alerter, раз в минуту);
  • расхождения s2↔s3 (компаратор, раз в день).

Формат строки: 2026-08-07T09:45:01+00:00 [s3] OK 🕒 текст сообщения. Многострочные сообщения склеены в одну строку ( вместо перевода строки).

Если журнал пуст или недоступен — так и напиши «журнал Телеграма пуст». Но НЕ пропускай этот шаг: сбор однажды стоял двое суток, владелец знал, а агент нет — потому что не посмотрел.

0. Обязательный старт КАЖДОЙ сессии (не пропускать)

  1. Прочитать этот файл целиком.
  2. Прочитать MCP-память: mcp__vestige__search по теме задачи — там состояние, решения и КОРНИ багов прошлых сессий (часто задача уже наполовину разобрана).
  3. Прочитать код через индекс: mcp__mcp-gwptd__rag_search — НЕ гадать по памяти, смотреть реальный код.
  4. Прочитать CLAUDE.md проекта.
  5. Если ты в проекте впервые (агент сотрудника, пробный период с 2026-07-29) — for-ai-agents/START-HERE.md: маршрут «что искать, что читать, что править», раскладка по задачам и грабли. На S3 память зовётся mcp__vestige-s3__*, на машине владельца — mcp__vestige__*. Запрещено писать/менять что-либо до шагов 1–4. Важный факт/решение/корень бага — СРАЗУ сохранять в mcp__vestige__smart_ingest (чтобы не потерять при компрессии).

0.1. СТАТУС РЕМЕДИАЦИИ (2026-07-03) — ЧТОБЫ НЕ ПЕРЕДЕЛЫВАТЬ ГОТОВОЕ

Крупный kernel-first рефакторинг ЗАВЕРШЁН и влит в master (merge e346dd5, +статус-баннеры cff576d). Все 10 эпиков плана docs/remediation/ реализованы. Перед тем как брать задачу — проверь её СТАТУС-баннер (в файле задачи после заголовка) и сводку docs/remediation/_execution-log.md: ✅ СДЕЛАНО / ❄️ ЗАМОРОЖЕНО / ⏭️ ОТЛОЖЕНО / ⏳ OWNER-GATED. Не переделывай сделанное.

  • Целевая = /new + Data API + kernel ETL. Бизнес-формулы починены В KERNEL: убран дубль Ozon, оборачиваемость=«продано» (realized), вычет возвратов (net), corrective портирован в Data API, WB-финансы V3 на POST detailed, degraded-контракт (enum data_status). Развёрнуто на s3 dev (крон build_all считает новыми формулами).
  • Старый PHP-слой ЗАМОРОЖЕН (@deprecated + трейт OldInterfaceOnly, недостижим в /new) — держим для сверки было→стало. НЕ трогать, НЕ «чинить», НЕ удалять (удаление — будущая итерация после cutover).
  • Owner-gated (НЕ делать без явного OK владельца): s2-деплой (миграция net-колонок, .env-пароли, ротация кредов, GWPTD_API_TOKENS), живой сбор WB-финансов (нужен токен scope «Финансы»), схлопывание двухколоночного FBO/FBS-дисплея рейтинга.
  • DNR-001 РЕШЁН — ПОДТВЕРЖДЕНО ВЛАДЕЛЬЦЕМ (2026-07-03): ВСЕ оценки моделей (рейтинг, оборачиваемость) считаются ТОЛЬКО от реальных продаж = «выкуплено − возвраты» (net realized). Заказы / спрос / «отгрузки» / корзины в числитель НЕ идут. Пример владельца: заказали 100 шт по ошибке, получили, вернули → рейтинг модели НЕ должен вырасти; хороша только та модель, что выкупили и не вернули. Указание ecca7f26 (спрос/velocity новинок) ОТМЕНЕНО. Это DO-NOT-REGRESS — никогда не переводить оценку моделей на спрос/заказы.
  • 📖 Бизнес-канон — docs/domain/ (читать ПЕРЕД любой правкой формул рейтинга/оборачиваемости/ возвратов/отгрузки): DO-NOT-REGRESS.md (контр-интуитивные решения SETTLED/CONTESTED, что «сломается при фиксе»), STATUS-SEMANTICS.md+metric-status-map.yaml (семантика статусов по метрике, группы МП, caveat'ы mp2/mp7/WB-дубль/легаси-хвост), COVERAGE-MATRIX.md (дыры сбора: YM недосбор, Ozon analytics и т.д. — объяснение расхождения цифр). Код — реализация правил, канон здесь.

1. Что мы строим

Мигрируем сбор данных маркетплейсов на V3 — новый протокол. Зачем (из V3/01_VERSION_3_OVERVIEW.md): в legacy бизнес-числа смешаны с raw_json, описание товара дублируется по таблицам, один товар имеет РАЗНЫЕ ID на WB/Ozon/YM/Lamoda и они НЕ связаны. V3 это чинит новой структурой: intake → kernel → reports, нормализованный dim_product + dim_product_identifier (связка всех mp-ID), артикул 1С как канонический ключ. Делается постепенно, параллельно рабочей системе.

  • Legacy РАБОТАЕТ и собирает уже 2 месяца (lamoda_reports, mp.hyp.ru на PHP+MySQL). НЕ трогать, НЕ ломать, НЕ откатывать на него API. Это ЭТАЛОН чисел для сверки.
  • Стек mp.hyp.ru = PHP + MySQL (требование Михаила, не менять). Python-коллектор V3 живёт отдельно, наружу отдаёт через Data API (HTTP/JSON), а не прямым SQL.
  • Интерфейс /new (Filament, читает Data API/kernel) — целевой, развит (Phase 7 сделана в ремедиации); legacy /admin заморожен для сверки. См. §0.1 выше.

2. Пайплайн разработки — ЖЁСТКО

Локально пишу → s3 обкатываю → s2 публикую только по явному OK.

  • Вся разработка, сборка, прогоны ETL, сверка kernel↔legacy — на s3 (там тот же legacy-слой, kernel, intake, ETL и коллекторы).
  • s2 (PROD) read-only разрешён для диагностики и копирования эталонных данных на s3 (решение владельца 2026-06-30): если для s3-прогона нужна полная legacy-история, её можно скачать/зазеркалить с s2 на s3 и дальше работать на s3.
  • s2 (PROD) писать/деплоить нельзя для разработки. Любые изменения данных, кода, контейнеров, кронов или cutover на s2 — только когда владелец явно сказал «публикуй» или отдельно разрешил конкретное действие.
  • Прод-cutover (переключение чтения mp.hyp.ru на kernel/Data API) — отдельный гейт ADR-0006: расхождение с legacy <0.5% × 14 зелёных дней + явный OK владельца.

3. Канон данных: ВСЁ через 1С

Все отгрузки на все маркетплейсы идут через 1С → каждый mp-артикул обязан быть в 1С (dim_product из partners.product, ADR-0007). Если артикул не резолвится / попал в resolution_quarantine — это БАГ нашей программы (нормализация, маппинг, пропущенный источник), а НЕ «товара нет в 1С». Синтетические/новые модели не создавать. Чинить матчинг.

4. Режим работы агентов

  • Codex = архитектор и пишет код (codex:codex-rescue). Давать узкие single-file ТЗ — открытые задачи («прочти весь движок») зависают на часы. Его патч всегда проверять (ошибается: напр. перепутал резолв seller_skunmID).
  • DeepSeek (/deepseek, терминал ds-delegate) — объёмная механика и вторые мнения. Полные правила и обязательный блок для промпта — в ~/.claude/skills/deepseek/SKILL.md.

Как проверять патч любого делегата (Codex, DeepSeek, opencode)

Смотри СНАЧАЛА что удалено, а не что добавлено:

git diff | grep '^-' | grep -v '^---'

Комментарии и докстроки в коде — действующие требования. Делегаты склонны их удалять и заменять утверждением, что их реализация достаточна, — так требование исчезает вместе с причиной. Поймано дважды за один день 02.08:

  • DeepSeek, build_fact_storage.py: стёр докстроку YM storage needs its own mapped/unallocated contract. Замер показал, что она была права — из 722 артикулов резолвилось 230, на остальных висело 131 865 ₽ из 440 102. Патч либо уронил бы сборку, либо тихо выбросил треть суммы.
  • Codex, mapper/transforms.py: жёстко прописал префикс базы lamoda_reports., хотя engine.py:194 специально его не использует — чтобы один YAML работал и на s2, и на s3. Работало бы только на s2.

И перед тем как поручать проекцию или миграцию — сначала измерь долю строк, которые не пройдут резолв или джойн. Она определяет, какое задание вообще ставить: простую проекцию или контракт с разделением. Один SQL до делегирования экономит цикл написания и отката.

  • Запускать несколько агентов параллельно: своё (диагностика/чтение) + Codex (код).
  • Держать основной контекст чистым — тяжёлое чтение делегировать субагентам, не тянуть всё в свой контекст.
  • Каждое архитектурное решение — через Codex + сверка с MCP-памятью.
  • UI/тексты после Codex — ревью по docs/UI-GUIDE.md (решение владельца 2026-06-12): страница обязана читаться по-человечески — единая анатомия секций, живые русские лейблы, три состояния, чек-лист п.6 перед коммитом.

5. Карта системы — заменена страницами блоков (14.08.2026)

Прежняя карта (была в этом разделе, датирована 20.07) устарела: половина строк про legacy, а замер 14.08 нашёл в ней девять неверных мест — перечень в docs/agents/ZAMER-KARTY-BLOKOV-2026-08-14.md, раздел «Что было неверно в прежней карте». Чинить её не стали: вместо неё — восемь страниц блоков docs/system/blocks/ (описательный уровень иерархии). Где что лежит — читать там, вход через docs/README.md, раздел «Система сверху вниз».

Соответствие mp_id площадкам стояло в прежней карте строкой, набранной руками. Оно не потеряно, а переехало туда, где порождается: docs/backend/generated/MARKETPLACES-AND-IDENTITY.md — и там полнее: не только номер и название, но группа (первичный → суб-MP) и realized-статус. Руками этот список больше не переписывать.

6. Текущее состояние (актуализация 2026-07-20)

  • S3 Next SHA является live-фактом: перед этим документационным выпуском read-only аудит подтвердил чистый/in-sync next/spec-platform@81d7caa299578e5c81ecf277650018cf25a6c6e5, потомок 10c720f/ca8c38a, включающий P1B/P3-D/P4/P6 исправления. После любого выпуска SHA меняется; всегда проверять его через mcp__gwptd__repo_status, а не использовать эту историческую строку как текущее значение.
  • Новый интерфейс и Data API на S3 работают: gwptd-app-new и gwptd-data-api healthy; внешний https://mp.hyp.ru/new* принадлежит S3, /new/login отдаёт 200, защищённые страницы возвращают ожидаемый SSO 302. Внешний / остаётся legacy entrypoint S2 и ведёт на /admin.
  • Collector recovery ещё не закрыт: P1B требует свежего естественного reference + build_all evidence на неизменённом runtime; P3 развёрнут dark/not activated; P4 и P5 нельзя объявлять закрытыми без их фактических evidence. Источник статуса и порядка действий — docs/remediation/S2-REFERENCE-S3-COLLECTOR-RECOVERY-PLAN.md и docs/remediation/PARALLEL-WORK-BOARD.md.
  • S2 остаётся read-only: не выполнять там deploy, миграции, изменения cron, контейнеров или данных без отдельного явного разрешения владельца.
  • Сведения ниже и в старых документах с датой 2026-06-11 — исторические результаты, а не инструкция о текущем runtime.

7. ВАЖНЫЕ ПОПРАВКИ (что в прежних заметках было НЕВЕРНО)

  • ❌ «WB недосбор = баг резолвера / товара нет в 1С». ✅ Корень: steady-state build_fact_orders.py не читал intake.wb_sales (пропущенный источник) → sale замёрз на 19.05. Резолвер исправен, все артикулы в 1С.
  • ❌ «kernel завышает WB ×2.5/×3». ✅ Артефакт бага кодирования status[] для FastAPI (Laravel слал status[0]=, FastAPI игнорировал → отдавал ВСЕ статусы). Реально kernel НЕДОбирал. Проверять API только через исправленный DataApiClient или литеральный &status=X, не сырым Http с массивом.
  • ❌ «mp6 заморозка/дубль mp6≡mp8 = баг дедупа YM». ✅ ИСТИННЫЙ корень — _cache_key (base.py) не включал URL: оба /campaigns/{id}/stats/orders давали один cache-key → fby получал кэш fbs → mp8 = данные fbs, mp6≡mp8 (и раньше дедуп морозил mp6). Фикс 30fd7de (url в хэш). Фикс A (dedup) и date-parser были band-aid'ами. Касалось ВСЕХ коллекторов с различителем в СЕРЕДИНЕ URL.
  • ❌ «kernel недозаполняет mp5/YM — блокеры cutover». ✅ Наоборот: LEGACY контаминирован (двойные записи: Ozon mp3↔mp5 дубль; YM один заказ под обе кампании; mp3 статус analytics = псевдозаказы; mp1 order с пустым order_id). Kernel ЧИЩЕ. Сверять против ОЧИЩЕННОГО legacy.
  • ❌ «карантин 613 = товара нет в 1С / баг матчинга». ✅ Корень — НЕПОЛНОТА ИСТОЧНИКА 1С: V3 тянет эндпоинт «Остатки с ценой» (1718, регистр остатков) → товары с 0 остатком выпадают. Полной номенклатуры пока нет (nomenclature_v2 пуст; присланная выгрузка — 1 склад, 18939, покрывает лишь 25/362). dim_product/resolve-back исправны — очистят сами по пополнении 1С.

Связанные документы

  • docs/README.md — вход в иерархию: раздел «Система сверху вниз» (стратегический → функциональный → описательный).
  • for-ai-agents/START-HERE.md — вход для нового агента: порядок поиска, куда класть правку по типу задачи, чего не делать без владельца, грабли окружения.
  • CLAUDE.md — обзор Laravel-приложения mp.hyp.ru (legacy), таблицы, API, деплой.
  • V3/_START_HERE_AFTER_COMPRESSION.md, V3/01_VERSION_3_OVERVIEW.md, V3/99_DECISIONS/ — спецификация и решения V3 (читать при работе с движком/kernel).
  • MCP-память (mcp__vestige__search) — живое состояние, корни багов, креды, правила.