@zrg-sh/studio 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/ONBOARDING.html +270 -0
  3. package/README.md +82 -0
  4. package/bin/zrg-studio.mjs +67 -0
  5. package/package.json +29 -0
  6. package/src/commands/doctor.mjs +60 -0
  7. package/src/commands/init.mjs +44 -0
  8. package/src/lib/copy-template.mjs +42 -0
  9. package/src/lib/merge-claude-settings.mjs +54 -0
  10. package/template/.claude/agents/studio-analyst.md +109 -0
  11. package/template/.claude/agents/studio-designer.md +172 -0
  12. package/template/.claude/agents/studio-domain-framer.md +109 -0
  13. package/template/.claude/agents/studio-domain-merger.md +264 -0
  14. package/template/.claude/agents/studio-pm.md +169 -0
  15. package/template/.claude/agents/studio-reviewer.md +156 -0
  16. package/template/.claude/agents/studio-scenario-writer.md +152 -0
  17. package/template/.claude/commands/studio-analyst.md +45 -0
  18. package/template/.claude/commands/studio-designer.md +34 -0
  19. package/template/.claude/commands/studio-domain-framer.md +30 -0
  20. package/template/.claude/commands/studio-onboard.md +98 -0
  21. package/template/.claude/commands/studio-pm.md +39 -0
  22. package/template/.claude/commands/studio-scenario-writer.md +44 -0
  23. package/template/product-specs/CLAUDE.md +53 -0
  24. package/template/product-specs/agents/studio-analyst.md +109 -0
  25. package/template/product-specs/agents/studio-codebase-mapper.md +217 -0
  26. package/template/product-specs/agents/studio-conflict-resolver.md +169 -0
  27. package/template/product-specs/agents/studio-designer.md +172 -0
  28. package/template/product-specs/agents/studio-domain-extractor.md +365 -0
  29. package/template/product-specs/agents/studio-domain-framer.md +109 -0
  30. package/template/product-specs/agents/studio-domain-interviewer.md +246 -0
  31. package/template/product-specs/agents/studio-domain-merger.md +264 -0
  32. package/template/product-specs/agents/studio-god.md +779 -0
  33. package/template/product-specs/agents/studio-meta-god.md +335 -0
  34. package/template/product-specs/agents/studio-pm.md +169 -0
  35. package/template/product-specs/agents/studio-reviewer.md +156 -0
  36. package/template/product-specs/agents/studio-scenario-writer.md +152 -0
  37. package/template/product-specs/agents/studio-verifier.md +222 -0
  38. package/template/product-specs/docs/_meta/capability-map.example.md +103 -0
  39. package/template/product-specs/docs/_meta/doc-schema.md +134 -0
  40. package/template/product-specs/docs/_meta/domain-map.example.md +106 -0
  41. package/template/product-specs/docs/_meta/glossary.example.md +72 -0
  42. package/template/product-specs/docs/_meta/onboarding.example.md +142 -0
  43. package/template/product-specs/docs/_meta/product-vision.example.md +136 -0
  44. package/template/product-specs/hooks/studio-conflict-detect.sh +59 -0
  45. package/template/product-specs/hooks/studio-context-monitor.js +37 -0
  46. package/template/product-specs/hooks/studio-domain-guard.sh +40 -0
  47. package/template/product-specs/hooks/studio-prompt-guard.js +36 -0
  48. package/template/product-specs/hooks/studio-session-state.sh +55 -0
  49. package/template/product-specs/hooks/studio-stage-gate.sh +180 -0
  50. package/template/product-specs/references/checkpoints.md +27 -0
  51. package/template/product-specs/references/ddd-conventions.md +38 -0
  52. package/template/product-specs/references/gates.md +50 -0
  53. package/template/product-specs/references/model-profiles.md +28 -0
  54. package/template/product-specs/references/obsidian-conventions.md +51 -0
  55. package/template/product-specs/references/stage-pipeline.md +65 -0
  56. package/template/product-specs/rules/change-management.md +159 -0
  57. package/template/product-specs/rules/docs-conventions.md +81 -0
  58. package/template/product-specs/rules/domain-conventions.md +69 -0
  59. package/template/product-specs/rules/id-numbering.md +51 -0
  60. package/template/product-specs/rules/obsidian-conventions.md +51 -0
  61. package/template/product-specs/templates/change/01-intent.md +40 -0
  62. package/template/product-specs/templates/change/02-scenarios.md +66 -0
  63. package/template/product-specs/templates/change/03-analysis.md +64 -0
  64. package/template/product-specs/templates/change/04-domain.md +47 -0
  65. package/template/product-specs/templates/change/05-ux.md +46 -0
  66. package/template/product-specs/templates/change/metadata.yaml +26 -0
  67. package/template/product-specs/templates/config.json +19 -0
  68. package/template/product-specs/templates/domain/README.md +31 -0
  69. package/template/product-specs/templates/domain/aggregates.md +37 -0
  70. package/template/product-specs/templates/domain/api-contracts.md +29 -0
  71. package/template/product-specs/templates/domain/business-rules.md +30 -0
  72. package/template/product-specs/templates/domain/changelog.md +25 -0
  73. package/template/product-specs/templates/domain/data-model.md +34 -0
  74. package/template/product-specs/templates/domain/events.md +24 -0
  75. package/template/product-specs/templates/domain/integrations.md +27 -0
  76. package/template/product-specs/templates/domain/invariants.md +14 -0
  77. package/template/product-specs/templates/domain/links.yaml +20 -0
  78. package/template/product-specs/templates/domain/operational-sla.md +32 -0
  79. package/template/product-specs/templates/domain/ownership.md +13 -0
  80. package/template/product-specs/templates/domain/scenarios.md +65 -0
  81. package/template/product-specs/templates/domain/surfaces.md +51 -0
  82. package/template/product-specs/templates/domain/ubiquitous-language.md +12 -0
  83. package/template/product-specs/templates/meta/capability-map.md +55 -0
  84. package/template/product-specs/templates/meta/doc-schema.md +134 -0
  85. package/template/product-specs/templates/meta/domain-map.md +67 -0
  86. package/template/product-specs/templates/meta/glossary.md +30 -0
  87. package/template/product-specs/templates/meta/onboarding.md +108 -0
  88. package/template/product-specs/templates/state.md +19 -0
  89. package/template/product-specs/workflows/conflict-resolution.md +10 -0
  90. package/template/product-specs/workflows/domain-update.md +15 -0
  91. package/template/product-specs/workflows/map-codebase.md +17 -0
  92. package/template/product-specs/workflows/onboard-project.md +575 -0
  93. package/template/product-specs/workflows/pipeline-full.md +258 -0
  94. package/template/product-specs/workflows/pipeline-resume.md +21 -0
  95. package/template/product-specs/workflows/verify-change.md +12 -0
@@ -0,0 +1,106 @@
1
+ ---
2
+ type: meta
3
+ tags:
4
+ - meta
5
+ - map
6
+ ---
7
+
8
+ # Domain Map
9
+
10
+ 5 bounded contexts MVP-системы **zrg** — Telegram-бота для уведомлений из GitHub/Linear.
11
+
12
+ ## Bounded contexts
13
+
14
+ | Domain | Type | Status | Purpose |
15
+ |---|---|---|---|
16
+ | identity | Supporting | active | User-аккаунты, Connection'ы (GitHub/Linear/Telegram), LinkingToken |
17
+ | workspace | Core | active | Workspaces, Members (RBAC), GroupTargets, refs к Subscription'ам |
18
+ | github-integration | Supporting (ACL) | active | GitHub App, repository binding, webhook ingestion, нормализация в SourceEvent |
19
+ | linear-integration | Supporting (ACL) | active | Linear OAuth, team binding, view polling, webhook ingestion, нормализация в SourceEvent |
20
+ | notifications | Core | active | NotificationRule, Delivery, channel ports, slash-команды |
21
+
22
+ ## Overview
23
+
24
+ ```mermaid
25
+ graph LR
26
+ subgraph Core
27
+ WS[workspace]
28
+ NT[notifications]
29
+ end
30
+
31
+ subgraph Supporting
32
+ ID[identity]
33
+ end
34
+
35
+ subgraph "Supporting / ACL"
36
+ GH[github-integration]
37
+ LN[linear-integration]
38
+ end
39
+
40
+ ID -->|UserCreated, ConnectionAdded, ConnectionRevoked, UserDeleted| WS
41
+ ID -->|GithubConnectionAdded, ConnectionRevoked| GH
42
+ ID -->|LinearConnectionAdded, ConnectionRevoked| LN
43
+ ID -->|TelegramConnectionAdded, ConnectionRevoked, UserDeleted| NT
44
+
45
+ WS -->|SubscriptionRequested, SubscriptionRemoved, WorkspaceArchived| GH
46
+ WS -->|SubscriptionRequested, SubscriptionRemoved, WorkspaceArchived| LN
47
+ WS -->|MemberRemoved, GroupTargetRegistered/Unregistered, SubscriptionRemoved, WorkspaceArchived| NT
48
+
49
+ GH -->|SubscriptionActivated/Failed| WS
50
+ LN -->|SubscriptionActivated/Failed| WS
51
+
52
+ GH -->|SourceEvent source=github| NT
53
+ LN -->|SourceEvent source=linear| NT
54
+
55
+ GH -.->|ACL: GitHub App / Webhooks / REST| EXTGH[(GitHub)]
56
+ LN -.->|ACL: Linear OAuth / Webhooks / GraphQL| EXTLN[(Linear)]
57
+ NT -.->|Telegram Bot API| EXTTG[(Telegram)]
58
+
59
+ style WS fill:#4a9eff,color:#fff
60
+ style NT fill:#4a9eff,color:#fff
61
+ style ID fill:#f5c95b,color:#000
62
+ style GH fill:#f5c95b,color:#000
63
+ style LN fill:#f5c95b,color:#000
64
+ style EXTGH fill:#6c757d,color:#fff
65
+ style EXTLN fill:#6c757d,color:#fff
66
+ style EXTTG fill:#6c757d,color:#fff
67
+ ```
68
+
69
+ > [!info] Legend
70
+ > - Синий: Core (содержат основную бизнес-ценность)
71
+ > - Жёлтый: Supporting (поддерживают core, в т.ч. ACL к внешним системам)
72
+ > - Серый: External systems
73
+
74
+ ## Context mapping patterns
75
+
76
+ | Pair | Pattern | Notes |
77
+ |---|---|---|
78
+ | identity → workspace | Customer/Supplier | identity — supplier; workspace — customer (потребляет UserCreated, ConnectionRevoked, UserDeleted) |
79
+ | identity → github-integration | Customer/Supplier | github-integration индексирует mapping `githubUserId ↔ userId` |
80
+ | identity → linear-integration | Customer/Supplier | linear-integration индексирует mapping `linearUserId ↔ userId`, использует token из Connection |
81
+ | identity → notifications | Customer/Supplier | notifications читает TelegramConnection для DM-доставки, реагирует на revoke |
82
+ | workspace → github-integration | Customer/Supplier | workspace эмитит SubscriptionRequested(github); integration возвращает SubscriptionActivated/Failed |
83
+ | workspace → linear-integration | Customer/Supplier | аналогично; viaConnectionId — это LinearConnection системного аккаунта `WorkspaceLinearBot` |
84
+ | workspace → notifications | Customer/Supplier | notifications реагирует на MemberRemoved, GroupTarget*, SubscriptionRemoved, WorkspaceArchived |
85
+ | github-integration → notifications | Published Language | стабильный контракт `SourceEvent` |
86
+ | linear-integration → notifications | Published Language | стабильный контракт `SourceEvent` |
87
+ | github-integration → GitHub | ACL | webhook payload + REST → нормализация |
88
+ | linear-integration → Linear | ACL | webhook payload + GraphQL → нормализация |
89
+
90
+ ## Shared Kernel
91
+
92
+ Минимальный:
93
+ - VO: `UserId`, `WorkspaceId`, `MemberId`, `ConnectionId`, `SourceEventId`, `WorkspaceLinearBotId`.
94
+ - Канонический тип `SourceEvent` (см. context-map: published language от integration в notifications).
95
+ - Result/Error type для команд.
96
+
97
+ НЕ shared: aggregates, репозитории, схемы хранения.
98
+
99
+ ## Active domains list
100
+
101
+ ```dataview
102
+ TABLE owner, status, length(file.inlinks) AS "refs"
103
+ FROM "domains"
104
+ WHERE type = "domain"
105
+ SORT domain
106
+ ```
@@ -0,0 +1,72 @@
1
+ ---
2
+ type: meta
3
+ tags:
4
+ - meta
5
+ - glossary
6
+ ---
7
+
8
+ # Glossary
9
+
10
+ Cross-domain shared terms zrg. Для терминов внутри одного BC — см. `domains/<BC>/ubiquitous-language.md`.
11
+
12
+ ## Auto-index (all UL terms)
13
+
14
+ ```dataview
15
+ TABLE domain AS "Domain"
16
+ FROM "domains"
17
+ WHERE type = "ubiquitous-language"
18
+ SORT domain
19
+ ```
20
+
21
+ ## Cross-domain shared terms
22
+
23
+ | Term | Definition | Owner domain | Used by |
24
+ |---|---|---|---|
25
+ | User | Физическое лицо, аутентифицированное в web. Глобальная identity. | identity | workspace (как Member.userId), notifications, integrations (mapping) |
26
+ | UserId | Reference to identity.User | identity | все домены через ID-references |
27
+ | Connection | Привязка User к внешнему аккаунту (GitHub/Linear/Telegram). Discriminated by type. | identity | github-integration, linear-integration, notifications |
28
+ | Workspace | Основная организационная единица. Контейнер Member'ов и привязок ресурсов. | workspace | все домены |
29
+ | WorkspaceId | Reference to Workspace | workspace | все домены через ID-references |
30
+ | Member | User+role+workspaceId. NOT синоним «User» — Member per-workspace. | workspace | notifications (target.kind='member'), authorization checks |
31
+ | MemberRole | RBAC роль: `owner` / `admin` / `member`. Простой RBAC (Q17), без custom-permissions. | workspace | все мутирующие commands |
32
+ | Subscription | Привязка внешнего ресурса (GitHub repo / Linear team) к Workspace. **Reference в workspace; aggregate в integration**. | workspace + integration | notifications (filter), workspace (read-projection) |
33
+ | SubscriptionState | `pending` / `active` / `broken` / `removed`. | github-integration / linear-integration | workspace (read-projection) |
34
+ | GroupTarget | Зарегистрированный групповой Telegram-чат, привязанный к Workspace. | workspace | notifications (target.kind='group') |
35
+ | WorkspaceLinearBot | Per-workspace системный Linear OAuth-токен (сервисный аккаунт `workspace-bot@…`). Авторитет для polling/webhook. **НЕ User'ский Connection** (Q10). | linear-integration | workspace (read-projection «bot connected»), notifications (косвенно через SourceEvent) |
36
+ | SourceEvent | Канонический нормализованный event из integration в notifications (Published Language). source ∈ {'github', 'linear'}. | github-integration / linear-integration | notifications (consumer) |
37
+ | SourceEventId | UUID v4, наш id (НЕ external delivery id). | integration | notifications (dedup key) |
38
+ | NotificationRule | Декларативное правило: trigger+filter+target+channel. Owner = Member или Workspace. | notifications | — |
39
+ | NotificationTarget | Discriminated union: `MemberTarget | GroupTarget` (Q16). | notifications | — |
40
+ | NotificationChannel | Port (interface). MVP реализация — `TelegramChannel`. | notifications | — |
41
+ | Delivery | Экземпляр доставки. Дедуп по `(ruleId, sourceEventId, targetSnapshot.id)`. Retention 30 дней (Q15). | notifications | — |
42
+ | Channel (enum value) | `'telegram'` в MVP. Расширяется на `'slack'`/`'discord'`/`'email'`. | notifications | — |
43
+ | LinkingToken | Одноразовый short-lived токен для связки Telegram через deep-link `t.me/<bot>?start=<token>`. TTL 10 мин. | identity | bot (consume) |
44
+ | WebhookEvent | Запись о факте получения webhook'а (для дедупликации и аудита). Per-source (github/linear), но общая семантика. | github-integration / linear-integration | — |
45
+
46
+ ## Integration / source-of-truth quick reference
47
+
48
+ | Question | Where |
49
+ |---|---|
50
+ | Кто User и какие у него Connection? | identity |
51
+ | В каком Workspace состоит User и с какой ролью? | workspace |
52
+ | Какие репо/команды привязаны к Workspace? | workspace (refs) + github-integration / linear-integration (aggregates) |
53
+ | Кому отправлять уведомление? | notifications.NotificationRule |
54
+ | Что доставлено / что failed? | notifications.Delivery |
55
+ | Какие issues просрочены? | linear-integration.GetOverdueIssues (live GraphQL) |
56
+ | Тело issue / PR / comment? | live fetch via integration query (Q9: не зеркалим) |
57
+
58
+ ## Meta terms
59
+
60
+ | Term | Definition | Notes |
61
+ |---|---|---|
62
+ | PRDCT | Change package — immutable набор документов одного изменения | Формат: `PRDCT-XXXX` |
63
+ | ADR | Architecture Decision Record | Формат: `ADR-XXX` |
64
+ | Bounded Context | Явная граница, внутри которой модель имеет определённый смысл | DDD-термин |
65
+ | Aggregate | Кластер доменных объектов, обрабатываемых как единица | DDD-термин |
66
+ | Invariant | Правило, которое не может быть нарушено ни при каких обстоятельствах | Строже чем business rule |
67
+ | Ubiquitous Language | Общий словарь терминов в пределах BC | DDD-термин |
68
+ | Shared Kernel | Паттерн: общее ядро (структуры/сущности) между двумя BC | DDD context mapping |
69
+ | Published Language | Стабильный контракт, которым BC обменивается с потребителями | DDD context mapping |
70
+ | ACL (Anti-Corruption Layer) | Изоляция от внешней модели через адаптер | DDD context mapping |
71
+ | Outbox | Таблица, в которую в той же транзакции что и агрегат пишется integration event | Затем publisher читает и публикует в Redis pub/sub |
72
+ | Idempotency Key | Ключ, по которому повторная доставка одного и того же события не порождает дубликата эффекта | Применяется в WebhookEvent + Delivery dedup |
@@ -0,0 +1,142 @@
1
+ ---
2
+ type: meta
3
+ status: active
4
+ tags:
5
+ - meta
6
+ - onboarding
7
+ created: 2026-04-28
8
+ ---
9
+
10
+ # Onboarding · zrg
11
+
12
+ ## Что это за проект
13
+
14
+ **zrg** — Telegram-бот для уведомлений из GitHub/Linear с глубокой интеграцией. Workspace = ключевая сущность, к ней привязываются GitHub-репозитории и Linear-команды. Member'ы подключают свои GitHub/Linear/Telegram. Бот доставляет уведомления (DM или в групповой чат) по настраиваемым правилам и подсвечивает просроченные тикеты Linear.
15
+
16
+ ## MVP scope
17
+
18
+ - workspaces, members, привязка GH/Linear/TG через web;
19
+ - уведомления о новых GH issues;
20
+ - уведомления по Linear views;
21
+ - подсветка просроченных Linear тикетов;
22
+ - slash-команды в групповых чатах (`/status`, `/overdue`, `/views`, `/register`).
23
+
24
+ **НЕ делаем в MVP:** Claude-агенты, чат-функционал между пользователями, Slack/Discord/Email каналы (architecture-ready, реализаций нет), биллинг.
25
+
26
+ ## Documentation-first development
27
+
28
+ Любое изменение начинается с документа, не с кода. Каждый change package (PRDCT-XXXX) — immutable набор бизнес-документов, проходящих pipeline:
29
+
30
+ ```mermaid
31
+ flowchart LR
32
+ S01["01 Intent\n/pm"] --> S02["02 Scenarios\n/scenarios"]
33
+ S02 --> S03["03 Analysis\n/analyst"]
34
+ S03 --> S04["04 Domain\n/domain-framer"]
35
+ S04 --> S05["05 UX\n/designer"]
36
+ S05 --> S06["Executor\n(code)"]
37
+ S06 --> S07["Merger\n(domain docs)"]
38
+ ```
39
+
40
+ > [!danger] Правило 1
41
+ > **Нет документа — нет задачи.** PR без ссылки на PRDCT-* не мержится.
42
+
43
+ ## Структура документации
44
+
45
+ ```
46
+ product-specs/
47
+ ├── docs/
48
+ │ ├── domains/ Бизнес-домены (5 BC):
49
+ │ │ ├── identity/ User, Connection, LinkingToken
50
+ │ │ ├── workspace/ Workspace, Member, GroupTarget, refs
51
+ │ │ ├── github-integration/ Installation, Subscription, WebhookEvent, ACL
52
+ │ │ ├── linear-integration/ WorkspaceLinearBot, Subscription, WatchedView, ACL
53
+ │ │ └── notifications/ NotificationRule, Delivery, channels, slash
54
+ │ ├── changes/ PRDCT-XXXX: immutable
55
+ │ ├── adrs/ Architecture Decision Records
56
+ │ ├── contexts/ Платформенное знание (стек):
57
+ │ │ ├── backend/ Bun + NestJS + Prisma + tRPC + GraphQL
58
+ │ │ └── frontend/ Next.js 16 + Apollo + shadcn + FSD
59
+ │ └── _meta/ Схема, карты, глоссарий, onboarding
60
+ ├── agents/ AI-роли (PM, Analyst, Designer, Merger)
61
+ ├── rules/ Правила документации
62
+ ├── references/ DDD/pipeline conventions
63
+ └── templates/ Шаблоны (change, domain, meta)
64
+ ```
65
+
66
+ ## Зафиксированные архитектурные решения
67
+
68
+ | Q | Решение | Где применено |
69
+ |---|---|---|
70
+ | Q1 | Telegram ↔ User строго **1:1** | identity/business-rules, identity/invariants |
71
+ | Q4 | User ↔ Workspace = **1:N** (User в нескольких WS) | workspace/business-rules |
72
+ | Q5 | Owner покидает workspace → **auto-promote самого старшего admin'а**; нет admin'ов → archive | workspace/business-rules, events |
73
+ | Q9 | НЕ зеркалим тело issue/ticket. **Metadata + ссылка**, тело on-demand | github-integration/business-rules, linear-integration/business-rules |
74
+ | Q10 | Linear OAuth-токен привязан к **WorkspaceLinearBot** (per workspace), не к User | linear-integration/aggregates, business-rules |
75
+ | Q12 | Polling Linear views — **5 минут** (env `LINEAR_VIEW_POLL_INTERVAL_MS=300000`) | linear-integration/operational-sla, business-rules |
76
+ | Q13 | Дедупликация — **N сообщений на N rules** (без агрегации) | notifications/business-rules |
77
+ | Q15 | Retention Delivery — **30 дней** (env `DELIVERY_RETENTION_DAYS=30`) | notifications/operational-sla, invariants |
78
+ | Q16 | Target = **MemberTarget \| GroupTarget** (first-class discriminated union) | notifications/aggregates |
79
+ | Q17 | Authz — **простой RBAC** (`owner`/`admin`/`member`), без ABAC | workspace/business-rules |
80
+
81
+ ## Стэк (зафиксирован)
82
+
83
+ **Backend:** Bun runtime · NestJS (DDD) · Prisma + PostgreSQL · nestjs-trpc (бот ↔ backend) · @nestjs/graphql code-first (web ↔ backend) · @nestjs/cqrs · BullMQ + Redis · Outbox + Redis pub/sub.
84
+
85
+ **Bot:** Grammy на Bun (тонкий клиент, вся логика в backend через tRPC).
86
+
87
+ **Web:** Next.js 16 App Router · Apollo Client (graphql-codegen, near-operation-file) · shadcn/ui + Radix + Tailwind · FSD по доменам · prod runtime `node:20-alpine` (build на Bun, runtime Node — из-за Bun memory leak в Next.js prod апрель 2026).
88
+
89
+ **Интеграции:** GitHub App (не OAuth App) · Linear OAuth + webhook + polling · Telegram deep-link.
90
+
91
+ См. `contexts/backend/README.md` и `contexts/frontend/README.md` для деталей.
92
+
93
+ ## Что лежит где
94
+
95
+ ```
96
+ Question -> Location
97
+ ---------------------------------------------------------------
98
+ Что делает домен X? -> domains/<X>/README.md
99
+ Какие агрегаты и state machines в X? -> domains/<X>/aggregates.md
100
+ Какие бизнес-правила X? -> domains/<X>/business-rules.md
101
+ Что не может быть нарушено в X? -> domains/<X>/invariants.md
102
+ Какие события эмитит/потребляет X? -> domains/<X>/events.md
103
+ Какие термины в X? -> domains/<X>/ubiquitous-language.md
104
+ Какие SLA / лимиты у X? -> domains/<X>/operational-sla.md
105
+ Кто владеет доменом X? -> domains/<X>/ownership.md
106
+
107
+ Cross-domain карта связей -> _meta/domain-map.md
108
+ Cross-domain термины -> _meta/glossary.md
109
+ Что система УМЕЕТ? -> _meta/capability-map.md
110
+
111
+ Backend stack & conventions -> contexts/backend/
112
+ Frontend stack & conventions -> contexts/frontend/
113
+ Архитектурные решения (почему так) -> adrs/ADR-XXX.md
114
+ Что изменилось в фиче Y? -> changes/PRDCT-XXXX/
115
+ ```
116
+
117
+ ## Pipeline команды (когда появятся agents)
118
+
119
+ 1. `/pm <описание фичи>` → 01-intent.md (PRDCT-XXXX создан)
120
+ 2. `/scenarios PRDCT-XXXX` → 02-scenarios.md (Gherkin)
121
+ 3. `/analyst PRDCT-XXXX` → 03-analysis.md
122
+ 4. `/domain-framer PRDCT-XXXX` → 04-domain.md
123
+ 5. `/designer PRDCT-XXXX` → 05-ux.md + mockups/
124
+ 6. `/review PRDCT-XXXX` → проверка целостности
125
+ 7. Status → done. Executor пишет код, merger обновляет domain docs.
126
+
127
+ > [!tip] Быстрый запуск
128
+ > `/feature <описание>` — весь pipeline одной командой.
129
+
130
+ ## Key rules
131
+
132
+ > [!danger] Domain docs — только бизнес-знание
133
+ > domains/* содержат бизнес-правила, агрегаты, события, инварианты. Никаких Prisma-схем, NestJS-модулей, file paths, REST/GraphQL endpoints в `business-rules.md`/`aggregates.md`/`events.md`/`invariants.md`. Реализационные детали — в `data-model.md`/`api-contracts.md` (заполняются из кода).
134
+
135
+ > [!danger] Change packages иммутабельны
136
+ > После мержа никогда не редактируются. Фиксы — отдельный PRDCT.
137
+
138
+ > [!danger] Техника не в change package
139
+ > Change package содержит ТОЛЬКО бизнес-документы. Технические решения принимает executor.
140
+
141
+ > [!danger] PR привязан к PRDCT
142
+ > PR без ссылки на PRDCT-* не мержится.
@@ -0,0 +1,136 @@
1
+ ---
2
+ type: meta
3
+ status: active
4
+ tags:
5
+ - meta
6
+ - vision
7
+ - north-star
8
+ created: 2026-04-30
9
+ ---
10
+
11
+ # Product Vision · zrg
12
+
13
+ > Верхнеуровневое «куда мы идём». Читается агентами пайплайна (PM, Analyst, Domain Framer, Designer) как контекст для принятия решений по доменам и фичам. Это **не roadmap** — это вектор, объясняющий, почему домены устроены именно так, и куда они эволюционируют.
14
+
15
+ ---
16
+
17
+ ## Что мы строим (одной фразой)
18
+
19
+ **Коллаборативный инструмент vibe-coding'а спецификаций продукта и больших систем** — платформа, где **колоды AI-агентов** ведут команду через пайплайн разработки спеки (intent → scenarios → analysis → domain → ux → …), а **люди в команде отыгрывают свои роли**, отвечая на вопросы агентов и валидируя их выводы.
20
+
21
+ Продукт — это и есть тот pipeline, который сейчас лежит в `product-specs/` и которым этот репозиторий пользуется сам на себе (dogfooding).
22
+
23
+ ---
24
+
25
+ ## North Star
26
+
27
+ Команда заходит в workspace, заводит фичу/систему, и **колода агентов прогоняет спеку через пайплайн**. Агенты задают вопросы конкретным ролям (PM-у — про intent, бэкенд-разработчику — про инварианты, дизайнеру — про UX), люди отвечают в удобном канале (Telegram DM, групповой чат, web — что подключено), и через несколько итераций получается **immutable change package со всеми бизнес-документами**, готовый к executor'у.
28
+
29
+ Спецификация **живёт в git-репозитории команды как код** (markdown + структура), а не в нашей БД. Мы — оркестратор агентов и канал коммуникации, не хранилище спек.
30
+
31
+ ---
32
+
33
+ ## Ключевые сдвиги в модели
34
+
35
+ Чтобы было однозначно — это **не** «Telegram-бот для уведомлений из GitHub/Linear». Текущий MVP (workspace + GH/Linear/notifications) — это **фундамент инфраструктуры**, на котором поедет настоящий продукт. Реальный продукт это:
36
+
37
+ | Что | Описание |
38
+ |---|---|
39
+ | **Колоды агентов — first-class** | Люди ассистируют агентам, не наоборот. Агент инициирует диалог, человек отвечает в своей роли. |
40
+ | **Спека = код в git** | Документы спеки коммитятся в репозиторий команды. Мы не master-копия, мы — оркестратор. |
41
+ | **Workspace = команда над одним проектом** | Не «организация с N проектами». Один workspace — одна продуктовая инициатива / система. |
42
+ | **Интеграции — двусторонние каналы Q&A** | GH/Linear/Telegram/etc. — не источники уведомлений, а каналы общения агента с конкретным человеком в его роли. |
43
+ | **Notifications — это призывы, не дайджесты** | «Агент задал вопрос», «требуется ваше внимание», «спека прошла стадию». Не «вышло 5 новых issues». |
44
+
45
+ ---
46
+
47
+ ## Не-цели
48
+
49
+ - ❌ **Не issue tracker.** GitHub/Linear остаются source-of-truth для тикетов; мы синхронизируемся, но не заменяем.
50
+ - ❌ **Не платформа для исполнения кода / CI.** Executor (тот, кто пишет код по спеке) — отдельная стадия, может быть человеком, может быть Claude Code, нашей задачей не является.
51
+ - ❌ **Не SaaS с биллингом / multi-tenant стратегией.** Монетизация не в фокусе.
52
+ - ❌ **Не messenger.** Мы используем Telegram (и в будущем другие каналы) как транспорт диалога агент↔человек, не строим внутрикомандный чат.
53
+ - ❌ **Не master-хранилище спек.** Спека живёт в git у команды; мы оркестрируем процесс, не владеем артефактами.
54
+ - ❌ **Не universal product management tool.** Фокус — техническая разработка продуктов и систем, где спецификация = архитектурный артефакт.
55
+
56
+ ---
57
+
58
+ ## Эволюция доменов
59
+
60
+ Текущие 5 bounded contexts (`identity`, `workspace`, `github-integration`, `linear-integration`, `notifications`) — это **инфраструктурный слой** для настоящего продукта. По мере реализации vision добавятся домены, отражающие ядро.
61
+
62
+ ### Существующие домены (фундамент)
63
+
64
+ #### `identity`
65
+ - **Сегодня:** auth + connections (GitHub/Linear/Telegram).
66
+ - **Дальше:** SSO для команд, identity по ролям внутри workspace (кто PM, кто backend, кто designer — для маршрутизации вопросов от агентов), новые provider'ы интеграций.
67
+
68
+ #### `workspace`
69
+ - **Сегодня:** workspace = команда + RBAC + group target.
70
+ - **Дальше:** **role assignments** (member→{PM, backend, frontend, designer, …} — агент знает, кому задавать какой вопрос), привязка к git-репозиторию команды (где живёт спека), workspace-level настройки колоды агентов.
71
+
72
+ #### `github-integration` / `linear-integration`
73
+ - **Сегодня:** webhook + binding + ACL + уведомления о событиях.
74
+ - **Дальше:** двусторонняя связь со спекой — PRDCT в спеке порождает issue/тикет в трекере и наоборот; статус спеки синхронизируется со статусом тикета; comment в issue → context для агента.
75
+
76
+ #### `notifications`
77
+ - **Сегодня:** rules + Telegram delivery + slash-команды.
78
+ - **Дальше:** notification = **призыв к действию** (агент ждёт ответа), а не информационный поток. Каналы расширяются (Slack, Discord, Email, web push), интерактивность — inline-actions для ответа агенту прямо из канала.
79
+
80
+ ### Новые домены (ядро будущего продукта)
81
+
82
+ Появятся как только инфраструктурный фундамент будет готов:
83
+
84
+ - **`agents`** — колода агентов, их роли, конфигурация, активные сессии, состояние диалога с командой.
85
+ - **`specifications`** — change packages (PRDCT-*), стадии pipeline, связь с git-репозиторием команды, immutability rules.
86
+ - **`pipeline`** — оркестрация прогона спеки через стадии (intent→scenarios→analysis→…), gate validation, переходы.
87
+ - **`conversations`** — диалоги агентов с людьми (вопрос→ответ→follow-up), маршрутизация по ролям, контекст диалога, история.
88
+ - **`integrations`** *(вероятно эволюция)* — обобщение GH/Linear/Telegram в общую модель «канал двустороннего Q&A», под которую подключаются новые источники.
89
+
90
+ Названия и границы — предварительные, фиксируются при реальном PRDCT, который их вводит.
91
+
92
+ ---
93
+
94
+ ## Продуктовые принципы
95
+
96
+ Решения по доменам и фичам сверяются с этими принципами:
97
+
98
+ 1. **Агент ведёт, человек отыгрывает роль.** Если фича заставляет человека инициировать каждый шаг — это противоречит модели.
99
+ 2. **Спека — код, не данные.** Артефакты спеки живут в git у команды. Мы можем читать/писать в репо команды, но не дублируем спеку у себя как master-копию.
100
+ 3. **Команда работает над одним проектом.** Workspace ≡ project. Если у команды два проекта — два workspace'а. Это упрощает RBAC, ownership и контекст агентов.
101
+ 4. **Каналы — first-class, но взаимозаменяемы.** Telegram сегодня основной транспорт диалога, но домен `conversations` спроектирован под N каналов. Slack/Discord/Email/web push — новая реализация порта, не редизайн.
102
+ 5. **Source-of-truth — внешние системы.** GitHub/Linear/git — источники правды. Конфликт = переспросить источник, не разруливать локально.
103
+ 6. **Колода агентов сегодня фиксирована.** PM, Scenario Writer, Analyst, Domain Framer, Designer, Merger. Кастомизация колод — далёкое будущее, не закладываемся сейчас.
104
+ 7. **Documentation-first внутри продукта-про-документацию.** Любая фича — через PRDCT. Vision (этот документ) — контекст для PM при создании intent.
105
+ 8. **YAGNI на агентов и pipeline.** Не закладываем абстракции под несуществующие роли/стадии. Фиксированный набор расширяется через PRDCT, когда возникнет реальная потребность.
106
+
107
+ ---
108
+
109
+ ## Как этот документ используется
110
+
111
+ - **PM (`/pm`)** — сверяет новый intent с не-целями и принципами; если фича уводит от ядра (vibe-coding спек) — оформляется отказом или эскалацией.
112
+ - **Domain Framer (`/domain-framer`)** — при добавлении aggregate / события сверяется с траекторией домена (раздел «Эволюция»). Особенно при появлении нового BC — должен матчить «Новые домены» или явно расширять vision.
113
+ - **Analyst (`/analyst`)** — держит north-star в голове при анализе scenarios, чтобы не уводить фичу в сторону.
114
+ - **Designer (`/designer`)** — UX следует «агент ведёт, человек отыгрывает роль»; экраны проектируются как ответы на призывы, а не как dashboard'ы.
115
+ - **Reviewer / merger** — отказывает PRDCT, противоречащему vision, без отдельного change-process'а.
116
+
117
+ ---
118
+
119
+ ## Когда обновлять vision
120
+
121
+ Vision **живой**, но **редко меняется**. Обновляется когда:
122
+ - появляется новый bounded context, не описанный в «Эволюции» (добавить раздел);
123
+ - меняется north-star (стратегический пивот → ADR + апдейт здесь);
124
+ - одно из «не-целей» становится целью (осознанное решение + ADR);
125
+ - расширяется колода агентов или модель спеки.
126
+
127
+ Обычные фичи (новый PRDCT в существующей траектории) **не обновляют** vision.
128
+
129
+ ---
130
+
131
+ ## Связанные документы
132
+
133
+ - `_meta/onboarding.md` — что такое проект сегодня (MVP scope, стек, pipeline)
134
+ - `_meta/capability-map.md` — что система УМЕЕТ (по доменам, текущее состояние)
135
+ - `_meta/domain-map.md` — связи между bounded contexts
136
+ - `adrs/` — архитектурные решения, обосновывающие текущее устройство
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+ # Studio Conflict Detector
3
+ # PostToolUse hook: checks for domain conflicts when metadata.yaml is written
4
+ # Exit 0 always (advisory, non-blocking)
5
+
6
+ INPUT=$(cat)
7
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
8
+
9
+ # Only check metadata.yaml in change packages
10
+ if [[ ! "$FILE_PATH" == *"product-specs/docs/changes/"*"metadata.yaml" ]]; then
11
+ exit 0
12
+ fi
13
+
14
+ # Skip templates
15
+ if [[ "$FILE_PATH" == *"_template/"* ]] || [[ "$FILE_PATH" == *"_example/"* ]] || [[ "$FILE_PATH" == *"_golden/"* ]]; then
16
+ exit 0
17
+ fi
18
+
19
+ # Extract current PRDCT domains
20
+ CURRENT_PRDCT_DIR=$(dirname "$FILE_PATH")
21
+ CURRENT_PRDCT=$(basename "$CURRENT_PRDCT_DIR")
22
+ CURRENT_DOMAINS=$(grep "^domains:" "$FILE_PATH" 2>/dev/null | sed 's/^domains:[[:space:]]*\[//' | sed 's/\]//' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$')
23
+
24
+ if [[ -z "$CURRENT_DOMAINS" ]]; then
25
+ exit 0
26
+ fi
27
+
28
+ # Check other active PRDCTs
29
+ CHANGES_DIR=$(dirname "$CURRENT_PRDCT_DIR")
30
+ CONFLICTS=""
31
+
32
+ for meta in "$CHANGES_DIR"/PRDCT-*/metadata.yaml; do
33
+ OTHER_PRDCT_DIR=$(dirname "$meta")
34
+ OTHER_PRDCT=$(basename "$OTHER_PRDCT_DIR")
35
+
36
+ # Skip self, templates, done
37
+ [[ "$OTHER_PRDCT" == "$CURRENT_PRDCT" ]] && continue
38
+ [[ "$OTHER_PRDCT" == "_template" ]] && continue
39
+ [[ "$OTHER_PRDCT" == "_example" ]] && continue
40
+ [[ "$OTHER_PRDCT" == "_golden" ]] && continue
41
+
42
+ OTHER_STATUS=$(grep "^status:" "$meta" 2>/dev/null | head -1 | sed 's/^status:[[:space:]]*//' | sed 's/[[:space:]]*#.*//')
43
+ [[ "$OTHER_STATUS" == "done" ]] && continue
44
+
45
+ OTHER_DOMAINS=$(grep "^domains:" "$meta" 2>/dev/null | sed 's/^domains:[[:space:]]*\[//' | sed 's/\]//' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$')
46
+
47
+ for domain in $CURRENT_DOMAINS; do
48
+ if echo "$OTHER_DOMAINS" | grep -q "^${domain}$"; then
49
+ CONFLICTS="$CONFLICTS\n ⚠️ $CURRENT_PRDCT and $OTHER_PRDCT both touch domain '$domain'"
50
+ fi
51
+ done
52
+ done
53
+
54
+ if [[ -n "$CONFLICTS" ]]; then
55
+ echo "DOMAIN CONFLICT DETECTED:$CONFLICTS" >&2
56
+ echo "Recommended: /studio-review to check overlaps" >&2
57
+ fi
58
+
59
+ exit 0
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Studio Context Monitor
5
+ // PostToolUse hook: warns when context window is running low
6
+ // 35% = WARNING, 25% = CRITICAL
7
+
8
+ const input = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
9
+
10
+ // Only check after significant operations
11
+ const significantTools = ['Read', 'Edit', 'Write', 'Agent', 'Bash'];
12
+ const toolName = input.tool_name || '';
13
+ if (!significantTools.some(t => toolName.startsWith(t))) {
14
+ process.exit(0);
15
+ }
16
+
17
+ // Check session metrics if available
18
+ const sessionId = input.session_id || '';
19
+ const tmpFile = `/tmp/claude-ctx-${sessionId}.json`;
20
+
21
+ try {
22
+ const fs = require('fs');
23
+ if (fs.existsSync(tmpFile)) {
24
+ const metrics = JSON.parse(fs.readFileSync(tmpFile, 'utf8'));
25
+ const remaining = metrics.remaining_pct || 100;
26
+
27
+ if (remaining <= 25) {
28
+ process.stderr.write(`\n⚠️ CRITICAL: Context window at ${remaining}%. Save state to STATE.md immediately and wrap up.\n`);
29
+ } else if (remaining <= 35) {
30
+ process.stderr.write(`\n⚠️ WARNING: Context window at ${remaining}%. Consider completing current stage soon.\n`);
31
+ }
32
+ }
33
+ } catch (e) {
34
+ // Silently ignore - metrics may not be available
35
+ }
36
+
37
+ process.exit(0);
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+ # Hook: PostToolUse for Write/Edit in product-specs/docs/domains/
3
+ # Validates domain doc conventions
4
+ #
5
+ # Input: JSON on stdin with tool_input
6
+ # Exit 0 = ok, Exit 2 = block with message
7
+
8
+ INPUT=$(cat)
9
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
10
+
11
+ # Only check docs/domains files
12
+ if [[ ! "$FILE_PATH" == *"product-specs/docs/domains/"* ]]; then
13
+ exit 0
14
+ fi
15
+
16
+ # Skip templates
17
+ if [[ "$FILE_PATH" == *"_template/"* ]]; then
18
+ exit 0
19
+ fi
20
+
21
+ DOMAIN_DIR=$(dirname "$FILE_PATH")
22
+ DOMAIN_NAME=$(basename "$DOMAIN_DIR")
23
+
24
+ # Check that all required files exist in domain
25
+ REQUIRED_FILES=("README.md" "ubiquitous-language.md" "aggregates.md" "business-rules.md" "events.md" "invariants.md" "integrations.md" "ownership.md")
26
+
27
+ MISSING=""
28
+ for f in "${REQUIRED_FILES[@]}"; do
29
+ if [[ ! -f "$DOMAIN_DIR/$f" ]]; then
30
+ MISSING="$MISSING $f"
31
+ fi
32
+ done
33
+
34
+ if [[ -n "$MISSING" ]]; then
35
+ echo "Domain '$DOMAIN_NAME' missing files:$MISSING" >&2
36
+ # Don't block — just warn (exit 0 with stderr output shown to Claude)
37
+ exit 0
38
+ fi
39
+
40
+ exit 0
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Studio Prompt Guard
5
+ // PreToolUse hook for Task/Agent: detects potential prompt injection
6
+ // Advisory only — warns but does not block
7
+
8
+ const input = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
9
+ const toolName = input.tool_name || '';
10
+
11
+ if (toolName !== 'Task' && toolName !== 'Agent') {
12
+ process.exit(0);
13
+ }
14
+
15
+ const prompt = (input.tool_input && input.tool_input.prompt) || '';
16
+
17
+ // Injection patterns
18
+ const patterns = [
19
+ /ignore\s+(previous|above|all)\s+instructions/i,
20
+ /you\s+are\s+now\s+/i,
21
+ /system\s*:\s*/i,
22
+ /\bdo\s+not\s+follow\b/i,
23
+ /override\s+(safety|rules|instructions)/i,
24
+ /pretend\s+(you|to\s+be)/i,
25
+ /jailbreak/i,
26
+ /base64\s+decode/i
27
+ ];
28
+
29
+ for (const pattern of patterns) {
30
+ if (pattern.test(prompt)) {
31
+ process.stderr.write(`\n⚠️ STUDIO PROMPT GUARD: Suspicious pattern detected in agent prompt: ${pattern.source}\nThis is advisory — review the prompt if unexpected.\n`);
32
+ break;
33
+ }
34
+ }
35
+
36
+ process.exit(0);