Files
specs/openspec/changes/archive/2026-11-02-account-top-positions/process-record.md
T
codex-bot 3821d9ed58
Specs security / security (push) Successful in 7s
Specs verify / verify (push) Successful in 14s
refactor: group canonical specs by domain and archive account-top-positions (#74)
2026-11-02 21:50:49 +03:00

21 KiB
Raw Blame History

Process Record

Mode: lab Class: complex — межсистемно (backend + frontend + T-Bank), синхронизация внешних данных и финансовые расчёты долей Issue: WealthLedger/main#48

Change Profile

Артефакт Выбран Причина
research yes Trigger: новый продуктовый функционал и вопрос владельца «какой ещё есть критерий?». Нужно сравнить критерии концентрации и формы визуализации в других продуктах. Итог — analysis/research.md.
ux-design yes Trigger: новый экран, вкладка «Концентрация» с четырьмя разрезами, выбором валюты, диаграммой и «Прочее». Отдельно нужно решить, как она соотносится с существующей «Структурой портфеля».
system-analysis yes Trigger: меняется контракт Portfolio, в позициях появляются сектор и эмитент. Новые данные берутся из внешней интеграции T-Bank (инструмент, актив и его бренд).
data-mapping yes Trigger: данные T-Bank (sector, asset → brand) нужно преобразовать в данные позиций Portfolio, а коды секторов — в русские подписи. Нужно правило для пустых и неизвестных значений.
failure-model yes Trigger: обогащение позиций идёт через внешнюю интеграцию в часовой синхронизации. Отказ или неполнота данных T-Bank не должны ломать Portfolio Snapshot и его свежесть (Open Decision 4 Proposal).
nfr no Число позиций одного счёта ограничено, вкладка считается по уже загруженному Portfolio. Нагрузку на T-Bank и лимиты запросов рассматривает failure-model; отдельных обязательств по задержке, объёму и хранению нет.
observability no Новых фоновых процессов нет: обогащение идёт внутри существующей синхронизации с её логированием. Недоступность данных видна пользователю как явные группы «не указан»; частичный успех обогащения (Snapshot сохранён, часть данных не получена) фиксируется в failure-model и существующих логах синхронизации без новых метрик и алертов.
security-analysis no Модель доступа и trust boundaries не меняются. Сектор и бренд — публичные справочные данные инструмента, к Portfolio того же User добавляются только они. Новые запросы к T-Bank идут под уже существующим токеном подключения того же User, новых секретов и прав нет.
test-cases yes Trigger: финансовые расчёты (суммы, доли, топ-5, «Прочее», сумма долей = 100 %) и много граничных случаев: одна валюта из нескольких, меньше пяти элементов, равные суммы, нет сектора или бренда, шорт, неоценённые позиции. Для проверки нужны конкретные данные и расчётный oracle.
docs-impact yes Trigger: несколько docs targets — домен Portfolio, страница интеграции T-Bank (новые используемые данные) и глоссарий (Концентрация, Сектор, Эмитент).

Gate Log

Gate Дата Scope Validation Findings Decision
G1 2026-10-30 proposal, change-profile openspec validate — ожидаемая ошибка «no deltas» до specs; readiness: plan OK (proposal, process-record, research); HTML-комментариев нет; git diff --check OK G1 review independent-reviewer: 1 blocker, 4 major, 6 minor — закрыты решениями владельца (issuecomment-3077) и правками; повторный review: ready approved "вроде все ок"
G1 2026-10-30 proposal — G2 review B1: правило валют вкладки противоречит proposal invalidated: решение владельца по B1 (issuecomment-3079) меняет правило валют в proposal
G1 2026-10-30 proposal, change-profile openspec validate --strict valid; readiness: plan OK; proposal обновлён по 3079 (свой список валют вкладки) G2 re-review independent-reviewer: B1 закрыт в proposal approved "Да, G1 ок" (issuecomment-3080)
G2 2026-10-30 specs openspec validate --strict valid; git diff --check OK; readiness: plan OK; self-check по spec-writing.md G2 review qa-engineer + independent-reviewer: 1 blocker (B1, валюты), 4 major, ~12 minor — закрыты решениями владельца (3079, 3080) и правками; финальный re-review: ready approved "да, идем дальше"
G2 2026-10-30 specs — system-analysis/ux-design: эмитент у фондов, обновление metadata, имя эмитента при расхождении, поведение вкладки (сохранение выбора в пределах страницы, скрытый Select, метрика ≤5, partial) invalidated: решения владельца (issuecomment-3081) меняют Specs
G2 2026-10-30 specs, system-analysis, data-mapping, failure-model openspec@1.13.1 validate --strict valid; validate --specs 33/33; git diff --check OK; readiness: plan OK; Coverage 32/32 G2 rev2/rev3 review independent-reviewer + qa-engineer: 1 blocker (B1 — противоречие canonical «Свежесть и fallback»), 3 major, ~8 minor — закрыты решениями владельца (3081, 3082) и правками; финальный re-review: ready approved "ок, давай дальше"
G3 2026-10-31 design, ux-design, qa-analysis, test-cases, docs-impact, tasks openspec@1.13.1 validate --strict valid; git diff --check OK; readiness: apply OK; Visual Package v2 SHA-256 сверены reviewer; Coverage 32/32 G3 review independent-reviewer + frontend-engineer: 4 major, 4 minor, Q2 — закрыты; backend-engineer не выполнен (квота API), backend-утверждения design сверены основным агентом с кодом; повторный review: ready. Включает изменение вне Specs: подпись «Государственный сектор» на странице акции и в каталогах (3084) approved "да, все окей, идем дальше"
G4 2026-11-02 archive Код и docs в develop: backend 17432df, frontend 70a2c33, docs 37430da; openspec@1.13.1 validate --strict valid Independent Review, QA и проверка отката не выполнялись archived without verification: решение владельца в сессии specs#74 (descope 3.1–3.4, 5.1)

Примечание к G2 (2026-10-30): GIVEN «сектор и бренд актива позиции ещё ни разу не получены» в Scenario «Недоступность сектора и эмитента не нарушает Snapshot» (finding N1) и замена строки design-обязательства в failure-model (N2) внесены основным агентом до записи approved G2 и входят в утверждённую версию.

Descoped Work

Task Причина Gate
3.1 Independent Review Владелец решил архивировать без G4: код и docs уже в develop и релизах G4
3.2 QA test-cases Владелец решил архивировать без G4: код и docs уже в develop и релизах G4
3.3 QA exploratory Владелец решил архивировать без G4: код и docs уже в develop и релизах G4
3.4 Откат backend Владелец решил архивировать без G4: код и docs уже в develop и релизах G4
5.1 Запись G4 с evidence Владелец решил архивировать без G4: код и docs уже в develop и релизах G4

Lab Journal

Стадия Роль / сабагент Уникальные находки Решения Риски найдены / исключены Проблемы передачи Skills Стоимость Переносимо
research product-researcher В Portfolio DTO нет сектора и эмитента, хотя T-Bank их отдаёт. Доля топ-5 понятнее HHI. Общий мультивалютный рейтинг без конвертации некорректен. «Структура» дублировала бы существующий виджет. MVP: акции, облигации, секторы; позже: страна, maturity, riskLevel, P&L, HHI; не делать: кредитный рейтинг, конвертацию, treemap Найден: полнота sector неизвестна. Исключено: смешение валют Нет — 1 вызов Шаблон «must / later / no» для выбора критериев
proposal product-analyst + основной агент Эмитент требует отдельной идентичности; основной агент нашёл в proto T-Bank AssetFull.brand {uid, name, company, sector} (краткий Asset бренда не содержит). 8 Open Decisions, 3 из них меняют scope Владелец: «Эмитенты» в MVP (отклонение от research: Later → MVP), эмитент = бренд T-Bank, фонды не входят, госбумаги — по сектору T-Bank, режим lab Найден: «Эмитенты» зависят от полноты бренда. Исключено: группировка по названию Валидация change ждёт delta specs (ожидаемо) — 1 вызов + 2 вопроса владельцу Решать scope-вопросы до G1 через короткий опрос
G1 review independent reviewer + product-analyst Источник бренда указан неточно (Asset вместо AssetFull.brand); «Секторы» не задавали набор типов; раскрытие «Прочее» было Open Decision; не зафиксировано отклонение от research Владелец (Issue #48, комментарий): «Прочее» раскрывается; без бренда — fallback «Эмитент не указан» без нового G1; «Секторы» только STOCK/BOND/FUND; общий топ-5 вне scope Найден: несоответствие источника и scope. Исключено: зависимость «Эмитентов» от полноты бренда Proposal правился после review; Gate Log не заполнялся — 1 вызов Сверять ссылки на proto с исходником до G1
specs product-analyst Остальные нормы вкладки не требуют новых источников; в canonical нет перечня вкладок страницы счёта и правил выбора валюты «Структуры портфеля» (они только в коде и docs) — правила валюты, округления, равных сумм определены в Specs и вынесены на подтверждение G2. Эмитент и сектор — новые поля позиции Portfolio 2 дельты: новая portfolio-concentration (23 Requirement), portfolio-view MODIFIED «Нормализованный состав Portfolio». Решения владельца (3078) внесены Найден: расхождение «Структуры портфеля» (деньги в знаменателе и в валютах) и вкладки (без денег) — различие зафиксировано явно Нет — 1 вызов Сверять правила «как в существующем виджете» с canonical до написания, а не с кодом
G2 review qa-engineer + independent-reviewer + product-analyst Валюты вкладки не были определены независимо от «Структуры»; «Прочее» при шести элементах скрывало одну строку; метод наибольшего остатка противоречил показу долей в карточках; подписи секторов без источника; не было граничных сценариев 5/6 элементов и противоречивый GIVEN Владелец (3079): свой список валют вкладки; округление как в карточках, «< 0,1 %»; «Прочее» от семи элементов. Автор: список валют включает отрицательные и нулевые позиции STOCK/BOND/FUND; null считается в сноске при любой валюте Найден: расхождение формата долей между спеками и кодом. Исключено: инвариант «100,0 %» на показанных значениях Gate Log ведёт основной агент (G1 инвалидирован) — 1 вызов Сверять формат чисел с кодом существующего виджета до написания норм
specs rev2 product-analyst G2 инвалидирован решениями 3081: issuer у фондов в данных; обновление sector/brand раз в сутки с последним известным значением; отказ token — как существующая недействительность; trim пробелов; имя эмитента по наибольшей позиции; сохранение выбора в пределах страницы; метрика топ-5 при ≥6 элементах; центр кольца; «Данные неполные» portfolio-concentration 28 Requirement (+5: вкладка в состояниях страницы, название эмитента при разных названиях, центр диаграммы, строки без переходов, предупреждение о неполных данных; «Суммарная доля топ-5» и «Начальное состояние» переписаны); portfolio-view MODIFIED + 3 ADDED (срок обновления, последнее известное, ошибки получения) Найден: «Данные неполные» привязано к meta по tbank-data-sync, не к неоценённым позициям. Исключено: конфликт metadata/invalid token (отсылка к существующему поведению) Gate Log ведёт основной агент — 1 вызов Сверять производные analysis-артефакты с Delta Specs до G2
specs rev3 product-analyst G2 re-review: хранение sector/brand противоречило «Свежесть и fallback» (только онлайн, без долговременного справочника) и «metadata не определяет успешность»; граница 24 ч была сформулирована как «24 ч + интервал»; «не найдено», пустой ответ и ответ о другом активе не были определены 3082: исключение для sector/brand; «не найдено» = «значения нет»; равные наибольшие позиции эмитента — по алфавиту; предупреждение о неполных данных только на вкладке portfolio-view: MODIFIED «Свежесть и fallback» (полная копия + 2 исключения и 2 сценария), ADDED «Обновление сектора и эмитента» и «Результат получения сектора и эмитента» (таблица исходов), без дублей; portfolio-concentration: название эмитента по алфавиту, предупреждение без дубля Найден: страничного сообщения о неполноте в canonical «Состояния и ошибки Portfolio на клиенте» нет (требует лишь не выдавать неполный итог за окончательный), поэтому MODIFIED для него не нужен. Исключено: дублирование норм об ошибках Gate Log ведёт основной агент — 1 вызов
design ∥ qa-analysis solution-architect, qa-engineer Общий metadata-кэш не подходит под 24 ч и 4 исхода, нужна отдельная таблица классификации; шаг классификации должен идти до publish, иначе отказ token не инвалидирует подключение; DonutChart 9.7.3 хватает без прямого recharts Таблица TbankInstrumentClassification, opt-in NOT_FOUND только для новых вызовов, состояние вкладки поднято в page VM; владелец: ~25 ч, квоты в QA до G4, «Государственный сектор» в общем словаре (3084) Найдено: изменение страницы акции вне Specs (одобрено 3084); откат образа без миграции Субагенты не видели полный текст review, findings пересылались вручную — 2 вызова + 3 доработки Сверять design-ссылки на код до G3
test-cases + docs-impact + tasks qa-engineer, documentation-engineer, solution-architect 21 из 30 зарезервированных TC ничего не добавляли сверх Scenario и выброшены; «эмитент» конфликтует с термином docs 15 TC + TC-CONC-020; глоссарий с оговоркой, ADR 022 (3083); 28 tasks по 4 repo Найдено: 2 неверных oracle (TC-CONC-007, TC-META-003) — — 3 вызова Пересчитывать oracle независимым ревьюером
G3 review independent-reviewer, frontend-engineer; backend-engineer — сбой по квоте API (3 попытки) 4 major, 4 minor, Q2 (откат без миграции); frontend API DonutChart подтверждён Все findings закрыты; backend-утверждения design (до publish, InvalidToken catch, NOT_FOUND в call(), WORK_WAIT_BOUND_MS) основной агент сверил с кодом вручную Остаётся: backend-ревью субагентом не выполнено Квота API — 5 вызовов Ревью backend повторить на G4