25 апреля 2026
В зрелой команде архитектурная сторона обычно размечена: модули, bounded contexts, ADR, arc42-секции, OpenAPI, repo-map, AGENTS.md. Эта разметка отвечает на вопрос «как устроен код» - и работает: агент по символу попадает в файл, по эндпоинту видит контракт, по ADR понимает, почему так. Но агенту, которому ставят задачу «поправь баг на онбординге», нужен другой ответ - «что приложение умеет с точки зрения пользователя и где это в коде». Этот функциональный слой почти ни у кого не оформлен явно: он рассыпан по Jira-эпикам, Confluence-PRD, реестру feature-флагов, головам PM. Прицельного публичного решения (machine-readable feature catalog × CJM-индекс × связан с кодом × живой через CI) нет - соседние подходы закрывают только части. Статья описывает, почему пробел существенен, картирует то, что уже есть, и предлагает конкретную структуру - Operation → Job → Journey + Feature Registry + слой проблем (pain_points / constraints / unhappy_paths) - валидированную в production у одного B2B SaaS со сложной доменной моделью.
Где уже хорошо: техническая сторона размечена
Зрелая инженерная команда обычно имеет несколько слоёв документации, отвечающих на технические вопросы:
- Модули и bounded contexts (DDD, Evans, 2003) - организация кода по доменным границам.
- Architecture Decision Records (Nygard, 2011) - фиксация архитектурных решений с датой, контекстом, последствиями.
- arc42 (Starke, 2008+) - 12-секционный шаблон описания архитектуры: context view, building blocks, runtime, deployment, concepts, decisions, quality, risks, glossary.
- C4 model (Brown, 2018) - четыре уровня диаграмм: context, containers, components, code. Подробнее в C4 Model.
- OpenAPI / Protobuf - машиночитаемые контракты сервисов.
- Repo-map (Aider) или семантический индекс (Sourcegraph SCIP) - авто-производный слой символов и зависимостей.
- AGENTS.md / CLAUDE.md (Linux Foundation, 2025+) - корневой набор правил поведения для AI-агентов.
Этот стек работает. Агент по упоминанию класса попадает в файл. По эндпоинту находит контракт. По ADR понимает, почему запрос асинхронный, а не синхронный. Эта часть - решённая задача, и большая часть индустрии уже её решает теми или иными комбинациями инструментов.
Чего нет: функциональность как наблюдаемая поверхность
Проблема в том, что вся перечисленная разметка отвечает на вопрос «как устроен код». Она не отвечает на вопрос «что приложение умеет с точки зрения пользователя».
«Фича» в этой статье - не модуль и не endpoint. Фича - это наблюдаемая возможность пользователя что-то сделать в продукте: онбординг, восстановление пароля, экспорт CSV, отправка приглашения, эскалация заявки в саппорт, оплата по подписке. Единица, которую видит и обсуждает пользователь, продакт-менеджер, support-инженер, иногда юрист. Не unit of code, а unit of capability.
В типичном проекте этот слой размечен неявно. Знание о фичах живёт в:
- Jira/Linear-эпиках и тикетах - разрозненно, без связи с кодом, без machine-readable schema, с переменным качеством описаний.
- Confluence/Notion-PRD - свободный текст, оптимизированный под человека, который умеет читать «между строк».
- Реестре feature-флагов (LaunchDarkly, OpenFeature, Unleash) - только in-flight toggles, не полный inventory of capabilities.
- Головах PM и tech leads - knowledge silo, который теряется при текучке.
- Названиях файлов и папок - косвенный сигнал без гарантий и без описания границ.
- Тестах (RSpec, Cucumber, Playwright) - executable, но не сгруппированы в feature inventory.
Машиночитаемой карты «что приложение умеет → где это в коде» обычно нет. И даже когда часть знания формализована (например, есть PRD в Notion), она не связана с кодом ссылками, которые агент мог бы пройти.
Это и есть пробел. Не техническая сторона, не архитектура, не контракты - именно функциональная поверхность.
Почему агенту это критично: четыре класса провалов
Intent gap
Задачи приходят в терминах пользователя, а не в терминах сервисов. «Поправь баг на онбординге», «добавь поле в экспорт», «клиент не получает email после регистрации». Агент должен сам сообразить, в каких файлах живёт «онбординг» как фича.
Хороший DDD не помогает: bounded context Auth содержит и регистрацию, и login, и password reset, и MFA, и SSO - десятки независимых пользовательских capability. Знание о том, что онбординг = регистрация + welcome-email + первичная настройка профиля + опциональный туториал, не зафиксировано нигде. Агент это «угадывает» по grep'у и пропускает шаги.
Boundary blur
Без явных границ фичи правка либо узкая, либо размазанная. Агент правит ровно тот файл, на который указал пользователь, но забыл соседний endpoint, который тоже относится к фиче. Или наоборот - вошёл в чужую фичу под предлогом рефакторинга и сломал кусок, не имеющий отношения к задаче.
Модуль не равен фиче. Bounded context UserProfile может содержать «фичу аватаров», «фичу custom fields», «фичу импорта из LDAP» - все три имеют разные roadmap, owners, lifecycle и тесты. Без явной разметки границ фичи агент трактует «правка UserProfile» как «правка любого файла в этом модуле».
Cross-feature blindness
Две фичи делят одно событие, одну таблицу или один queue. Это типично: «новый пользователь» - событие, на которое подписаны и welcome-email, и провижининг workspace, и outbound-аналитика, и invite-flow для команды. Но это нигде не записано как первoклассный факт. Агент правит handler welcome-email и неосознанно ломает provisioning, потому что они слушают одно и то же событие с одинаковым subscription pattern.
DDD context map иногда фиксирует upstream/downstream между контекстами, но не на уровне фич. ADR фиксирует решение «использовать event-driven архитектуру» - но не «эти три фичи разделяют это событие». Без явных related_features агент не видит коллизий.
Lifecycle blindness
Фича deprecated, за флагом, в migration mode, замороженная до Q3, доступна только enterprise-tier клиентам. Это статусы, которые меняют поведение разработки: «не правь это, мы это удаляем», «это под флагом, новый код не должен это вызывать», «миграция в процессе, не трогай старый code path до завершения переноса event ledger».
Эта информация почти всегда живёт в головах. Агент пишет код против фичи, которая через две недели будет удалена. Или фиксит баг в старом code path, который уже за миграционным флагом ведёт в новую реализацию. Без явного lifecycle-поля у feature-узла агент работает в темноте.
Карта соседних референсов
Прежде чем предлагать решение, полезно зафиксировать, что уже есть, и где у каждого подхода граница.
| Подход | Что закрывает | Чего не делает |
|---|---|---|
| Meta-repo pattern (seylox, март 2026) | Cross-repo навигация: AGENTS.md + repos.yaml + workflows/ + active-work/ | Сам автор пишет: «фокус на внутренней архитектуре, не на user-facing capabilities» |
| deliberate.codes spec (2026) | Качество одного спека: Purpose / Requirements / Scenarios, RFC 2119, явные SHALL NOT | Один спек, не inventory; нет journey, нет связности |
| Spec Kit, OpenSpec, Kiro, BMAD | Spec authoring в моменте создания фичи; EARS-нотация в Kiro | Точечные спеки, не постоянный feature catalog; брошенные после implementation |
| Backstage Software Catalog | Каталог сервисов, API, ownership, dependency graph | Сервисы и компоненты, не user-facing capabilities |
| Backstage AIContext (RFC #33575) | Попытка добавить AI-context как entity в catalog | Скиллы и rules, не функциональная карта; в обсуждении |
| Feature-flag manifests (OpenFeature, Reflag, Cloudflare Flagship) | Live-toggles с machine-readable manifest; пример - Duolingo flag-removal agent | In-flight subset, не полный inventory; вне флагов знания нет |
| Journey-mapping AI-агенты (A. Grippo и др., 2026) | Schema-first journey-data: stages, actions, touchpoints, pains, opportunities | UX-исследование, не привязано к коду; одноразовый артефакт |
| AGENTS.md, Memory Bank, SKILL.md | Корневой протокол поведения, скиллы как пакеты, persistent context | Корневой / инфраструктурный уровень, не feature catalog |
| Codified Context Infrastructure (arXiv:2602.20478) | Трёхъярусная память на 108K LOC, 283 сессии: hot constitution, domain specialists, cold knowledge | Cold-memory организована по техническим темам, не по user-facing capabilities |
| DDD bounded contexts, arc42, C4 | Архитектурная декомпозиция | Один context = десятки фич; гранулярность не та |
| User Story Mapping (Patton, 2014) | Visualization journey как backbone + walking skeleton | Стикеры на доске; не machine-readable, не привязаны к коду |
| BDD / Specification by Example (Adzic, 2011) | Gherkin как living documentation | Acceptance criteria без feature inventory и без journey-индекса |
| Capability surfaces (Schema.org BuyAction, Vercel Agent Readability) | Декларация capability для AI-агентов в вебе/коммерции | Другая среда (web), не код проекта |
Никто целиком не закрывает «machine-readable feature catalog × journey-индекс × связан с кодом × живой через CI». Это значит:
- (a) пробел реальный, а не пересказ существующего фреймворка;
- (b) если решение нужно, его придётся собирать из частей или взять структуру из условно успешной production-практики и адаптировать.
Возможный подход: Operation → Job → Journey + Feature Registry
Один из подходов, который работает в продакшене у B2B SaaS со сложной доменной моделью (учётная и налоговая практика для accounting-фирм, десятки interconnected workflows, два типа пользователей - firm-сторона и client-сторона - с разными journeys, сезонные пики нагрузки, регуляторные ограничения), - трёхуровневая иерархия + отдельный реестр фич + слой проблем.
Структура называется Business Operations Hierarchy. Текущее состояние - 17 operations, 30 jobs, happy paths размечены для всех; pain_points и метрики добавляются итеративно. Применяется как input context для AI при написании PRD, генерации продуктовых гипотез, оценке impact фич, планировании research, написании release notes, онбординге новых членов команды.
Уровень 1: Operation
Operation - это repeatable unit of work, который команда (или клиент команды) выполняет в продукте. Имеет понятный trigger, участников и outcome. Это не фича, не модуль и не endpoint - это повторяющаяся единица бизнес-активности.
Примеры из анонимного B2B SaaS: «intake документов от возвращающегося клиента», «проверка собранных данных перед началом работы», «выставление подписки и управление seat-ами», «балансировка нагрузки между членами команды».
Поля Operation:
id- стабильный семантический идентификатор (например,tax-prep.intake). Не меняется при ренеймингеname. Это якорь, на который ссылаются Jobs, Features и downstream-артефакты.name- читаемое имя.description- что делает эта operation.actor- кто выполняет: owner, manager, doer, client или комбинация.cadence- one-time / daily / weekly / monthly / seasonal / continuous / event-driven. Важна для приоритизации: сезонная операция, занимающая 3 месяца в году, и continuous - разные классы фич.features- references на узлы Feature Registry.- Метаданные приоритизации -
volume(сколько раз исполняется в период),priority_tier(P0/P1/P2),success_metric,time_to_complete.
Тип operation: service-specific (привязана к конкретной service-line) или cross-cutting (работает поверх всей платформы).
Уровень 2: Job (JTBD)
Job - это конкретная цель, которой пользователь пытается достичь в рамках operation. Формулируется в JTBD-нотации (Christensen, 2016; Ulwick, 2016): «When I [situation], I want to [action], so that [outcome]».
Пример: «When I begin intake for a returning tax client, I want to determine which tax documents are still needed, so I can request the right items upfront and move the client into preparation without unnecessary delay or back-and-forth».
Поля Job:
jtbd- JTBD-statement.actor- primary actor (часто отличается от Operation: одна Operation содержит и firm-side, и client-side jobs).trigger- что запускает job.outcome- что считается достигнутой целью.journey- happy path как ordered sequence шагов с явными actor-метками.features- references на узлы Feature Registry, которые используются в этом job.pain_points- 2-3 известных проблемы, которые пользователь испытывает в этом job. Источник: support-тикеты, user interviews, session recordings, NPS-комментарии.constraints- ограничения, которые нельзя нарушить при улучшении job (regulatory, technical, UX). Пример: «KBA mandatory для Form 8879 по требованию IRS, $1 за верификацию».unhappy_paths- 2-3 ключевых сценария, где happy path ломается. Пример: «client doesn't respond for 2+ weeks → deadline at risk → extension flow needed».adjacent_jobs- dependency-граф:blocked_by,triggers,parallel. Закрывает cross-feature blindness.- Метрики -
success_metric,volume,time_to_complete.
Уровень 3: Journey
Journey - это ordered sequence шагов от trigger до outcome. Каждый шаг помечен actor-меткой: [Firm], [Doer], [Manager], [Owner], [Client], [System]. Это и есть тот самый «декомпозированный CJM», который запускает агента в коде.
Пример (фрагмент):
[Firm] Review prior-year client context (last year's return, account tags, notes)
[Firm] Identify which documents are needed this year
[Firm] Build the document checklist - manually or using AI from prior-year return PDF
[Firm] Send organizer with checklist to the client
[Client] Receive notification (email / push / portal to-do)
[Client] Open organizer, fill out questionnaire
[Client] Upload documents and match them to checklist items
[Client] Submit organizer
[Firm] Review submitted organizer; verify uploaded documents
[Firm] If documents are missing - send a Client Request for the specific items
[Client] Upload missing documents
[Firm] Confirm all documents received; move job to next pipeline stage
Каждый шаг - точка, к которой можно подвесить связь с кодом, тестом, флагом, ADR. Когда задача формулируется как «баг на шаге 7 онбординга для возвращающегося клиента», агент перестаёт угадывать.
Feature Registry: фичи как переиспользуемые capability
Здесь принципиально - фичи живут в отдельном реестре, и Jobs ссылаются на них, не дублируя описание. Одна фича (например, «Document Checklist», «Pipeline Automations», «Client Requests») переиспользуется в десятках jobs, и дублировать её описание - значит обречь систему на drift.
Detail Feature Registry разбирается в следующей секции.
Слой проблем
Главное отличие этой структуры от обычного «journey-документа» - не happy path, а слой проблем: pain_points, constraints, unhappy_paths. Без него агент генерирует generic-гипотезы («давайте автоматизируем шаг 3»). С ним - агент попадает в реальные боли пользователей.
Метаданные приоритизации (volume, priority_tier, success_metric) дают агенту основания не «починить всё подряд», а сосредоточиться на P0-операциях с высоким volume. Это превращает feature catalog из справочника в инструмент prioritization.
Принципы living document
Принципы применимы к любой реализации, не только к описанной структуре:
- Living, not snapshot. Документ обновляется при каждом значимом изменении продукта. Update-триггеры: launch новой фичи, новая service-line, research-результаты, изменения бизнес-модели, ежеквартальный review.
- One owner, many contributors. Один владелец - человек из research-команды, отвечающий за консистентность; contributors - PMs (правят jobs/journeys при шиппинге фич), researchers (добавляют pain_points/unhappy_paths), support (приносят топ pain_points из тикетов), data analysts (volume, success_metric).
- Depth over breadth. 10 jobs с полным набором полей (pain_points, constraints, unhappy_paths, metrics) ценнее 50 jobs с happy-path-only.
- Review как для кода. Минорные правки - self-merge с уведомлением owner; новый Job или Operation - review от owner + PM из релевантной области; структурные изменения - review от owner + product lead.
- Use as input context for AI, not as a final artifact. Документ не заменяет PRD, research-plans или roadmap. Он - context, который делает все эти артефакты лучше.
- Не дублировать то, что живёт в других системах. Каталог содержит references на features, тикеты, research-отчёты, не их копии.
Что класть в feature-узел Feature Registry
Operation → Job → Journey - функциональная карта. Feature Registry - то, что связывает её с кодом.
Узел Feature Registry - YAML-документ (markdown с frontmatter тоже подходит, но YAML агенты парсят надёжнее) со следующими полями. Каждое поле обосновано через конкретный класс агентских вопросов, которые оно закрывает.
id- стабильный идентификатор (например,document-checklist,client-requests).name- читаемое имя.purpose- 1-2 предложения о том, что фича умеет с точки зрения пользователя. Закрывает: «что это за фича, в чём её ценность» - агент использует, когда видит ссылку из Job.lifecycle- active / deprecated / behind_flag / migrating / planned. Закрывает lifecycle blindness: если deprecated - агент знает, что новый код не должен зависеть от этой фичи.triggers- что запускает выполнение фичи (action пользователя, событие, scheduled job).primary_flow- happy path в Gherkin-нотации (Given/When/Then) или EARS (Mavin et al., 2009). Закрывает: «как фича работает в общих чертах» - агент использует для test generation и regression checks.acceptance_criteria- набор Given/When/Then-сценариев. Маппится 1:1 на исполняемые тесты (Cucumber / RSpec feature specs / Playwright). Закрывает: «как доказать, что фича работает» - агент использует для генерации тестов и регрессионной проверки после правки.files_likely_affected- массив glob-паттернов или путей:app/services/document_checklist/**,app/views/web/checklists/*.erb,spec/features/document_checklist_spec.rb. Закрывает intent gap и boundary blur. Агент сразу знает, где правда живёт.contracts- API endpoints, события, флаги, schema. Закрывает: «что эта фича публикует наружу» - критично для cross-feature blindness.invariants- утверждения, которые должны оставаться истинными (например, «подписанный документ не может быть удалён», «один клиент не может иметь два активных engagement letter»). Закрывает: «что нельзя ломать» - агент проверяет diff против инвариантов.failure_modes- известные режимы провала (timeout, partial write, race condition, retry storm) и стратегии (retry, circuit breaker, compensation).concurrency_risks- явные race conditions с другими фичами. Закрывает: «что может пойти не так и кто это уже встретил».bounded_context_ref- ссылка на DDD context, в котором живёт фича (auth,billing,documents).adr_refs- ссылки на ADR, объясняющие, почему фича сделана именно так.flag_refs- ссылки на feature flags из реестра.related_features- другие фичи, которые делят события, таблицы или флоу. Закрывает cross-feature blindness.owners- команда / person / Slack-канал.metrics(опционально) - ссылки на дашборды (grafana://...) или ключевые метрики (success_rate,latency_p95).
Пример узла (полный):
id: document-checklist
name: Document Checklist
purpose: |
Интерактивный список документов, который firm запрашивает у client для конкретного engagement.
Client видит список в портале/мобильном приложении, помечает items как N/A или uploads
документ; firm видит progress в реальном времени.
lifecycle: active
triggers:
- "[Firm] sends organizer with checklist to client"
- "[Firm] sends standalone Client Request"
primary_flow:
- given: client receives notification with checklist
when: client opens checklist in portal
then: each item shows status (pending / uploaded / N/A)
acceptance_criteria:
- id: ac-1
given: client uploads document via mobile app
when: document is matched to checklist item
then: item moves to "uploaded" status and firm sees notification
- id: ac-2
given: client marks item as N/A
when: firm reviews the checklist
then: N/A items show explanation if provided
files_likely_affected:
- app/services/document_checklist/**
- app/models/checklist_item.rb
- app/views/clients/checklists/*.erb
- spec/features/document_checklist_spec.rb
contracts:
api:
- POST /api/v2/checklists/:id/items/:item_id/upload
- PATCH /api/v2/checklists/:id/items/:item_id/mark_na
events_published:
- checklist.item_uploaded
- checklist.completed
events_consumed:
- documents.received
- clients.invited
invariants:
- completed checklist cannot be modified by client without firm reopening it
- item marked as "uploaded" must reference a valid Document record
failure_modes:
- mode: client uploads photo instead of PDF
impact: downstream OCR fails
strategy: validate MIME-type at upload, prompt for re-upload
- mode: pipeline automation fires twice (idempotency violation)
impact: duplicate notifications to client
strategy: idempotency key on automation execution
concurrency_risks:
- feature: pipeline_automations
risk: automation modifies checklist while client is editing
- feature: client_requests
risk: duplicate request for same document via different surface
bounded_context_ref: documents
adr_refs:
- ADR-0017-checklist-storage-model
- ADR-0024-event-driven-notifications
flag_refs:
- checklist_v2_layout (rollout)
related_features:
- organizers
- client_requests
- pipeline_automations
owners:
team: documents-platform
slack: "#documents-team"
metrics:
- dashboard: grafana://document-checklist/overview
- kpi: completion_rate_within_7_days
Хранение - YAML или Markdown с frontmatter. Markdown полезен, если хочется в один файл совместить машиночитаемый header и человеческое описание (этот же приём использует Anthropic SKILL.md - frontmatter + body). Структурированную часть агенты парсят через frontmatter; описание - читают как контекст.
Где живёт и как сшивается с DDD, arc42, ADR
Функциональный слой (Operations + Jobs + Feature Registry) - не самостоятельный документ, который заменяет архитектурную документацию. Он - connector, ссылающийся:
- Вверх - на L4 (AGENTS.md, SKILL.md): эти артефакты говорят, как агенту работать вообще; функциональный слой говорит, что и где работать.
- Вбок - на Jira/Linear через MCP: Job
tax-prep.intake.job-1ссылается на тикеты PROJ-123, PROJ-456 (актуальные in-flight changes); агент через MCP подтягивает их content, не дублируя в YAML. - Вниз - на DDD bounded context (
bounded_context_ref), ADR (adr_refs), OpenAPI (черезcontracts), тесты (черезacceptance_criteria→ Cucumber/RSpec feature spec), файлы (черезfiles_likely_affected).
Функциональный слой не дублирует архитектуру; он индексирует её и репозиторий по user-facing координатам.
Где физически хранить
Вариант A: рядом с кодом, в репозитории.
/operations/
tax-prep/
intake/
job-1.yaml # JTBD + journey + pain_points
job-2.yaml
review/
job-1.yaml
/features/
document-checklist.yaml
client-requests.yaml
organizers.yaml
Плюсы: близость к коду, одно PR-ревью на изменение фичи и узла, schema-валидация в CI. Минусы: разные команды могут пройти мимо, если у них собственная репозиторная структура.
Вариант B: отдельный репозиторий-каталог.
Плюсы: один источник истины поверх многих репозиториев, проще CI и валидация. Минусы: drift между каталогом и кодом - физическая дистанция увеличивает шансы рассинхрона.
Вариант C: Backstage AIContext (RFC #33575).
Плюсы: интеграция с уже существующим developer portal (если он есть), ownership/lifecycle бесплатно. Минусы: lock-in, RFC всё ещё в обсуждении, схема не оптимизирована под user-facing capabilities.
Слой качества: ATAM-utility tree поверх journey
Functional layer отвечает на «что делает». Quality layer отвечает на «насколько хорошо это нужно делать». Без quality scenarios агент не видит, какие правки опасны.
ATAM (Architecture Tradeoff Analysis Method, Bass / Klein / Kazman, CMU/SEI-2000-TR-004) предлагает строить utility tree:
quality
├── performance
│ ├── latency
│ │ └── scenario: онбординг шаг 7 (upload) - p95 < 3s
│ └── throughput
├── security
│ ├── data_isolation
│ │ └── scenario: client A не видит документы client B
│ └── identity
└── availability
└── scenario: intake-flow доступен в 99.9% случаев
Сценарии привязаны к конкретным шагам journey, не к модулям. Зачем это агенту?
Когда агент правит шаг 7 онбординга, он видит, что это sensitivity point по latency p95 < 3s. Это меняет его поведение: он не предлагает синхронный сетевой вызов в этом code path, не добавляет блокирующий external API call без timeout, не вводит N+1 query в горячий путь.
Минимальный артефакт - YAML с quality scenarios:
quality_scenarios:
- id: qs-onboarding-latency
quality: performance.latency
scenario: |
Когда client загружает документ на шаге 7 онбординга,
от click до confirmation должно проходить <3s p95
sensitivity_for:
- operation: tax-prep.intake
job: job-2
step: 7
sources:
- dashboard: grafana://onboarding/upload-latency
- SLO: docs/slos/onboarding.md
- id: qs-document-isolation
quality: security.data_isolation
scenario: |
Документы client A не должны быть доступны client B
ни через API, ни через portal, ни через no-login link
sensitivity_for:
- feature: document-checklist
- feature: client-requests
- feature: no-login-links
Полный utility tree - амбициозно. Минимум, который реально работает: 5-7 сценариев на самые critical journey-шаги. Большинство правок не затрагивает quality-границ; те, которые затрагивают, должны явно столкнуться с этим артефактом.
Как держать слой живым
Документация дрейфует. Без механик поддержания feature catalog умрёт за квартал и станет хуже, чем его отсутствие, - агент будет генерировать ответы по устаревшим данным.
Пять механик:
1. Schema-валидация в CI
JSON Schema на формат YAML-узлов (Operation, Job, Feature) и проверка в CI. PR не проходит, если узел сломан или не имеет обязательных полей. Это превращает feature catalog из «wiki» в код-уровень артефакт.
2. Drift-detector
Cron / CI-job, который раз в неделю сравнивает узлы Feature Registry с реальностью:
- Узел ссылается на
files_likely_affected: app/services/foo/**, но в этом пути нет коммитов за 90 дней - флаг (либо узел устарел, либо фича действительно стабильна; владелец проверяет). - Узел ссылается на
flag_refs: checklist_v2_layout, но флаг не существует в реестре - флаг (либо узел устарел, либо флаг удалён без обновления узла). - Узел ссылается на
adr_refs: ADR-0017, но ADR помечен как superseded - флаг.
Детектор не блокирует, он создаёт issues в трекере для owner.
3. PR-чеклист или агентский pre-commit
В definition of done для feature launches: «обновить узел Feature Registry». Можно автоматизировать: pre-commit hook проверяет, что diff в app/services/document_checklist/** сопровождается diff в features/document-checklist.yaml. Если нет - предупреждение (не блокировка, чтобы не мешать в крайних случаях).
Альтернатива - агентский pre-commit: agent читает diff, читает текущий узел, проверяет, нужно ли обновить, и если да - предлагает diff в YAML.
4. Один owner + структурированные contributors
Без явной роли owner документ умирает. У уровня Operation/Job - один owner на всю иерархию (обычно из research-команды). У Feature Registry - один owner на узел или на группу узлов (часто team owner фичи).
Contributors структурированы по типу контента:
- PMs - jobs / journeys при шиппинге фич;
- researchers - pain_points, unhappy_paths;
- support / CS - топ pain_points из тикетов и feedback;
- data analysts - volume, success_metric, метрики.
5. Quarterly review
Раз в квартал owner проходит по всему документу и делает sanity check. Это не replacement для непрерывного обновления, а защита от того, что некоторые узлы перестали обновляться, а никто не заметил.
Production-evidence
- 17-Operation / 30-Job иерархия + слой проблем + pricing/volume метаданные работает в проде у одной B2B SaaS-команды (учётная и налоговая практика, сложная домен-модель). Уровень адопции - PRD-генерация, research-планирование, release-notes пишутся с этим документом как input context, и команда отчитывается о существенном повышении качества AI-сгенерированных артефактов: AI работает с конкретными journey steps и pain points, а не с абстрактными feature descriptions.
- Codified Context Infrastructure (arXiv:2602.20478): на 108K LOC C# проекте за 283 development sessions показано, что трёхъярусная архитектура памяти масштабируется там, где single-file подход не работает. Структура отличается от feature catalog (cold-memory у них организована по техническим темам), но принципы - schema-first, structured content over prose, owners на artifacts - те же. Подробнее в статье об инфраструктуре контекста для агентов.
- Duolingo flag-removal agent (2024): production-агент, который читает реестр feature flags и удаляет dead flags из кодовой базы. Узкий случай feature-catalog-driven работы, но доказательство, что machine-readable feature surface работает в проде, а не только в research-papers.
Антипаттерны
- «У нас есть DDD, этого хватит». Bounded context структурирует код, но не functional surface. Один auth-context = регистрация + login + reset + MFA + SSO + session management. Это разные фичи с разным lifecycle, разными pain points, разными owners. DDD - необходимое, не достаточное. Подробнее про DDD - в статье о Domain-Driven Design.
- «У нас всё в Jira / Linear». Тикеты не имеют schema, не привязаны к коду через стабильные refs (links - это weak refs), фрагментированы по эпикам, чьи границы кто как нарисовал. MCP-мост помогает агенту читать тикеты, но не превращает тикеты в feature inventory.
- Happy-path-only документация. Без pain_points, constraints, unhappy_paths AI генерирует generic-гипотезы. «Давайте автоматизируем шаг 3» - типичный output, когда AI не знает, что 40% клиентов на шаге 3 промахиваются. Слой проблем превращает документ из «как должно быть» в «как реально».
- «Задокументируем сразу всё». 50 jobs с happy-path-only хуже, чем 10 jobs с полными полями. Глубина выигрывает у ширины: agent работает с ограниченным числом высококачественных узлов лучше, чем с большим числом средне-качественных.
- Свободный текст там, где должна быть структура. Agents парсят tables, code blocks, structured fields лучше, чем prose. Если поле имеет фиксированный набор значений (
lifecycle: active|deprecated|behind_flag|migrating) - это enum, не свободный текст. - Tool lock-in. «Всё в Backstage», «всё в Kiro», «всё в Notion». Один инструмент - одна точка отказа. Структурированный YAML рядом с кодом + автоматический mirror в developer portal - устойчивее, чем монолит на одном вендоре.
- Дублирование того, что живёт в других системах. Узел Feature не содержит копию description из Jira. Он содержит reference. Иначе - два источника истины, которые разойдутся.
agent_hintsкак догадка автора. Поля типаfiles_likely_affected,failure_modes,concurrency_risksценны, когда они построены на реальной статистике (commits, incidents, postmortems). Если автор додумал их «на глаз», агент работает на догадках, и доверие к узлам падает.- Документ-снимок вместо живого документа. Без update-триггеров, owner и review feature catalog умрёт. Хуже, чем его отсутствие: агент будет генерировать ответы по устаревшим данным с уверенным тоном.
Минимальная рабочая система
Чтобы не утонуть в попытке покрыть всё сразу, начинать стоит с одного critical journey и 5-7 фич.
Шаг 1: выбрать одну critical operation
P0 для бизнеса, частая (high volume), с понятным actor и outcome. Примеры: онбординг нового пользователя, основной checkout flow, intake critical-path. Не выбирать low-traffic admin-флоу - там пробел не виден агенту, потому что задачи редко приходят в этом периметре.
Шаг 2: разметить 1 Operation + 2-3 Jobs
YAML-файл на каждую сущность. Поля минимум: id, name, description, actor, cadence, features (refs). Для Jobs: jtbd, journey (happy path с actor-метками), features. Pain points / constraints / unhappy paths - в следующей итерации.
Шаг 3: Feature Registry с 5-7 узлами
Узлы для фич, упомянутых в jobs. Поля минимум: id, name, purpose, lifecycle, files_likely_affected, acceptance_criteria (хотя бы 1-2). Остальные поля (contracts, invariants, failure_modes) - итеративно по мере того, как реально проявляются.
Шаг 4: schema-валидация в CI
JSON Schema на формат + один CI-job, который запрещает мерджить YAML, не проходящий валидацию. Это превращает узлы из «wiki» в проверяемый артефакт.
Шаг 5: один pilot ADR-as-rule
Один ADR с companion executable rule (стиль archgate / AgDR). Например: «Все uploads в hot-path онбординга должны иметь timeout < 5s» - превращается в lint-rule, который агент проверяет автоматически.
Шаг 6: один drift-job
Cron-job раз в неделю: для каждого узла Feature проверить, что files_likely_affected содержат коммиты за последние 90 дней, и что flag_refs существуют в реестре флагов. Создаёт issues для owner, не блокирует.
Шаг 7: подключить MCP-мосты
К Jira/Linear (актуальные in-flight тикеты по jobs/features), к GitHub (PRs и issues по features), к реестру флагов (current state). Это нулевая стоимость авторинга, поэтому первый шаг.
Через месяц - решение продолжать или сворачивать
Метрики, по которым решать (грубо):
- Сколько раз документ был использован как input context при PRD-writing / research-planning (ритуальная метрика).
- Сколько gen-AI-задач в выбранной operation попали в правильные файлы с первого раза (косвенная мера качества).
- Сколько раз schema-валидация поймала рассинхрон или drift-detector нашёл устаревший узел (мера живости).
Если месяц прошёл, и эти метрики растут - расширять (следующая operation, больше узлов). Если документ обновляется реже коммитов в фичах, которые он описывает, - сворачивать или менять модель (возможно, проблема в process, а не в формате).
Что не делать на старте:
- arc42 на все 12 секций сразу;
- полный event-storming со всеми bounded contexts;
- миграция всей PM-документации в Backstage;
- покрытие всех 30 фич по фиче-в-неделю.
Источники
Теория и practice
- Patton, J. User Story Mapping: Discover the Whole Story, Build the Right Product (O'Reilly, 2014).
- Adzic, G. Specification by Example (Manning, 2011); Impact Mapping (Provoking Thoughts, 2012).
- Brandolini, A. Introducing EventStorming (Leanpub, 2018).
- Christensen, C. M. Competing Against Luck (Harper Business, 2016) - JTBD canon.
- Ulwick, A. Jobs to Be Done: Theory to Practice (IDEA Bite Press, 2016).
- North, D. «Introducing BDD» (Better Software, March 2006).
- Nygard, M. Documenting Architecture Decisions (2011, blog).
- Bass, L., Klein, M., Kazman, R. «ATAM: Method for Architecture Evaluation» (CMU/SEI-2000-TR-004, 2000).
- Evans, E. Domain-Driven Design (Addison-Wesley, 2003).
- Mavin, A. et al. «Easy Approach to Requirements Syntax» (RE'09, 2009).
- Brown, S. The C4 Model for Software Architecture (c4model.com, 2018+).
- Starke, G. arc42 (arc42.org, 2008+).
Industry artefacts and tools
- AGENTS.md - Linux Foundation / Agentic AI Foundation, 2025+.
- SKILL.md (Anthropic) - frontmatter + body skill packages.
- Memory Bank (Cline).
- Codified Context Infrastructure (arXiv:2602.20478).
- Backstage AIContext - RFC issue #33575.
- Spec Kit (GitHub).
- OpenSpec, Kiro (AWS), BMAD Method - spec-driven development frameworks.
- AgDR / Agent Decision Records.
- Archgate CLI - executable rules для ADR.
- OpenFeature, Cloudflare Flagship, Reflag.
- Duolingo flag-removal agent.
- Aider repo-map.
- Sourcegraph SCIP / Amp.
- Anthropic «Effective context engineering for AI agents» (2025).
Adjacent references
- Meta-repo pattern (seylox, март 2026).
- Writing specs for AI coding agents (deliberate.codes, 2026).
- AI agent for journey mapping (A. Grippo, Medium, март 2026).
- Vercel «Agent Readability Specification».
- Schema.org BuyAction + x402 - agentic commerce protocol.
Смежные статьи на сайте
- Context Engineering - как устроено контекстное окно как ресурс и failure modes контекста.
- SDLC для AI-агентов - где функциональный слой лежит в spec-driven процессе разработки.
- Инфраструктура контекста для AI-агентов - трёхъярусная архитектура памяти из Codified Context.
- C4 Model - архитектурная нотация на четырёх уровнях.
- Domain-Driven Design - bounded contexts как соседний слой.
- Spec Kit - конкретный фреймворк spec-driven development.
- Как устроен Claude Code - skills и rules как L4 слой.