Files
main/audits/2026-10-11/reports/15-sdd-specs-and-documentation.md
T
codex-bot d07fbfabb1 docs: archive technical audit 2026-10-11 in develop (#36)
Переносит архив `audits/2026-10-11/` (19 файлов) из codex/audit-remediation-2026-10-11 в develop и добавляет точечный allowlist в .gitignore.
2026-10-17 19:38:03 +03:00

71 KiB
Raw Blame History

Аудит 15 — SDD, Specs & Documentation

1. Audit metadata

  • Дата: 11 октября 2026 года.
  • Задание: audit-prompts/15-sdd-specs-and-documentation.md.
  • Результат: audit-results/15-sdd-specs-and-documentation.md. Имя выбрано по прямому указанию пользователя; файл находится вне четырёх предметных репозиториев.
  • Режим: read-only для frontend, backend, specs, docs; создан только этот отчёт. Исходники, конфигурации, тесты, архивы, generated artifacts и зависимости не изменялись.
  • Skill: установленный ponytail-audit прочитан и применён к стоимости документационной сложности. Его область — упрощение; расхождения требований, контрактов и lifecycle проверены дополнительно по протоколу задания. verification-before-completion применён к проверке результата. graphify прочитан: существующий graphify-out/graph.json не найден, граф не создавался из-за read-only границы и запрета дополнительных артефактов.
  • Предыдущий аудит: audit-results/technical-audit-2026-10-11.md использован как реестр гипотез, не как доказательство. Его runtime findings не переносились в этот отчёт.

Репозитории и точные revisions

Workspace: /Users/ksv741/Project/vibe/WealthLedger.

Repo Найденный путь от workspace HEAD Рабочее дерево
root . dc030f84c979cedb2628ef4bd97c62d6c63a9256 Чистое; audit-results исключён root allowlist
frontend frontend/ c8821200ce699dab1ce65360d1968d5877a2e78b Чистое
backend backend/ 0ad84ff4f0b4712abc7e69dc299856f14af6eadd Чистое
specs specs/ fcdc805f6c1b3be6a20a7e858e3e80cbd83a9121 Чистое
docs docs/ e6fd4f64b81dd73b33959b845a1babcfac1891c8 Чистое

git status --porcelain=v1 проверен до исследования и перед записью. Итоговый повтор и проверка отчёта зафиксированы в разделе 9. Чистый status root сам по себе не подтверждает сохранность ignored nested repositories, поэтому они проверяются отдельно.

Фактический layout и tooling

  • specs/openspec/ — единственный найденный store; config выбирает wealth-ledger-sdd-v2, change metadata сохраняет выбор конкретной schema.
  • Backend — NestJS 12, Prisma 7.10, SQLite, TypeScript 6; frontend — React 19.3, Vite 8.3, TanStack Query 5, TypeScript 5.9. Источники: manifests, без проверки всех установленных runtime-версий.
  • docs — Markdown и Mermaid без настроенного публикационного генератора; specs — OpenSpec и Git tooling.
  • Найден executable openspec: /Users/ksv741/.nvm/versions/node/v24.21.0/bin/openspec. Установленный package manifest содержит @fission-ai/openspec 1.13.1. Это статическое чтение manifest, не результат запуска openspec --version.
  • Далее $OPENSPEC — обозначение каталога /Users/ksv741/.nvm/versions/node/v24.21.0/lib/node_modules/@fission-ai/openspec, а не созданная конфигурация проекта.

Выполненные проверки и ограничения

Выполнены безопасные чтения и поиск, git rev-parse HEAD, git status, выборочные git log, git show --stat, git ls-files, подсчёты через rg -c, git diff --check, а также:

git diff --no-index --stat backend/openapi.json frontend/src/shared/api/spec/openapi.json

Результат сравнения: exit 0, различий файлов на диске нет. Это не подтверждает свежую генерацию относительно handlers, совместимость с target contract или совместимость развёрнутой пары приложений.

Не запускались: application tests, full-suite/build/verify, OpenSpec validation/status/archive/sync, codegen, install, миграции, браузер, внешние API или сетевые проверки URL. Не создавались инструменты аудита. Чтение имеющихся tests подтверждает содержание assertions, но не их успешное исполнение.

2. Executive verdict

  1. Факт — разделение authority в целом удачное. Требования принадлежат specs, объяснения текущей системы — тематическим docs, причины решений — ADR, executable HTTP contract — backend metadata/OpenAPI, frontend получает отдельный snapshot. Второй постоянный editable OpenAPI в docs/specs не найден в исследованной области. Это разделение следует сохранить.
  2. Факт — нормативная документационная policy не согласована с текущим docs repo. Canonical project-documentation требует docs/features, audit snapshots и remediation registry, тогда как действующие docs instructions запрещают исследовательские отчёты и используют тематические страницы. Наибольшая польза — согласовать норму, а не восстановить старые деревья (SPEC-001).
  3. Факт — архивная метка не доказывает завершение. reconcile-hourly-investment-sync находится в archive с 10 unchecked tasks и Completion Evidence о завершении. Установленные native archive и стандартный skill допускают confirmation для incomplete tasks; проектная spec обещает более строгий запрет. Причина конкретного архивирования UNVERIFIED, противоречие сохранённых records подтверждено (SPEC-002).
  4. Факт — обновлённые cross-cutting docs сосуществуют с устаревшим текущим объяснением. Обзор портфеля описывает минутную свежесть и прежний refresh, страница акций — прежний background-reference путь рядом с online appendix. Это current-doc drift, а не основание переписывать исторический ADR 017 (SPEC-003).
  5. Факт — основной specs router пропустил несколько текущих продуктовых тем. В AI_INDEX отсутствуют прямые входы в банковские карты, hourly sync, data sync, online reference и value history. Это затрудняет адресное чтение требований после недавних поставок (SPEC-004).
  6. Факт и риск — одинаковые OpenAPI copies не закрывают target compatibility. У скринера опубликованная schema теряет additionalProperties: false и lot.minimum: 1 из target contract. Прочитанный parity test сравнивает генератор с runtime metadata, не с target. Реальная выдача некорректного lot и обработка неизвестного поля в живом pipeline не проверены (SPEC-005).

Итог: пять подтверждённых локальных findings уровня P2; P0/P1 в этом scope не установлены. Массовое переписывание docs, сокращение стандартных OpenSpec skills, удаление archives или новый documentation generator не обоснованы. Runtime/CI экономия не измерена; ожидаемая польза — меньше ошибочных решений и повторного выяснения authority.

3. Inventory & coverage

Метрики и метод подсчёта

Объект Результат Метод и границы
Canonical capability specs 30 git ls-files 'openspec/specs/*/spec.md' и количество строк через rg -c '.'; tracked specs в данном checkout
Change metadata 62 Tracked openspec/changes/*/.openspec.yaml; 61 путь под archive/, 1 вне archive
Active change stock-screener Единственная metadata вне archive; schema v2, created 2026-10-10
Docs Markdown 50 git ls-files '*.md' и rg -c '.'; включая README, AGENTS, CONTRIBUTING, CHANGELOG и исторический отчёт
ADR records 17 Tracked adr/*.md, имена с числовым префиксом; adr/README.md исключён
Прямые canonical links в AI_INDEX 16 rg --only-matching 'openspec/specs/[^)]+/spec\.md' AI_INDEX.md и количество строк; это число ссылок, не оценка всей косвенной достижимости
Unchecked tasks в выбранном reconciliation archive 10 rg -c '^- \[ \]' .../tasks.md; только этот файл, не все архивы
Checked tasks активного скринера 8 rg -c '^- \[x\]' openspec/changes/stock-screener/tasks.md; checkbox не доказывает acceptance

Это inventory по tracked путям и адресная содержательная выборка. Полный semantic review всех 30 specs, 61 archives и 50 Markdown-файлов не выполнялся. Число файлов не использовано как доказательство избыточности.

Source-of-Truth Authority Matrix

Знание Authority и статус Owner / consumer Что доказывает и чего не доказывает
Intent текущей обычной задачи Прямой запрос пользователя; current Пользователь → implementation owner Задаёт scope; не запускает SDD автоматически (specs/AGENTS.md:3–6)
Intent OpenSpec change proposal.md; draft/approved определяется явным решением Change Owner → Analyst/engineers Наличие файла не доказывает approval
Сохранённое behavioral requirement specs/openspec/specs/*/spec.md; нормативный current store Product/System Analyst, для процесса Engineering Owner → реализация/review Согласованная норма; может оказаться устаревшей или противоречивой
Поведение ещё не закрытого change Active delta specs; target Change Owner/Analyst → affected engineers и QA До sync/archive не является автоматически canonical current capability
Target interface Change-local system-analysis/contracts/; target, после archive historical System Analyst + producer/consumer owners Планирует межсистемный contract; не второй постоянный current OpenAPI
HTTP shape реализации Backend controllers/DTO/Swagger metadata; current Backend → consumers, generator, HTTP tests Генерация отражает metadata, не автоматически все фактические response branches
Публикуемый OpenAPI backend/openapi.json; generated, Git-ignored по локальной policy Backend → явная передача consumer Совпадение файла с consumer не доказывает происхождение от текущего source
Consumer contract frontend/src/shared/api/spec/openapi.json; versioned snapshot Frontend → generated types и client Локальный предоставленный вход; не второй независимо редактируемый API design
Generated transport types frontend/src/shared/api/generated/schema.d.ts; derived Generator → frontend source/typecheck Производны от snapshot; не runtime-validation произвольного ответа
Current architecture/product explanation docs/architecture, domains, integrations, glossary; current Автор затронутого изменения → contributor/support Самостоятельное объяснение; расхождение с code/spec требует обозначения
Architectural rationale docs/adr; historical decision с current/superseded частями Engineering Owner → будущий change История решения; Accepted baseline не является полным current reference
Реальный механизм Source/config/Prisma schema; current checkout Owner соответствующего module/slice → инженеры Позволяет вывести поведение; не подтверждает deployment или все runtime cases
Regression / acceptance proof Assertions и наблюдённый результат на нужном revision Developer tests + QA/reviewer Зелёный structural/parity gate не подменяет semantic acceptance
Completion record Archived completion-evidence.md; historical evidence Finalization owner → reviewer/contributor Должен отделять observed факты, ограничения и незавершённую работу
Coding/process instructions Repo-local AGENTS и conventions; current локальная policy Owner repo → участники разработки Не обязаны читать соседний checkout; конфликт с canonical process spec остаётся предметом согласования

Основания: specs/README.md:3–31, specs/openspec/config.yaml:17–43,55–69, docs/CONTRIBUTING.md:7–26,58–79,122–144, backend/.ai/conventions/http-api.md:69–88, frontend/.ai/conventions/data.md:15–33.

Фактический OpenSpec lifecycle

  • Legacy wealth-ledger-sdd, schema version 5: proposal → specs → design → tasks → apply. Выбранный банковский archive действительно сохраняет legacy .openspec.yaml.
  • Default/new wealth-ledger-sdd-v2, schema version 8: proposal → specs → system-analysis → design + qa-analysis → docs-impact → tasks → apply. У stock screener и reconciliation archive выбрана v2.
  • V2 schema отдельно задаёт observable delta, target contract, internal design, system QA и docs promotion. skip_specs: true предусмотрен для отсутствия behavioral delta; фальшивый Requirement не требуется (specs/README.md:14).
  • Native delta application обнаруживает change-local specs и сопоставляет их canonical target paths: $OPENSPEC/dist/core/specs-apply.js:67–103. Archive вызывает тот же механизм и имеет отдельный skip-specs путь: $OPENSPEC/dist/core/archive.js:1158–1169.
  • Project docs/config требуют semantic verification и docs delivery до archive; native incomplete-task confirmation не является такой проверкой. Различие — SPEC-002.
  • Скринер имеет implementation и docs в текущих commits, но остаётся active. Само отсутствие canonical stock-screener/spec.md не finding: approvals/независимая QA и готовность Finalization в этой сессии не подтверждались. Автоматический sync/archive не предлагается.

Spec-to-Implementation Traceability Sample

Выборка risk-based: последняя реализованная v2 функция, недавно архивированное системное изменение границы чтения и legacy денежная функция. Она проверяет разные стадии lifecycle и разные consumers, но не репрезентативна для всех функций.

Use case / requirement Design / ADR / contract Реализация и consumer Test proof, прочитанный статически Docs / результат
Скринер: полный каталог, совместные фильтры, отдельный выпуск, стабильные страницы — active stock-screener/specs/stock-screener/spec.md:7–76 Active system-analysis/analysis.md:24–57; design.md:37–67; target OpenAPI:7–66,92–177. ADR обоснованно N/A (docs-impact.md:22–24) Backend stock.controller.ts:85–109 → stock-screener.service.ts:65–109; selector:21–105. Frontend StocksPage.vm.ts:29–55,58–115 использует generated routes Service tests:40–77 проверяют неизменный asOf, 30+1 страницу, повторный search, пустоту и ownership/revision; HTTP stocks.e2e-spec.ts:65–105; frontend page tests:71–86,127–172. Не запускались docs/domains/instruments/stocks.md:31–53 и docs/architecture/http-api.md:24–33 отражают новый поток. Target constraints теряются в schema — SPEC-005. Active status сохранён
Локальное чтение Portfolio независимо от hourly attempt — canonical portfolio-view/spec.md:9–16,96–124, hourly-investment-sync/spec.md:27–40 Reconciliation archive: target envelope и docs-impact:14–19; ADR 019:9–29 portfolio.service.ts:55–110,113–198 читает local access/repository и наблюдение hourly; consumer contract schema.d.ts:1051 задаёт resource envelope tbank-local-reads.e2e-spec.ts:167–234 публикует snapshot, затем проверяет warm GET без дополнительных GetAccounts/metadata/decrypt и отсутствие revision/token в JSON. Не доказывает весь scheduler portfolio-loading.md:10–22,34–43 и freshness page:3–12,40–60 актуальны по выбранной границе. Overview не приведён к ним — SPEC-003; archive task evidence противоречив — SPEC-002
Value history: точка только полной оценки, без нового публичного чтения — portfolio-value-history/spec.md:8–28 ADR 019:17–26; reconciliation docs-impact:45–50 сознательно не создаёт публичную страницу истории portfolio.repository.ts:116–183: fenced transaction, upsert snapshot, условная запись points по attempt/currency tbank-value-history.e2e-spec.ts:125–201 проверяет две валюты и отсутствие points при неизвестной цене. Suite не запускался; scheduler в setup подменён (:47–53) Отсутствие history UI/doc tutorial не дефект: публичный read не требуется. Нужно различать внутренние points и отсутствующий пользовательский график, не обещать новую функцию
Карты: расходы/возвраты/net, возврат в своём периоде, исключение переводов — manual-bank-cards/spec.md:448–492 Legacy add-manual-bank-cards/design.md:82–126; постоянный ADR N/A допустим, storage rationale остаётся в Design и общих ADR Controller bank-cards.controller.ts:127–130 → get-bank-summary.use-case.ts:12–37 → bank-card.calculations.ts:59–111; DTO consumer schema.d.ts:810–827 Domain test:74–137 проверяет отрицательный net и исключение transfers/topups; frontend BankSummary.view.test.tsx:9–33 показывает три точных итога. Не запускались docs/domains/cards/overview.md:80–97 объясняет три суммы и месяцы возврата. В этой выборке семантика согласована; отсутствие прямого входа в spec — SPEC-004

В таблице использованы следующие корни сокращённых paths:

  • Canonical requirements: specs/openspec/specs/; активный скринер: specs/openspec/changes/stock-screener/; reconciliation archive: specs/openspec/changes/archive/2026-10-09-reconcile-hourly-investment-sync/; банковский Design: specs/openspec/changes/archive/2026-10-09-add-manual-bank-cards/design.md.
  • Backend stocks: backend/src/modules/investments/instruments/stocks/presentation/stock.controller.ts, application/stock-screener.service.ts, application/stock-screener.service.spec.ts, domain/stock-screener-selection.rules.ts относительно того же stocks/.
  • Backend Portfolio: backend/src/modules/investments/portfolio/application/portfolio.service.ts, backend/src/modules/investments/portfolio/infrastructure/portfolio.repository.ts.
  • Backend banking: backend/src/modules/banking/bank-cards/presentation/bank-cards.controller.ts, backend/src/modules/banking/bank-cards/application/get-bank-summary.use-case.ts, backend/src/modules/banking/bank-cards/domain/bank-card.calculations.ts, backend/src/modules/banking/bank-cards/domain/bank-card.calculations.spec.ts.
  • Backend HTTP/SQLite suites: backend/test/stocks.e2e-spec.ts, backend/test/tbank-local-reads.e2e-spec.ts, backend/test/tbank-value-history.e2e-spec.ts.
  • Frontend stock source/tests: frontend/src/pages/stocks/ui/StocksPage/StocksPage.vm.ts, frontend/src/pages/stocks/ui/StocksPage/StocksPage.test.tsx; банковский test: frontend/src/entities/bank-card/ui/BankSummary/BankSummary.view.test.tsx; transport types: frontend/src/shared/api/generated/schema.d.ts.
  • Docs: docs/domains/portfolio/flows/portfolio-loading.md, docs/architecture/cross-cutting/data-freshness.md, docs/adr/019-hourly-reads-and-online-instrument-reference.md.

Фактическая успешность всех перечисленных tests в этом аудите UNVERIFIED.

Current vs Historical Document Ledger

Документ / группа Статус Consumer / disposition
specs/AI_INDEX.md current router Используется AGENTS для точного выбора spec; актуализировать продуктовые входы, SPEC-004
specs/openspec/specs/project-documentation/spec.md current normative location, часть содержания устарела Согласовать conflicting норму, SPEC-001; не объявлять историческим молча
specs/openspec/specs/openspec-authority-and-lifecycle/spec.md current process spec при явно выбранном SDD Сохранить approvals и boundaries; отделить проектный preflight от native guarantees, SPEC-002
specs/openspec/changes/stock-screener/** active target; approval/acceptance status unknown Сохранять; checked tasks не дают автоматического права Finalization
.../archive/2026-10-09-reconcile-hourly-investment-sync/** historical planning/evidence, contradictory completion Сохранить исходную историю; установить disposition и закрыть ambiguity вне read-only archive, SPEC-002
.../archive/2026-10-09-add-manual-bank-cards/design.md historical Design Сохранять исходные решения и старые paths; «реализация не начата» в preimplementation Design не current-doc bug
docs/domains/portfolio/overview.md, docs/domains/instruments/stocks.md current explanations с drift Исправить current claims, SPEC-003; не превращать страницу в migration diary
docs/architecture/cross-cutting/data-freshness.md, docs/domains/portfolio/flows/portfolio-loading.md current, более новая модель Сохранить в качестве входа для semantics; не копировать целиком во все домены
docs/adr/017-local-tbank-reads-and-background-sync.md historical, superseded части отмечены KEEP: :3–15 явно направляют к ADR 018/019 и current freshness
docs/adr/019-hourly-reads-and-online-instrument-reference.md accepted current architectural decision KEEP: определяет новую границу; не доказывает каждую ветвь runtime
docs/adr/020-hourly-sync-verification-evidence.md historical synthetic measurement KEEP полезные условия и ограничения :7–24,36–42. Не переносить цифры в production SLA; отсутствие повторного измерения не делает исторический результат дефектом
docs/code-quality-review.md dated historical audit, явно разрешённое исключение KEEP: :5–16 датируют отчёт, :34–36 фиксируют прямое исключение пользователя. Не применять запрет docs-аудитов ретроспективно
Внешние docs links на fixed commit revision-bound reference Не считать broken только из-за старого SHA. Для current route обозначать характер ссылки; remote availability не проверена

Duplication/Drift Register

Register ID Copies / consumers Вывод Disposition
DR-01 Canonical project-documentation ↔ docs AGENTS/CONTRIBUTING ↔ v2 Docs Impact Конфликт размещения и обязанности создавать материалы, а не просто похожие слова SPEC-001
DR-02 Archive tasks.md ↔ Completion Evidence ↔ canonical archive blocking requirement Противоречивое завершение выбранного change; установленный native flow допускает иной lifecycle SPEC-002
DR-03 Portfolio overview ↔ актуальные flow/freshness ↔ source TTL; stocks body ↔ online appendix ↔ handler Разные поколения текущего объяснения, практический false expectation SPEC-003
DR-04 AI_INDEX ↔ canonical product capabilities Пять выбранных product topics не имеют прямого router entry; все 14 отсутствующих links автоматически дефектами не объявляются SPEC-004
DR-05 Target screener YAML ↔ backend DTO/generated JSON ↔ frontend JSON/types Ослаблены два machine-readable ограничения; совпадение publisher/consumer copies не закрывает target review SPEC-005
DR-06 Backend generated JSON ↔ frontend snapshot ↔ generated TS Обоснованные producer artifact и consumer derivatives, не конкурирующий editable authority KEEP
DR-07 Immutable archives/ADR ↔ current docs Историческая копия сохраняет rationale; удаление ради DRY уничтожает полезную историю KEEP
DR-08 openspec-authority-and-lifecycle/spec.md:380–426 и specs/README.md:3,14 Canonical spec содержит одноразовую sequencing/pilot obligation, README сохраняет legacy-transition заметку при отсутствии legacy active metadata в inventory INVESTIGATE: проверить завершённость перехода у Engineering Owner; не rewrite archive и не менять lifecycle автоматически

Documentation Minimal Baseline

Минимум определяется потребностью читателя, не числом файлов или требованием «документ на каждый метод».

Читатель / задача Достаточный существующий вход Что должно остаться
Новый участник docs/README.md → overview.md, glossary.md, architecture Context/Container Задачи продукта, доменные различия, владельцы данных и внешние системы
Реализатор use case specs/AI_INDEX.md → точный canonical requirement; при явном SDD — selected change Проверяемый outcome, ошибки, границы денег/доступа; без обязательного code listing
Разработчик repo Локальные AGENTS/README/conventions frontend/backend Bootstrap, собственный публичный контракт и локальные проверки; независимость от соседнего checkout
Support / диагностика сумм docs/domains/portfolio/how-to/investigate-discrepancy.md, domain data-reference, freshness Происхождение цифры, неизвестное vs ноль, source/client state, безопасная диагностика
Operations / восстановление docs/architecture/deployment.md, Container storage/recovery Подтверждённая topology, сохранность SQLite/секретов, update/rollback и ограничения
Изменение API Backend DTO/OpenAPI + frontend snapshot; при v2 — change-local target Producer/consumer responsibilities, nullable/required/errors и согласованный переход
Обоснование решения docs/adr/README.md → конкретный ADR, при локальном решении archived Design Исторические alternatives/consequences и явная supersession
Завершение SDD Выбранные tasks + отдельное observed completion/review evidence Различие implementation, structural validation и независимой acceptance

В просмотренных актуальных тематических входах не обнаружена необходимость добавлять placeholder pages, четыре жанра Diátaxis на каждую область или второй ручной docs index. Не требуется копировать OpenAPI/DTO в Markdown или переносить каждую change sequence в current docs.

4. Findings

SPEC-001 — Canonical documentation policy конкурирует с действующими правилами docs

  • Decision = SIMPLIFY
  • Severity = P2
  • Confidence = High
  • Evidence: specs/openspec/specs/project-documentation/spec.md:47–52,77–108,141–150,171–189; docs/AGENTS.md:3–14; docs/CONTRIBUTING.md:19–26,43–50,81–99; specs/openspec/config.yaml:22–26,37–43; specs/AI_INDEX.md:33–35.
  • Claim: одна canonical spec нормативно требует деревья и документы, которые current docs policy исключает или заменяет. Это разрешается только owner decision, а не автоматическим выбором «код/AGENTS важнее spec».
  • Current mechanism: project-documentation требует отдельный feature document в docs/features, immutable audit snapshots и remediation registry в docs. Docs считает своим содержанием системное объяснение, ADR и тематические страницы, запрещает отчёты исследований и второй архитектурный guide. V2 Docs Impact уже использует новую тематическую модель. Consumer — Finalization/review явно выбранного SDD и contributor, которому нужно обновить docs.
  • Impact / actual cost: следование старой spec создаёт ненужные copies, следование новой policy оставляет формальное расхождение acceptance. Impact unmeasured: не измерено, сколько change reviews это задержало.
  • Why now: recent screener и hourly changes уже документированы в domains/ и architecture/; старый обязательный docs/features не является фактическим owner.
  • Minimum change: Engineering Owner согласует небольшой delta для project-documentation: требовать актуального тематического объяснения, достижимого из existing router, и ADR по значимому решению. Убрать предписание старых paths и обязанность держать аудиты/remediation в docs; сохранить completion evidence в OpenSpec и наблюдаемую проверку. Остальные process specs пересматривать только при подтверждённом аналогичном конфликте.
  • Guarantees at risk: discoverability, сохранность rationale, proof фактической поставки и разграничение planning/current facts. Их сохранить как outcomes; не заменить всё необязательной фразой «при необходимости».
  • Counterarguments / trade-offs: AI_INDEX называет process specs историей и необязательной процедурой обычной разработки; это снижает ежедневный impact. Однако файл остаётся в normative canonical location и содержит SHALL/MUST. Само устаревание исторического audit не finding; docs/code-quality-review.md имеет прямое пользовательское исключение.
  • Verification or rollback: сопоставить согласованную новую норму с существующим screener Docs Impact и банковской страницей: пользовательский поток, ограничения, ссылка на owner и current state находятся без второго дерева. Выполнить native spec validation и docs link checks при будущей правке. Откат — revert только нового согласованного delta; history не удалять.
  • Effort = S
  • Related finding IDs: SPEC-003, SPEC-004.

SPEC-002 — Архивированное завершение противоречит Tasks и обещанному project gate

  • Decision = FIX
  • Severity = P2
  • Confidence = High для противоречия records; причина архивирования неизвестна.
  • Evidence: specs/openspec/changes/archive/2026-10-09-reconcile-hourly-investment-sync/tasks.md:5–67; там же completion-evidence.md:5–18,24–41,52–57; specs/openspec/specs/openspec-authority-and-lifecycle/spec.md:148–161; specs/README.md:28–31; .agents/skills/sdd/openspec-archive-change/SKILL.md:45–70,81–106,207–214; $OPENSPEC/dist/core/archive.js:1105–1130. Git commit 329d66e767f7e89a40b96bb8e5b499f39f67feb6 добавляет этот archive и evidence.
  • Claim: canonical archive содержит 10 незавершённых implementation/docs tasks, но evidence объявляет реализацию и независимое review завершёнными. Native/standard workflow не гарантирует более строгую проектную норму «никакого confirmation override».
  • Current mechanism: Completion Evidence перечисляет backend/frontend/docs commits и successful checks, но оставляет specs delivery как pending archive commit и будущую Finalization. Все десять checkbox остались [ ]. Project spec запрещает archive с unchecked tasks; native CLI допускает confirmation/--yes, стандартный skill также допускает продолжение с warning. Operation guidance явно prompt-level, не enforceable check. Consumer — reviewer/new contributor, использующий archive для terminal status и acceptance trace.
  • Impact / actual cost: нельзя однозначно отличить незавершённую поставку от ошибки bookkeeping по её собственным records; положительный review record не является доказательством закрытия checklist. Impact unmeasured. Runtime недопоставка из этого факта не выводится.
  • Why now: это свежий системный v2 change, который задаёт модель чтения всему инвестиционному разделу; его archive используется как подтверждение уже promoted requirements.
  • Minimum change: Finalization Owner устанавливает по delivery commits и исходному review, какие outcomes реально завершены. Для read-only archive сохранить оригинал и добавить явный disposition в текущий локальный вход/новый согласованный record со ссылкой на исторический archive и найденный commit. На будущей Finalization явно проверять отсутствие unchecked implementation tasks и наличие observed review перед стандартным archive; документировать, что это project-controlled preflight, а не обещание native CLI. Не добавлять самописный verifier ради одного record.
  • Guarantees at risk: независимость acceptance, artifact approvals, связь с реальными checks и неизменность архивного evidence. Не ставить [x] задним числом только на основании нынешнего code; не выдавать отсутствие Tasks completion за доказанный runtime bug.
  • Counterarguments / trade-offs: commit добавлен общей SDD migration; возможно, checklist не перенесли после уже состоявшегося delivery. Native confirmation соответствует стандартной семантике, это не дефект OpenSpec. Такой контрпример объясняет mechanism, но не делает contradictory evidence самодостаточным.
  • Verification or rollback: read-only сверка десяти outcomes с cited commits и review context, явное заключение Finalization Owner; для следующего change reviewer подтверждает project preflight отдельно от structural status. Rollback нового disposition — revert нового explanatory record, original archive остаётся неизменным. Факт применения override/конкретного archive command — UNVERIFIED.
  • Effort = M
  • Related finding IDs: SPEC-003.

SPEC-003 — Current domain docs сохраняют прежнюю refresh/reference модель

  • Decision = FIX
  • Severity = P2
  • Confidence = High
  • Evidence: docs/domains/portfolio/overview.md:82–93; docs/domains/portfolio/flows/portfolio-loading.md:10–22,34–43; docs/architecture/cross-cutting/data-freshness.md:3–12,40–60; docs/domains/instruments/stocks.md:149–169,194–199; specs/openspec/specs/portfolio-view/spec.md:96–124; specs/openspec/specs/online-instrument-information/spec.md:8–17; backend/src/integrations/tbank/tbank-source.policy.ts:3–8; backend/src/modules/investments/portfolio/application/portfolio.service.ts:55–58,88–108; backend/src/modules/investments/instruments/stocks/presentation/stock.controller.ts:112–120; backend/src/modules/investments/instruments/stocks/application/stock-catalog.service.ts:59–70; backend/src/modules/investments/instruments/application/catalog-discovery.service.ts:143–166.
  • Claim: как минимум две current domain pages дают старые expectations, противоречащие current specs, более новым тематическим docs и изученному handler flow.
  • Current mechanism: Portfolio overview говорит о минутной свежести и refresh зависимостей независимо от свежести. Canonical spec и source TTL используют 60 минут; обычный portfolio GET local/read-only. Stocks body обобщает SQLite reuse metadata/discovery/company и отсутствие ожидания RPC, а его же online appendix сообщает противоположную модель. Обычный stock detail без sync=observe передаёт observe=false и ждёт upstream getShare. Consumer — читатель docs/README.md:18–19,38, попадающий сначала на domain explanation, а не на appended correction.
  • Impact / actual cost: contributor/support может ожидать ручной broker refresh или доступность online detail из локального кэша при upstream outage. Новая cross-cutting page не устраняет неверное утверждение в текущей точке входа. Impact unmeasured; фактические обращения support не измерены.
  • Why now: модель заменена hourly/online изменениями 9 октября, а страница акций уже обновлялась для скринера 11 октября.
  • Minimum change: адресно заменить старые Portfolio freshness/refresh предложения и разделить на странице акций online detail/company/search от сохраняемых financial resources. Оставить один непротиворечивый current смысл и ссылку на owner freshness page; удалить либо встроить дублирующий appendix после сверки. Отдельно различить внутренние value points и отсутствие публичного history UI, не добавляя новую пользовательскую функцию.
  • Guarantees at risk: fallback сохранённых финансовых данных, local read без personal work, исключения first-load, точность времён и connection access. Не расширять online-only правило на portfolio/quotes/candles или объявлять все SQLite rows актуальным справочником.
  • Counterarguments / trade-offs: stocks body может частично описывать сохранённый observe compatibility path. Сейчас scope этого описания не указан и оно сформулировано для обычного чтения; default handler выбирает другой путь. Отсутствие публичного history endpoint корректно. ADR 017 явно historical/superseded и не нуждается в таком cleanup.
  • Verification or rollback: пройти README → Portfolio/Stocks → freshness/HTTP API, сверить утверждения с двумя указанными call chains и existing tests. Для text-only исправления достаточно local Markdown/link checks и semantic review; application build не требуется. Откат — revert current-page diff, без изменения ADR/archives.
  • Effort = S
  • Related finding IDs: SPEC-001, SPEC-002.

SPEC-004 — Specs router не покрывает недавние current product capabilities

  • Decision = FIX
  • Severity = P2
  • Confidence = High
  • Evidence: specs/AGENTS.md:8–12; specs/AI_INDEX.md:15–35; specs/openspec/specs/manual-bank-cards/spec.md:10–31,448–492; specs/openspec/specs/hourly-investment-sync/spec.md:8–40; specs/openspec/specs/online-instrument-information/spec.md:8–17; specs/openspec/specs/portfolio-value-history/spec.md:8–28; specs/openspec/specs/tbank-data-sync/spec.md:9–37; specs/README.md:14.
  • Claim: рекомендуемый exact-target router не содержит прямых entries для пяти текущих тем: manual bank cards, hourly investment sync, T-Bank data sync, online instrument information, portfolio value history.
  • Current mechanism: AGENTS направляет читателя в AI_INDEX, который содержит прежний список product specs и общий footer о process/history. Новые capability paths присутствуют в canonical store после migration commit, но в таблице отсутствуют. Consumer — implementer/reviewer банковского сценария либо изменения refresh boundary, которому требуется не загружать всё дерево.
  • Impact / actual cost: повышается вероятность чтения только старого portfolio-view/tbank-connection или необходимости дополнительного поиска по archive вместо точного current requirement. Impact unmeasured; время и agent tokens не замерялись.
  • Why now: карточки и hourly/online модель недавно доставлены; банковская функция является самостоятельной областью без T-Bank и не выводится из старых brokerage topics.
  • Minimum change: добавить пять коротких topic → canonical path entries в существующую таблицу; при необходимости связать их с имеющимися Portfolio/Connection rows. Не делать полный второй индекс всех process/archive файлов. Stock screener не представлять canonical capability до согласованного sync/Finalization.
  • Guarantees at risk: точный выбор behavioral source, отличие historical/active/current, самостоятельность store без соседних repos. Ссылки должны оставаться локальными и lazy.
  • Counterarguments / trade-offs: requirements имеют косвенные textual references и доступны поиском, поэтому это не доказательство полной недостижимости. Девять остальных отсутствующих direct links относятся к process/foundation темам и не требуют автоматического включения. Это локальный router gap, не потребность в глобальном knowledge graph.
  • Verification or rollback: проверить существование targets и маршрут AGENTS → AI_INDEX → нужный requirement; local git diff --check. Нужный контекст теперь находится в одном entry, без scan всего store. Откат — revert только добавленных rows.
  • Effort = S
  • Related finding IDs: SPEC-001, SPEC-003.

SPEC-005 — Скринер теряет target constraints при публикации OpenAPI

  • Decision = FIX
  • Severity = P2
  • Confidence = High для machine-readable drift; runtime consequences не подтверждены.
  • Evidence: specs/openspec/changes/stock-screener/system-analysis/contracts/stock-screener.openapi.yaml:92–120,174–177; specs/openspec/changes/stock-screener/design.md:61–67; specs/openspec/changes/stock-screener/tasks.md:25–29; backend/src/modules/investments/instruments/stocks/presentation/stock.dto.ts:29–75,85–105; frontend/src/shared/api/spec/openapi.json:7495–7527,7570–7573; frontend/src/shared/api/generated/schema.d.ts:1285–1314; backend/test/openapi-contract.e2e-spec.ts:108–156; frontend/scripts/check-openapi.mjs:15–34.
  • Claim: published/consumer schema не сохраняет два конкретных ограничения change-local target: Criteria additionalProperties: false и nullable Item lot с minimum: 1.
  • Current mechanism: Criteria DTO описывает поля, но не публикует запрет дополнительных properties; Item DTO сообщает integer/nullable без minimum. Generated JSON повторяет эту metadata и совпадает с backend JSON на диске. Frontend types производны от snapshot. Backend parity сравнивает generator output с configured runtime OpenAPI, frontend check — generated types со snapshot; ни одна из прочитанных этих проверок не сравнивает target и published semantics. Consumer — инженер/инструмент, использующий OpenAPI для request validation или анализа допустимых response values.
  • Impact / actual cost: опубликованное описание допускает более широкий shape запроса и более широкий диапазон lot, чем target; producer/consumer agreement не доказывает сохранение согласованного ограничения. Impact unmeasured. Фактический запрос с unknown field и фактический ответ с lot 0/negative в этом аудите не воспроизводились.
  • Why now: task 2.2 активного скринера уже отмечена выполненной, хотя delivery plan отдельно требует semantic compatibility до закрытия change. Уточнить расхождение дешевле до Finalization.
  • Minimum change: Backend/Analyst owners согласуют судьбу обоих constraints: восстановить metadata/необходимую boundary guarantee либо явно изменить target с reapproval, если ограничения намеренно неприменимы. Использовать existing HTTP/parity suite для адресной проверки и повторно передать published artifact frontend. Не вводить общую contract registry, второй OpenAPI generator или mandatory cross-checkout CI.
  • Guarantees at risk: request trust-boundary validation, nullable/unknown distinction, page semantics, совместимость consumers. Исправление schema не должно незаметно изменять runtime acceptance или создавать breaking response contract.
  • Counterarguments / trade-offs: runtime может уже обеспечивать строгие значения независимо от Swagger; это не устраняет неполноту published contract, но может ограничить impact. TypeScript не выражает все JSON Schema bounds. Добавленное logoName — отдельное additive изменение и само по себе не объявлено дефектом. Понятие semantic compatibility может допускать отдельные расширения, но такое согласование не найдено в прочитанных artifacts.
  • Verification or rollback: на будущей правке сравнить конкретные criteria/item schema nodes target ↔ fresh generated OpenAPI и выполнить targeted HTTP checks для неизвестного property и lot boundary, затем существующие backend parity/frontend type checks. Если runtime менять не нужно, это должно быть подтверждено отдельно. Откат — revert согласованного metadata/target diff и вернуть предыдущий consumer artifact; не исправлять generated TS вручную.
  • Effort = S
  • Related finding IDs: none.

5. DELETE / SIMPLIFY / KEEP / INVESTIGATE

Decision Объект Основание / сохранённая гарантия
DELETE Нет безопасно доказанной группы документов для полного удаления Не удалять архивы, ADR или полезные explanation pages по размеру либо возрасту
SIMPLIFY Старые обязательные docs/features и audit/remediation prescriptions SPEC-001: оставить проверяемый docs outcome и единственный owner вместо восстановления параллельных деревьев
SIMPLIFY Повторяющиеся old/new current refresh/reference paragraphs В рамках SPEC-003 после замены ошибочных утверждений оставить один current смысл и адресные ссылки
KEEP 30 canonical specs как store, без общего переписывания Нормативное behavior и деньги/access acceptance остаются доступны; число файлов не доказательство bloat
KEEP Active stock-screener и его target YAML Не архивировать автоматически по checked tasks; target отдельно от permanent API authority
KEEP Legacy schema и metadata исторических changes Их graph/approvals нельзя поменять переходом default schema
KEEP ADR 017 с explicit supersession, ADR 019, historical measurement ADR 020 Сохранить причины, ограничения измерений и путь к current state
KEEP Backend-generated OpenAPI → отдельный frontend snapshot → generated TS Деривативы имеют разных consumers, гарантируют самостоятельность репозиториев
KEEP Точная денежная арифметика, DB transactions/CAS, replay/idempotency и connection fencing Документационное упрощение не удаляет механизмы денег, публикации и доступа
KEEP Независимый semantic/QA review и explicit approval Structural success и archive location не дают acceptance proof
INVESTIGATE Disposable transition/pilot constraints в canonical process spec DR-08: owner должен отделить завершённый rollout от enduring invariant; сейчас history не менять
INVESTIGATE Конкретная причина unchecked reconciliation archive SPEC-002: выяснить по original delivery/review, не по догадке о запуске CLI
FIX Current router, docs drift, completion disposition, target constraints SPEC-002–005; точечные изменения вместо нового tooling

Стандартные OpenSpec artifacts/skills — оставить без изменения

Этот аудит не предлагает менять установленный OpenSpec CLI, его встроенные schemas/templates или стандартные skills:

  • openspec-new-change, openspec-propose, openspec-continue-change, openspec-ff-change;
  • openspec-apply-change, openspec-update-change, openspec-verify-change;
  • openspec-sync-specs, openspec-archive-change, openspec-bulk-archive-change;
  • openspec-explore, openspec-onboard.

Inventory paths: .agents/skills/sdd/openspec-*/SKILL.md. Подробно прочитан archive skill только для проверки lifecycle semantics; пошаговая стоимость skill loading здесь не исследуется.

Сохранить стандартные proposal.md, delta spec.md, design.md, tasks.md, .openspec.yaml, операции ADDED/MODIFIED/REMOVED/RENAMED, canonical Purpose/Requirements/Scenario, native sync/archive и history. Project-owned v2 system-analysis, qa-analysis, docs-impact, target contracts и выбранные sequences также сохраняются по schema. Обнаруженный конфликт строжайшего project gate решается project-level disposition/preflight, а не правкой стандартного skill.

6. Cost & benefit

Finding / решение Класс ожидаемой пользы Фактическое измерение Обязательная граница при изменении
SPEC-001 Maintenance, cognitive load, предотвращение лишних документов not measured Сохранить полезное объяснение, rationale, navigation и проверяемый completion
SPEC-002 Надёжность evidence, меньше повторного восстановления delivery state not measured Не подменить independent acceptance, не переписать original archive
SPEC-003 Cognitive load, меньше неверных assumptions о freshness/outage recovery not measured Read locality, fallback, online/local distinction, правильные времена
SPEC-004 Navigation, agent tokens и человеческое время адресного чтения not measured Один существующий индекс; не обязательное чтение всего store
SPEC-005 Стабильность публичного контракта, меньше будущего integration rework not measured Совместимость target/published/consumer и trust-boundary validation
KEEP artifact copies/archives Сохранение contract autonomy и historical rationale not measured Не превращать экономию файлов в потерю доказательств или cross-repo CI dependency

Runtime и CI minutes savings этим аудитом не установлены. Для text-only/router исправлений application build не требуется; это граница проверок, а не измеренное ускорение. Новые dependencies не предлагаются, удаление dependencies не обосновано.

Ponytail-audit: компактный complexity результат

  • shrink: заменить старые обязательные docs trees единым проверяемым outcome в existing thematic owner. [specs/openspec/specs/project-documentation/spec.md] — SPEC-001.
  • shrink: убрать конкурирующий old/new current refresh/reference пересказ после semantic correction; оставить current explanation и ссылку. [docs/domains/portfolio/overview.md; docs/domains/instruments/stocks.md] — SPEC-003.
  • yagni: не добавлять новый manual index, schema registry, docs generator или собственный archive verifier; existing router и адресная проверка покрывают выявленный scope.

net: сокращение строк не измерено; 0 dependencies определены как кандидаты на удаление. Нельзя честно назвать -N lines до согласованного конкретного diff.

7. Top actions

Quick wins

  1. SPEC-003: исправить current Portfolio/Stocks refresh/reference объяснение, сохранив explicit разделение online reference и local financial read. Value высокое, риск низкий, effort S.
  2. SPEC-004: добавить пять точных product-topic entries в existing AI_INDEX. Value высокое для новых сценариев, риск низкий, effort S.
  3. SPEC-001: согласовать и сократить устаревшие documentation-path prescriptions до тематического docs outcome. Value среднее/высокое, риск локальный, effort S; это изменение нормы, поэтому нужен Engineering Owner.

Требуют подтверждения owner / contract / delivery

  1. SPEC-002: установить фактический disposition reconciliation archive по commits и original independent review; сохранить original records, явно обозначить расхождение. Value высокое для доверия к completion, effort M.
  2. SPEC-005: перед Finalization скринера проверить и согласовать два target constraints; исправить metadata либо получить target reapproval и подтвердить адресными checks. Value среднее/высокое, effort S.
  3. SPEC-002: для следующей Finalization явно отделить project preflight от native structural/archive success в существующем процессном входе. Не обещать недоказанную машинную блокировку и не менять стандартные skills.

Новый ADR не обязателен для редакционных правок или router entries. ADR/process decision потребуется только если owner решит изменить enduring archive/authority semantics; это отдельное согласованное решение, не автоматический результат аудита.

8. Cross-audit signals

  • Audit 08 — Test Quality: сила late-response proof в frontend/src/pages/stocks/ui/StocksPage/StocksPage.test.tsx:175–237; здесь использован только как ограничение test evidence, без повторного расследования.
  • Audit 07 — API/Data Flow: фактический hourly/read runtime и source failure branches в backend/src/modules/investments/tbank-sync/, operations/, upcoming-events/; documentation mismatch не объявлен доказательством нового runtime дефекта.
  • Audit 14 — AI workflow: частота загрузки большого schema/context и стандартных OpenSpec skills; specs/openspec/schemas/wealth-ledger-sdd-v2/schema.yaml, .agents/skills/sdd/. Token-cost исследование в audit 15 не выполнялось.
  • Audit 11 — Validation/CI: реальные merge/branch-protection settings и исполнение required acceptance gates; наличие документации и workflow не подтверждает remote enforcement. Сетевая проверка не выполнялась.

9. Open questions / verification plan

Вопрос, меняющий решение Статус Самая дешёвая проверка
Завершены ли все десять outcomes reconciliation или только перенос checklist неполон? UNVERIFIED Сопоставить outcomes с cited delivery commits и оригинальным review; Engineering/Finalization Owner даёт явный disposition. Без этого нельзя поставить checkbox задним числом
Был ли использован confirmation override/native command или archive перенесли при migration иначе? UNVERIFIED Проверить существующий finalization context/PR, без повторного archive или новых инструментов. Это меняет причину SPEC-002, но не противоречие records
Какой документационный scope теперь нормативен при явном SDD? Требует owner decision Engineering Owner сопоставляет SPEC-001 со screener Docs Impact и текущим CONTRIBUTING; согласует минимальный delta
Являются ли дополнительные properties и lot minimum намеренно изменённым target contract? UNVERIFIED Backend/System Analyst проверяют два конкретных schema nodes и approval context; выбрать metadata correction либо reapproval
Runtime действительно отвергает неизвестное screener field и не выдаёт lot вне target? UNVERIFIED При работе над SPEC-005 — адресный HTTP boundary check и управляемый источник; не реальный T-Invest token
Backend artifact свежий относительно текущих handlers, generated TS полностью соответствует snapshot? UNVERIFIED для нового запуска При contract fix: после локального nvm use --silent existing openapi:generate/test:openapi-contract, затем frontend openapi:check. Эти команды здесь не запускались, генерация нарушила бы read-only режим
Legacy-transition и одноразовый UI pilot полностью завершены? UNVERIFIED Проверить disposition соответствующих archived changes у Engineering Owner; если закрыты, отдельный approved delta удаляет лишь завершённые transition obligations
Доступны ли внешние fixed-commit URLs? UNVERIFIED При необходимости проверить только используемые URL в обычной сетевой среде. Их старый revision сам по себе не broken link

Проверка самого результата

  • До записи четыре repo и root имели пустой git status --porcelain=v1; git diff --check завершился успешно.
  • Markdown отчёта проверен существующим локальным markdownlint из docs после активации .nvmrc; проверяется только итоговый файл, без установки и auto-fix. Первый запуск выявил три MD029 из-за продолжения нумерации после подзаголовка; нумерация исправлена, повторный запуск — PASS, exit 0.
  • После записи отдельно проверены HEAD/status/diff четырёх repos и root. Единственная созданная запись — этот ignored root report; приложение, specs store и docs не изменены.
  • Semantic/Boy Scout review отчёта: у каждого finding есть source/consumer, механизм, контрпример, minimum change и сохранённые гарантии; current/historical/active не смешаны, исторические измерения не представлены как новые, отсутствие runtime proof помечено. Report не создаёт нового process authority.
  • Проверка Markdown не подтверждает работу приложения, рендер существующих Mermaid-диаграмм или успешность перечисленных application tests.

Команда проверки отчёта, working directory docs/:

source "$HOME/.nvm/nvm.sh" && nvm use --silent && ./node_modules/.bin/markdownlint --config .markdownlint.json -- "/Users/ksv741/Project/vibe/WealthLedger/audit-results/15-sdd-specs-and-documentation.md"

Итоговые repo checks: git rev-parse HEAD && git status --porcelain=v1 && git diff --check отдельно в каждом checkout — исходные SHA, пустой status, exit 0. git check-ignore audit-results/15-sdd-specs-and-documentation.md подтвердил, что отчёт находится в ignored root area.

10. Машинно-считываемая таблица для консолидации

ID Decision Severity Confidence Repo Files One-line impact Effort Related IDs
SPEC-001 SIMPLIFY P2 High specs,docs specs/openspec/specs/project-documentation/spec.md;docs/CONTRIBUTING.md;docs/AGENTS.md Conflicting normative documentation ownership encourages duplicate trees and ambiguous acceptance S SPEC-003,SPEC-004
SPEC-002 FIX P2 High specs specs/openspec/changes/archive/2026-10-09-reconcile-hourly-investment-sync/tasks.md;specs/openspec/changes/archive/2026-10-09-reconcile-hourly-investment-sync/completion-evidence.md;specs/openspec/specs/openspec-authority-and-lifecycle/spec.md Archived completion contradicts 10 unchecked tasks and promised project archive gate M SPEC-003
SPEC-003 FIX P2 High docs docs/domains/portfolio/overview.md;docs/domains/instruments/stocks.md Current domain explanations retain obsolete freshness and reference-refresh assumptions S SPEC-001,SPEC-002
SPEC-004 FIX P2 High specs specs/AI_INDEX.md Current product capabilities lack direct entries in the required exact-target router S SPEC-001,SPEC-003
SPEC-005 FIX P2 High backend,specs,frontend backend/src/modules/investments/instruments/stocks/presentation/stock.dto.ts;specs/openspec/changes/stock-screener/system-analysis/contracts/stock-screener.openapi.yaml;frontend/src/shared/api/spec/openapi.json Published screener schema omits two target constraints despite matching producer and consumer copies S none