From 08c951a4b82f8a20c899bbed622c4c62da2845fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 18 Jun 2026 23:33:54 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D1=80=D0=B0=D0=B7=D0=B2=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=D1=87=D0=B8=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=BA=D0=B0=20marketing-plugin=20=E2=80=94=208=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B2=D1=8B=D0=BA=D0=BE=D0=B2=20(=D1=80=D0=BE=D1=83?= =?UTF-8?q?=D1=82=D0=B5=D1=80-=D1=80=D0=B5=D0=B5=D1=81=D1=82=D1=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Эпик роутер-реестр, спека v2 §2, этап 1. Зонтик marketing-plugin развёрнут в 8 карточек-навыков + 8 под-узлов #74a..#74h. - 8 карточек: brand-review, campaign-plan, competitive-brief, content-creation, draft-content, email-sequence, performance-report, seo-audit - nodes.yaml: узел #74 → #74a..#74h; триггеры распределены (классификация marketing + маркетинговый контент → content-creation как resolver C1); ADR-015 boundary на content-creation; ссылка L16 обновлена - marketing-plugin:competitive-brief отличён от product-management:competitive-brief - зонтик убран; registry-load.test: 130 узлов / 122 active Регрессия (без 5 pre-existing node:test файлов): 4365 passed, exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../contracts/marketing-plugin.contract.json | 12 -- ...rketing-plugin__brand-review.contract.json | 29 +++++ ...keting-plugin__campaign-plan.contract.json | 29 +++++ ...ng-plugin__competitive-brief.contract.json | 29 +++++ ...ing-plugin__content-creation.contract.json | 29 +++++ ...keting-plugin__draft-content.contract.json | 29 +++++ ...eting-plugin__email-sequence.contract.json | 29 +++++ ...g-plugin__performance-report.contract.json | 29 +++++ .../marketing-plugin__seo-audit.contract.json | 29 +++++ docs/registry/nodes.yaml | 122 ++++++++++++++++-- docs/registry/splitting-inventory.md | 4 +- tools/registry-load.test.mjs | 10 +- 12 files changed, 349 insertions(+), 31 deletions(-) delete mode 100644 docs/registry/contracts/marketing-plugin.contract.json create mode 100644 docs/registry/contracts/marketing-plugin__brand-review.contract.json create mode 100644 docs/registry/contracts/marketing-plugin__campaign-plan.contract.json create mode 100644 docs/registry/contracts/marketing-plugin__competitive-brief.contract.json create mode 100644 docs/registry/contracts/marketing-plugin__content-creation.contract.json create mode 100644 docs/registry/contracts/marketing-plugin__draft-content.contract.json create mode 100644 docs/registry/contracts/marketing-plugin__email-sequence.contract.json create mode 100644 docs/registry/contracts/marketing-plugin__performance-report.contract.json create mode 100644 docs/registry/contracts/marketing-plugin__seo-audit.contract.json diff --git a/docs/registry/contracts/marketing-plugin.contract.json b/docs/registry/contracts/marketing-plugin.contract.json deleted file mode 100644 index 6e9aaad..0000000 --- a/docs/registry/contracts/marketing-plugin.contract.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "skill": "marketing-plugin", - "kind": "external", - "needs": ["маркетинговая задача (контент/кампания/SEO/email/бриф)"], - "produces": ["маркетинговый артефакт (контент/email-цепочка/SEO-аудит/бриф/отчёт)"], - "constraints": ["первичный resolver C1 (8 скилов)", "ADR-015: MKT3 решатель, материал — marketingskills #75; MKT2 НЕ product-management #42"], - "preview-form": "outline", - "defaults": ["скил под тип задачи C1"], - "key-decisions": ["какой маркетинг-скил под задачу"], - "acceptance-criteria": ["маркетинговый артефакт готов и таргетирован"], - "source": { "version": "n/a", "hash": "0000000000000000000000000000000000000000000000000000000000000000", "path": "" } -} diff --git a/docs/registry/contracts/marketing-plugin__brand-review.contract.json b/docs/registry/contracts/marketing-plugin__brand-review.contract.json new file mode 100644 index 0000000..80aadbb --- /dev/null +++ b/docs/registry/contracts/marketing-plugin__brand-review.contract.json @@ -0,0 +1,29 @@ +{ + "skill": "marketing-plugin:brand-review", + "kind": "external", + "needs": [ + "контент для проверки против голоса/гайда бренда" + ], + "produces": [ + "ревью с флагами по severity + before/after-фиксы" + ], + "constraints": [ + "под-навык зонтика marketing (первичный resolver C1)", + "ADR-015: решатель; материал — marketingskills #75; РФ-специфика — marketing-ru" + ], + "preview-form": "outline", + "defaults": [ + "brand-review — проверка контента на консистентность голоса" + ], + "key-decisions": [ + "что отклоняется от гайда" + ], + "acceptance-criteria": [ + "отклонения помечены с фиксами" + ], + "source": { + "version": "n/a", + "hash": "0000000000000000000000000000000000000000000000000000000000000000", + "path": "" + } +} diff --git a/docs/registry/contracts/marketing-plugin__campaign-plan.contract.json b/docs/registry/contracts/marketing-plugin__campaign-plan.contract.json new file mode 100644 index 0000000..7d50df8 --- /dev/null +++ b/docs/registry/contracts/marketing-plugin__campaign-plan.contract.json @@ -0,0 +1,29 @@ +{ + "skill": "marketing-plugin:campaign-plan", + "kind": "external", + "needs": [ + "маркетинговая цель (запуск/лидген/awareness)" + ], + "produces": [ + "бриф кампании: цели, аудитория, каналы, контент-календарь, метрики" + ], + "constraints": [ + "под-навык зонтика marketing (первичный resolver C1)", + "ADR-015: решатель; материал — marketingskills #75; РФ-специфика — marketing-ru" + ], + "preview-form": "outline", + "defaults": [ + "campaign-plan — план кампании по неделям" + ], + "key-decisions": [ + "каналы и messaging" + ], + "acceptance-criteria": [ + "кампания структурна и измерима" + ], + "source": { + "version": "n/a", + "hash": "0000000000000000000000000000000000000000000000000000000000000000", + "path": "" + } +} diff --git a/docs/registry/contracts/marketing-plugin__competitive-brief.contract.json b/docs/registry/contracts/marketing-plugin__competitive-brief.contract.json new file mode 100644 index 0000000..e8f92dd --- /dev/null +++ b/docs/registry/contracts/marketing-plugin__competitive-brief.contract.json @@ -0,0 +1,29 @@ +{ + "skill": "marketing-plugin:competitive-brief", + "kind": "external", + "needs": [ + "конкурент(ы) для маркетингового анализа" + ], + "produces": [ + "позиционирование, messaging-гэпы, угрозы, battlecards" + ], + "constraints": [ + "под-навык зонтика marketing (первичный resolver C1)", + "ADR-015: решатель; материал — marketingskills #75; РФ-специфика — marketing-ru" + ], + "preview-form": "outline", + "defaults": [ + "competitive-brief — маркетинговый конкурентный анализ" + ], + "key-decisions": [ + "где gap и angle" + ], + "acceptance-criteria": [ + "бриф покрывает позиционирование и гэпы" + ], + "source": { + "version": "n/a", + "hash": "0000000000000000000000000000000000000000000000000000000000000000", + "path": "" + } +} diff --git a/docs/registry/contracts/marketing-plugin__content-creation.contract.json b/docs/registry/contracts/marketing-plugin__content-creation.contract.json new file mode 100644 index 0000000..23de546 --- /dev/null +++ b/docs/registry/contracts/marketing-plugin__content-creation.contract.json @@ -0,0 +1,29 @@ +{ + "skill": "marketing-plugin:content-creation", + "kind": "external", + "needs": [ + "маркетинговая контент-задача (blog/social/email/landing/PR/case)" + ], + "produces": [ + "фреймворки и шаблоны контента под канал" + ], + "constraints": [ + "под-навык зонтика marketing (первичный resolver C1)", + "ADR-015: решатель; материал — marketingskills #75; РФ-специфика — marketing-ru" + ], + "preview-form": "outline", + "defaults": [ + "content-creation — основной resolver контента C1" + ], + "key-decisions": [ + "канал и формат контента" + ], + "acceptance-criteria": [ + "контент таргетирован под канал" + ], + "source": { + "version": "n/a", + "hash": "0000000000000000000000000000000000000000000000000000000000000000", + "path": "" + } +} diff --git a/docs/registry/contracts/marketing-plugin__draft-content.contract.json b/docs/registry/contracts/marketing-plugin__draft-content.contract.json new file mode 100644 index 0000000..416a1aa --- /dev/null +++ b/docs/registry/contracts/marketing-plugin__draft-content.contract.json @@ -0,0 +1,29 @@ +{ + "skill": "marketing-plugin:draft-content", + "kind": "external", + "needs": [ + "готовность драфтить маркетинг-контент" + ], + "produces": [ + "драфт с кросс-платформенным форматированием" + ], + "constraints": [ + "под-навык зонтика marketing (первичный resolver C1)", + "ADR-015: решатель; материал — marketingskills #75; РФ-специфика — marketing-ru" + ], + "preview-form": "outline", + "defaults": [ + "draft-content — черновик под платформы" + ], + "key-decisions": [ + "формат под платформу" + ], + "acceptance-criteria": [ + "драфт отформатирован под каналы" + ], + "source": { + "version": "n/a", + "hash": "0000000000000000000000000000000000000000000000000000000000000000", + "path": "" + } +} diff --git a/docs/registry/contracts/marketing-plugin__email-sequence.contract.json b/docs/registry/contracts/marketing-plugin__email-sequence.contract.json new file mode 100644 index 0000000..ae6ebea --- /dev/null +++ b/docs/registry/contracts/marketing-plugin__email-sequence.contract.json @@ -0,0 +1,29 @@ +{ + "skill": "marketing-plugin:email-sequence", + "kind": "external", + "needs": [ + "цель email-последовательности" + ], + "produces": [ + "multi-email цепочка: ветвление, timing, бенчмарки" + ], + "constraints": [ + "под-навык зонтика marketing (первичный resolver C1)", + "ADR-015: решатель; материал — marketingskills #75; РФ-специфика — marketing-ru" + ], + "preview-form": "outline", + "defaults": [ + "email-sequence — проектирование email-цепочек" + ], + "key-decisions": [ + "логика ветвления и тайминг" + ], + "acceptance-criteria": [ + "цепочка спроектирована с таймингом" + ], + "source": { + "version": "n/a", + "hash": "0000000000000000000000000000000000000000000000000000000000000000", + "path": "" + } +} diff --git a/docs/registry/contracts/marketing-plugin__performance-report.contract.json b/docs/registry/contracts/marketing-plugin__performance-report.contract.json new file mode 100644 index 0000000..f552068 --- /dev/null +++ b/docs/registry/contracts/marketing-plugin__performance-report.contract.json @@ -0,0 +1,29 @@ +{ + "skill": "marketing-plugin:performance-report", + "kind": "external", + "needs": [ + "маркетинговые метрики для отчёта" + ], + "produces": [ + "отчёт: тренды, инсайты, рекомендации оптимизации" + ], + "constraints": [ + "под-навык зонтика marketing (первичный resolver C1)", + "ADR-015: решатель; материал — marketingskills #75; РФ-специфика — marketing-ru" + ], + "preview-form": "outline", + "defaults": [ + "performance-report — отчёт по метрикам кампаний" + ], + "key-decisions": [ + "какие метрики и пороги" + ], + "acceptance-criteria": [ + "отчёт даёт actionable-рекомендации" + ], + "source": { + "version": "n/a", + "hash": "0000000000000000000000000000000000000000000000000000000000000000", + "path": "" + } +} diff --git a/docs/registry/contracts/marketing-plugin__seo-audit.contract.json b/docs/registry/contracts/marketing-plugin__seo-audit.contract.json new file mode 100644 index 0000000..d2efe48 --- /dev/null +++ b/docs/registry/contracts/marketing-plugin__seo-audit.contract.json @@ -0,0 +1,29 @@ +{ + "skill": "marketing-plugin:seo-audit", + "kind": "external", + "needs": [ + "сайт/контент для SEO-аудита" + ], + "produces": [ + "SEO-аудит: keyword, тех-секция, контент-гэпы" + ], + "constraints": [ + "под-навык зонтика marketing (первичный resolver C1)", + "ADR-015: решатель; материал — marketingskills #75; РФ-специфика — marketing-ru" + ], + "preview-form": "outline", + "defaults": [ + "seo-audit — полный SEO-аудит" + ], + "key-decisions": [ + "keyword-стратегия и тех-фиксы" + ], + "acceptance-criteria": [ + "аудит покрывает тех и контент" + ], + "source": { + "version": "n/a", + "hash": "0000000000000000000000000000000000000000000000000000000000000000", + "path": "" + } +} diff --git a/docs/registry/nodes.yaml b/docs/registry/nodes.yaml index 9197b6c..3873491 100644 --- a/docs/registry/nodes.yaml +++ b/docs/registry/nodes.yaml @@ -1905,34 +1905,132 @@ nodes: attributes: tooling_section: "§4.48 #73" - - id: "#74" - name: "marketing" - slug: "marketing-plugin" + - id: "#74a" + name: "marketing-brand-review" + slug: "marketing-plugin:brand-review" category: "off-phase" subcategory: "marketing-tooling" status: "active" dormancy_reason: null - capabilities: "Маркетинговый плагин с 8 скилами: создание контента, email-цепочки, SEO-аудит, конкурентные брифы, performance-отчёты, планирование кампаний; первичный resolver раздела C1." + capabilities: "Ревью контента против голоса/гайда бренда: флаги по severity + before/after-фиксы." + triggers: [] + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§4.49 #74" + + - id: "#74b" + name: "marketing-campaign-plan" + slug: "marketing-plugin:campaign-plan" + category: "off-phase" + subcategory: "marketing-tooling" + status: "active" + dormancy_reason: null + capabilities: "Бриф кампании: цели, аудитория, каналы, контент-календарь, метрики." triggers: - - {keyword: "маркетинговый контент", weight: 1.0} - {keyword: "кампания", weight: 1.0} - - {keyword: "seo-аудит", weight: 1.0} - - {keyword: "email-цепочка", weight: 1.0} - - {keyword: "конкурент-бриф", weight: 1.0} - - {keyword: "performance-report", weight: 1.0} - - {keyword: "email-рассылка", weight: 1.0} - {keyword: "лендинг", weight: 1.0} - {keyword: "реклама", weight: 1.0} - {keyword: "лидген", weight: 1.0} - {keyword: "вебинар", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§4.49 #74" + + - id: "#74c" + name: "marketing-competitive-brief" + slug: "marketing-plugin:competitive-brief" + category: "off-phase" + subcategory: "marketing-tooling" + status: "active" + dormancy_reason: null + capabilities: "Маркетинговый конкурентный анализ: позиционирование, messaging-гэпы, угрозы, battlecards. (Не путать с product-management:competitive-brief.)" + triggers: + - {keyword: "конкурент-бриф", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§4.49 #74" + + - id: "#74d" + name: "marketing-content-creation" + slug: "marketing-plugin:content-creation" + category: "off-phase" + subcategory: "marketing-tooling" + status: "active" + dormancy_reason: null + capabilities: "Фреймворки и шаблоны контента под канал (blog/social/email/landing/PR/case). Первичный resolver контента C1." + triggers: + - {keyword: "маркетинговый контент", weight: 1.0} - {classification: "marketing", weight: 1.0} boundaries: - - {adr: "ADR-015", role: "MKT1 vs C2/C3; MKT2 vs product-management #42; MKT3 vs marketingskills #75 (решатель, не материал)"} + - {adr: "ADR-015", role: "MKT1 vs C2/C3; MKT2 vs product-management; MKT3 vs marketingskills #75 (решатель, не материал)"} chain_membership: ["L16"] attributes: tooling_section: "§4.49 #74" install: "claude plugin install marketing@knowledge-work-plugins" + - id: "#74e" + name: "marketing-draft-content" + slug: "marketing-plugin:draft-content" + category: "off-phase" + subcategory: "marketing-tooling" + status: "active" + dormancy_reason: null + capabilities: "Драфт маркетинг-контента с кросс-платформенным форматированием." + triggers: [] + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§4.49 #74" + + - id: "#74f" + name: "marketing-email-sequence" + slug: "marketing-plugin:email-sequence" + category: "off-phase" + subcategory: "marketing-tooling" + status: "active" + dormancy_reason: null + capabilities: "Multi-email цепочка: логика ветвления, timing, бенчмарки." + triggers: + - {keyword: "email-цепочка", weight: 1.0} + - {keyword: "email-рассылка", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§4.49 #74" + + - id: "#74g" + name: "marketing-performance-report" + slug: "marketing-plugin:performance-report" + category: "off-phase" + subcategory: "marketing-tooling" + status: "active" + dormancy_reason: null + capabilities: "Отчёт по маркетинг-метрикам: тренды, инсайты, рекомендации оптимизации." + triggers: + - {keyword: "performance-report", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§4.49 #74" + + - id: "#74h" + name: "marketing-seo-audit" + slug: "marketing-plugin:seo-audit" + category: "off-phase" + subcategory: "marketing-tooling" + status: "active" + dormancy_reason: null + capabilities: "SEO-аудит: keyword-исследование, тех-секция, контент-гэпы." + triggers: + - {keyword: "seo-аудит", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§4.49 #74" + - id: "#75" name: "marketingskills" slug: "marketingskills" @@ -2407,7 +2505,7 @@ chains: name: "marketing chain" sequence: - "superpowers:brainstorming" - - "#74" + - "marketing-plugin:content-creation" - "#77" - "#78" - "#79" diff --git a/docs/registry/splitting-inventory.md b/docs/registry/splitting-inventory.md index 50ec261..93bb3dc 100644 --- a/docs/registry/splitting-inventory.md +++ b/docs/registry/splitting-inventory.md @@ -116,8 +116,8 @@ | adr-kit (2: adr, judge) | ✅ DONE | f01f5b8 (pushed) | | hookify (1–2) | ⏸ развилка владельцу (slug hookify:hookify кривой) | | | product-management (8) | ✅ DONE | 0258b9d (pushed) | -| design-plugin (7) | ✅ DONE | этот коммит | -| marketing-plugin (8) | ⬜ | | +| design-plugin (7) | ✅ DONE | bf3d557 (committed, push deferred — observer-race) | +| marketing-plugin (8) | ✅ DONE | этот коммит (push deferred) | | operations (8) | ⬜ | | | finance-plugin (7–8) | ⬜ | | | brand-voice (3) | ⬜ | | diff --git a/tools/registry-load.test.mjs b/tools/registry-load.test.mjs index 9fa154e..e688eaf 100644 --- a/tools/registry-load.test.mjs +++ b/tools/registry-load.test.mjs @@ -5,9 +5,9 @@ import { loadRegistry, clearCache, findByClassification, findByKeyword, findActi describe('registry-load', () => { beforeEach(() => clearCache()); - it('loads registry (123 nodes: разворачивание #33/#19/#57/#36/#42/#46 комков 18.06.2026)', () => { + it('loads registry (130 nodes: разворачивание #33/#19/#57/#36/#42/#46/#74 комков 18.06.2026)', () => { const r = loadRegistry(); - expect(r.nodes).toHaveLength(123); + expect(r.nodes).toHaveLength(130); expect(r.version).toBe('0.1.0'); }); @@ -46,9 +46,9 @@ describe('registry-load', () => { it('findActiveNodes excludes non-active (nodes.yaml registry)', () => { const r = loadRegistry(); const active = findActiveNodes(r); - // 123 nodes total; #1 historic, #17 dormant, #44/#50/#54/#67/#82/#83 deferred; - // развёрнуты: #33→2, #19→14, #57→7, #36→2, #42→8, #46 design→7 (active +...+6) → 115 active - expect(active).toHaveLength(115); + // 130 nodes total; #1 historic, #17 dormant, #44/#50/#54/#67/#82/#83 deferred; + // развёрнуты: #33→2, #19→14, #57→7, #36→2, #42→8, #46→7, #74 marketing→8 (+7) → 122 active + expect(active).toHaveLength(122); expect(active.map(n => n.id)).toContain('#18'); expect(active.map(n => n.id)).toContain('#19a'); expect(active.map(n => n.id)).not.toContain('#1');