Compare commits
19 Commits
49a8a3b2af
...
1006295bc7
| Author | SHA1 | Date |
|---|---|---|
|
|
1006295bc7 | |
|
|
e600181ab8 | |
|
|
cd8ac7e9aa | |
|
|
b0b1796227 | |
|
|
9d5739d992 | |
|
|
606ad6063b | |
|
|
cfafc89cf6 | |
|
|
07d34fb43a | |
|
|
5bcc235cdb | |
|
|
3970ace793 | |
|
|
77628f0055 | |
|
|
4104598460 | |
|
|
c8784a167b | |
|
|
47cf70f0e8 | |
|
|
3e2085975a | |
|
|
0674ce7381 | |
|
|
1d1a4070d5 | |
|
|
5cf4e72092 | |
|
|
92417e748b |
|
|
@ -13,13 +13,14 @@
|
||||||
"name": "bmad-pro-skills",
|
"name": "bmad-pro-skills",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"description": "Next level skills for power users — advanced prompting techniques, agent management, and more.",
|
"description": "Next level skills for power users — advanced prompting techniques, agent management, and more.",
|
||||||
"version": "6.6.0",
|
"version": "6.8.0",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Brian (BMad) Madison"
|
"name": "Brian (BMad) Madison"
|
||||||
},
|
},
|
||||||
"skills": [
|
"skills": [
|
||||||
"./src/core-skills/bmad-help",
|
"./src/core-skills/bmad-help",
|
||||||
"./src/core-skills/bmad-brainstorming",
|
"./src/core-skills/bmad-brainstorming",
|
||||||
|
"./src/core-skills/bmad-customize",
|
||||||
"./src/core-skills/bmad-spec",
|
"./src/core-skills/bmad-spec",
|
||||||
"./src/core-skills/bmad-party-mode",
|
"./src/core-skills/bmad-party-mode",
|
||||||
"./src/core-skills/bmad-shard-doc",
|
"./src/core-skills/bmad-shard-doc",
|
||||||
|
|
@ -35,12 +36,13 @@
|
||||||
"name": "bmad-method-lifecycle",
|
"name": "bmad-method-lifecycle",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"description": "Full-lifecycle AI development framework — agents and workflows for product analysis, planning, architecture, and implementation.",
|
"description": "Full-lifecycle AI development framework — agents and workflows for product analysis, planning, architecture, and implementation.",
|
||||||
"version": "6.6.0",
|
"version": "6.8.0",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Brian (BMad) Madison"
|
"name": "Brian (BMad) Madison"
|
||||||
},
|
},
|
||||||
"skills": [
|
"skills": [
|
||||||
"./src/bmm-skills/1-analysis/bmad-product-brief",
|
"./src/bmm-skills/1-analysis/bmad-product-brief",
|
||||||
|
"./src/bmm-skills/1-analysis/bmad-prfaq",
|
||||||
"./src/bmm-skills/1-analysis/bmad-agent-analyst",
|
"./src/bmm-skills/1-analysis/bmad-agent-analyst",
|
||||||
"./src/bmm-skills/1-analysis/bmad-agent-tech-writer",
|
"./src/bmm-skills/1-analysis/bmad-agent-tech-writer",
|
||||||
"./src/bmm-skills/1-analysis/bmad-document-project",
|
"./src/bmm-skills/1-analysis/bmad-document-project",
|
||||||
|
|
@ -49,18 +51,22 @@
|
||||||
"./src/bmm-skills/1-analysis/research/bmad-technical-research",
|
"./src/bmm-skills/1-analysis/research/bmad-technical-research",
|
||||||
"./src/bmm-skills/2-plan-workflows/bmad-agent-pm",
|
"./src/bmm-skills/2-plan-workflows/bmad-agent-pm",
|
||||||
"./src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer",
|
"./src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer",
|
||||||
|
"./src/bmm-skills/2-plan-workflows/bmad-prd",
|
||||||
"./src/bmm-skills/2-plan-workflows/bmad-create-prd",
|
"./src/bmm-skills/2-plan-workflows/bmad-create-prd",
|
||||||
"./src/bmm-skills/2-plan-workflows/bmad-edit-prd",
|
"./src/bmm-skills/2-plan-workflows/bmad-edit-prd",
|
||||||
"./src/bmm-skills/2-plan-workflows/bmad-validate-prd",
|
"./src/bmm-skills/2-plan-workflows/bmad-validate-prd",
|
||||||
"./src/bmm-skills/2-plan-workflows/bmad-create-ux-design",
|
"./src/bmm-skills/2-plan-workflows/bmad-ux",
|
||||||
"./src/bmm-skills/3-solutioning/bmad-agent-architect",
|
"./src/bmm-skills/3-solutioning/bmad-agent-architect",
|
||||||
|
"./src/bmm-skills/3-solutioning/bmad-architecture",
|
||||||
"./src/bmm-skills/3-solutioning/bmad-create-architecture",
|
"./src/bmm-skills/3-solutioning/bmad-create-architecture",
|
||||||
"./src/bmm-skills/3-solutioning/bmad-check-implementation-readiness",
|
"./src/bmm-skills/3-solutioning/bmad-check-implementation-readiness",
|
||||||
"./src/bmm-skills/3-solutioning/bmad-create-epics-and-stories",
|
"./src/bmm-skills/3-solutioning/bmad-create-epics-and-stories",
|
||||||
"./src/bmm-skills/3-solutioning/bmad-generate-project-context",
|
"./src/bmm-skills/3-solutioning/bmad-generate-project-context",
|
||||||
"./src/bmm-skills/4-implementation/bmad-agent-dev",
|
"./src/bmm-skills/4-implementation/bmad-agent-dev",
|
||||||
|
"./src/bmm-skills/4-implementation/bmad-investigate",
|
||||||
"./src/bmm-skills/4-implementation/bmad-dev-story",
|
"./src/bmm-skills/4-implementation/bmad-dev-story",
|
||||||
"./src/bmm-skills/4-implementation/bmad-quick-dev",
|
"./src/bmm-skills/4-implementation/bmad-quick-dev",
|
||||||
|
"./src/bmm-skills/4-implementation/bmad-checkpoint-preview",
|
||||||
"./src/bmm-skills/4-implementation/bmad-sprint-planning",
|
"./src/bmm-skills/4-implementation/bmad-sprint-planning",
|
||||||
"./src/bmm-skills/4-implementation/bmad-sprint-status",
|
"./src/bmm-skills/4-implementation/bmad-sprint-status",
|
||||||
"./src/bmm-skills/4-implementation/bmad-code-review",
|
"./src/bmm-skills/4-implementation/bmad-code-review",
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,8 @@ CLAUDE.local.md
|
||||||
.claude/settings.local.json
|
.claude/settings.local.json
|
||||||
.junie/
|
.junie/
|
||||||
.agents/
|
.agents/
|
||||||
|
.analysis/
|
||||||
|
|
||||||
|
|
||||||
z*/
|
z*/
|
||||||
!docs/zh-cn/
|
!docs/zh-cn/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|

|
||||||
|
|
||||||
|
[](https://www.npmjs.com/package/bmad-method)
|
||||||
|
[](LICENSE)
|
||||||
|
[](https://nodejs.org)
|
||||||
|
[](https://www.python.org)
|
||||||
|
[](https://docs.astral.sh/uv/)
|
||||||
|
[](https://discord.gg/gk8jAdXWmj)
|
||||||
|
|
||||||
|
[English](README.md) | [简体中文](README_CN.md) | [Tiếng Việt](README_VN.md) | 한국어
|
||||||
|
|
||||||
|
**Build More Architect Dreams** - BMad Method 모듈 생태계를 위한 포괄적인 AI 기반 애자일 개발 프레임워크입니다. 버그 수정부터 엔터프라이즈 시스템까지, 프로젝트 규모와 도메인에 맞춰 계획 깊이를 조절합니다.
|
||||||
|
|
||||||
|
**100% 무료 오픈 소스입니다.** 유료 장벽도, 잠긴 콘텐츠도, 폐쇄형 Discord도 없습니다. 우리는 닫힌 커뮤니티나 강좌 비용을 낼 수 있는 사람만이 아니라 모두가 더 나은 도구를 쓸 수 있어야 한다고 믿습니다.
|
||||||
|
|
||||||
|
## 왜 BMad Method인가요?
|
||||||
|
|
||||||
|
전통적인 AI 도구는 사용자를 대신해 생각하고 평균적인 결과를 내는 데 그치는 경우가 많습니다. BMad의 전문 에이전트와 안내형 워크플로는 AI와 함께 더 나은 사고를 끌어내도록 돕는 전문가 협업자처럼 작동합니다.
|
||||||
|
|
||||||
|
- **AI 안내 도움말** - 언제든 `bmad-help` 스킬을 호출해 다음 단계 안내를 받습니다
|
||||||
|
- **규모와 도메인에 적응** - 프로젝트 복잡도에 맞춰 계획 깊이를 자동으로 조절합니다
|
||||||
|
- **구조화된 워크플로** - 분석, 계획, 아키텍처, 구현 전반에 애자일 모범 사례를 적용합니다
|
||||||
|
- **전문 에이전트** - PM, 아키텍트, 개발자, UX 등 12개 이상의 역할별 전문가를 제공합니다
|
||||||
|
- **파티 모드** - 여러 에이전트 페르소나를 한 세션에 불러와 함께 협업하고 토론합니다
|
||||||
|
- **전체 수명주기 지원** - 브레인스토밍부터 배포까지 함께합니다
|
||||||
|
|
||||||
|
[**docs.bmad-method.org**에서 더 알아보기](https://docs.bmad-method.org/ko-kr/)
|
||||||
|
|
||||||
|
## BMad의 다음 단계
|
||||||
|
|
||||||
|
**V6가 출시됐고, 이제 시작입니다!** BMad Method는 크로스 플랫폼 에이전트 팀과 서브 에이전트 통합, 스킬 아키텍처, BMad 빌더 v1, 개발 루프 자동화 등 여러 개선과 함께 빠르게 진화하고 있습니다.
|
||||||
|
|
||||||
|
**[전체 로드맵 보기](https://docs.bmad-method.org/ko-kr/roadmap/)**
|
||||||
|
|
||||||
|
## 빠른 시작
|
||||||
|
|
||||||
|
**필수 조건**: [Node.js](https://nodejs.org) v20.12+ · [Python](https://www.python.org) 3.10+ · [uv](https://docs.astral.sh/uv/)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install
|
||||||
|
```
|
||||||
|
|
||||||
|
> 최신 사전 릴리스 빌드를 사용하려면 `npx bmad-method@next install`을 실행하세요. 기본 설치보다 변경이 더 잦을 수 있습니다.
|
||||||
|
|
||||||
|
설치 프로그램의 안내를 따른 다음, Claude Code나 Cursor 같은 AI IDE를 프로젝트 폴더에서 엽니다.
|
||||||
|
|
||||||
|
**비대화형 설치**(CI/CD용):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --directory /path/to/project --modules bmm --tools claude-code --yes
|
||||||
|
```
|
||||||
|
|
||||||
|
모듈 설정 옵션은 `--set <module>.<key>=<value>`로 재정의할 수 있습니다. 여러 번 사용할 수 있습니다. 로컬에서 알려진 공식 키를 보려면 `--list-options [module]`을 실행하세요.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --yes \
|
||||||
|
--modules bmm --tools claude-code \
|
||||||
|
--set bmm.project_knowledge=research \
|
||||||
|
--set bmm.user_skill_level=expert
|
||||||
|
```
|
||||||
|
|
||||||
|
[전체 설치 옵션 보기](https://docs.bmad-method.org/ko-kr/how-to/non-interactive-installation/)
|
||||||
|
|
||||||
|
> **무엇을 해야 할지 모르겠나요?** `bmad-help`에게 물어보세요. 다음에 해야 할 일과 선택 사항을 정확히 알려줍니다. `bmad-help 아키텍처를 막 끝냈는데 다음에 무엇을 해야 하나요?`처럼 질문할 수도 있습니다.
|
||||||
|
|
||||||
|
## 모듈
|
||||||
|
|
||||||
|
BMad Method는 전문 도메인을 위한 공식 모듈로 확장됩니다. 설치 중에 선택하거나 나중에 추가할 수 있습니다.
|
||||||
|
|
||||||
|
| 모듈 | 목적 |
|
||||||
|
| ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
|
||||||
|
| **[BMad Method(BMM)](https://github.com/bmad-code-org/BMAD-METHOD)** | 34개 이상의 워크플로를 제공하는 핵심 프레임워크 |
|
||||||
|
| **[BMad 빌더(BMB)](https://github.com/bmad-code-org/bmad-builder)** | 커스텀 BMad 에이전트와 워크플로 생성 |
|
||||||
|
| **[테스트 설계자(TEA)](https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise)** | 위험 기반 테스트 전략과 자동화 |
|
||||||
|
| **[게임 개발 스튜디오(BMGD)](https://github.com/bmad-code-org/bmad-module-game-dev-studio)** | Unity, Unreal, Godot 워크플로 |
|
||||||
|
| **[창의적 지능 제품군(CIS)](https://github.com/bmad-code-org/bmad-module-creative-intelligence-suite)** | 혁신, 브레인스토밍, 디자인 사고 |
|
||||||
|
|
||||||
|
## Web Bundles
|
||||||
|
|
||||||
|
V4에도 Web bundle이 있었습니다. V6에서는 새롭게 개선된 형태로 다시 돌아왔습니다.
|
||||||
|
|
||||||
|
Web bundle은 선택한 BMad 스킬을 **Google Gemini Gem**과 **ChatGPT Custom GPT**로 설치할 수 있게 패키징합니다. 브레인스토밍, 제품 개요, PRD, PRFAQ, UX 사양, 시장 및 산업 리서치 같은 앞단 계획 작업은 웹 LLM 구독 환경에서 진행하고, 다듬어진 산출물은 IDE로 가져와 구현에 사용하세요. 계획 작업을 사용량 과금형 IDE 토큰 대신 정액 구독 환경에서 처리하므로 긴 작업에서는 비용을 줄이는 데 도움이 됩니다. Gemini나 ChatGPT에서 사용할 수 있는 가장 좋은 모델을 선택하면 됩니다.
|
||||||
|
|
||||||
|
현재 제공되는 번들은 브레인스토밍, 제품 개요, PRFAQ, PRD, UX, 시장 및 산업 리서치입니다.
|
||||||
|
|
||||||
|
**[bmadcode.com/web-bundles](https://bmadcode.com/web-bundles/)에서 찾아보고 설치하세요.** 번들마다 카드가 하나씩 있고, Gemini와 ChatGPT 설치 단계가 페이지 안에 안내되며, ZIP 파일도 바로 다운로드할 수 있습니다. 개념 설명은 [Web bundle 가이드](https://docs.bmad-method.org/ko-kr/explanation/web-bundles/)를 참고하세요.
|
||||||
|
|
||||||
|
## 문서
|
||||||
|
|
||||||
|
[BMad Method 문서 사이트](https://docs.bmad-method.org/ko-kr/) - 튜토리얼, 가이드, 개념 설명, 참조 문서
|
||||||
|
|
||||||
|
**빠른 링크:**
|
||||||
|
|
||||||
|
- [시작하기 튜토리얼](https://docs.bmad-method.org/ko-kr/tutorials/getting-started/)
|
||||||
|
- [이전 버전에서 업그레이드](https://docs.bmad-method.org/ko-kr/how-to/upgrade-to-v6/)
|
||||||
|
- [테스트 설계자 문서](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/)
|
||||||
|
|
||||||
|
## 커뮤니티
|
||||||
|
|
||||||
|
- [Discord](https://discord.gg/gk8jAdXWmj) - 도움을 받고, 아이디어를 나누고, 협업하세요
|
||||||
|
- [YouTube](https://youtube.com/@BMadCode) - 튜토리얼, 마스터 클래스 등
|
||||||
|
- [X / Twitter](https://x.com/BMadCode)
|
||||||
|
- [웹사이트](https://bmadcode.com)
|
||||||
|
- [GitHub Issues](https://github.com/bmad-code-org/BMAD-METHOD/issues) - 버그 제보와 기능 요청
|
||||||
|
- [토론](https://github.com/bmad-code-org/BMAD-METHOD/discussions) - 커뮤니티 대화
|
||||||
|
|
||||||
|
## BMad 후원
|
||||||
|
|
||||||
|
BMad는 모두에게 무료이며 앞으로도 그럴 것입니다. 이 저장소에 스타를 눌러 주거나, [커피 한 잔 후원](https://buymeacoffee.com/bmad)을 보내거나, 기업 후원은 <contact@bmadcode.com>으로 문의해 주세요.
|
||||||
|
|
||||||
|
## 기여
|
||||||
|
|
||||||
|
기여를 환영합니다! 자세한 지침은 [CONTRIBUTING.md](CONTRIBUTING.md)를 확인하세요.
|
||||||
|
|
||||||
|
## 라이선스
|
||||||
|
|
||||||
|
MIT 라이선스입니다. 자세한 내용은 [LICENSE](LICENSE)를 확인하세요.
|
||||||
|
|
||||||
|
**BMad**와 **BMAD-METHOD**는 BMad Code, LLC의 상표입니다. 자세한 내용은 [TRADEMARK.md](TRADEMARK.md)를 확인하세요.
|
||||||
|
|
||||||
|
[](https://github.com/bmad-code-org/BMAD-METHOD/graphs/contributors)
|
||||||
|
|
||||||
|
기여자 정보는 [CONTRIBUTORS.md](CONTRIBUTORS.md)를 확인하세요.
|
||||||
|
|
@ -1,59 +1,150 @@
|
||||||
---
|
---
|
||||||
title: "Party Mode"
|
title: "Party Mode"
|
||||||
description: Multi-agent collaboration - get all your AI agents in one conversation
|
description: Get your AI agents in one conversation — run them, build your own cast, and choose how independently they think
|
||||||
sidebar:
|
sidebar:
|
||||||
order: 11
|
order: 11
|
||||||
---
|
---
|
||||||
|
|
||||||
Get all your AI agents in one conversation.
|
Party mode puts your AI agents in one room and lets them talk, to each other and to you. This page explains what a party is, the four ways it can run, how to build your own cast of personas instead of using the installed agents, and how a party remembers you between sessions.
|
||||||
|
|
||||||
## What is Party Mode?
|
## What is Party Mode?
|
||||||
|
|
||||||
Run `bmad-party-mode` and you've got your whole AI team in one room - PM, Architect, Dev, UX Designer, whoever you need. Party Mode orchestrates the discussion, picking relevant installed agents per message. Agents respond in character, agree, disagree, and build on each other's ideas.
|
Run `bmad-party-mode` and the BMad agents you already have installed gather in one conversation: the PM, Architect, Dev, UX Designer, and whoever else your selected modules bring. That installed lineup is your default party, ready with no setup. They answer in character, agree, disagree, and build on each other. You steer the room. Ask a follow-up, push back, pull one voice forward, or change the subject. The conversation runs until you end it.
|
||||||
|
|
||||||
The conversation continues as long as you want. Ask follow-ups, push back on answers, redirect the discussion - it's a real back-and-forth with your agents until you're done.
|
It works because the personas hold different priorities. The Architect guards the design, the PM guards scope, the Dev guards what's actually buildable. Put them in the same room and the tradeoff surfaces now, in the conversation, instead of three weeks into the sprint.
|
||||||
|
|
||||||
**Good for:**
|
**Good for:**
|
||||||
|
|
||||||
- Big decisions with tradeoffs
|
- Decisions with real tradeoffs
|
||||||
- Brainstorming sessions
|
- Brainstorming and "what are we missing?"
|
||||||
- Post-mortems when things go wrong
|
- Post-mortems and retrospectives
|
||||||
- Sprint retrospectives and planning
|
- Pressure-testing a plan before you commit
|
||||||
|
|
||||||
## Examples
|
Party mode is also a fast and genuinely fun way to brainstorm, since the personas have opinions and they clash. And you can start a party from inside any other workflow: mid-brainstorm, mid-PRD, while coding, working a sales angle, or shaping a creative piece. Any time you want more perspectives on what's in front of you, pull in a room without dropping what you were doing.
|
||||||
|
|
||||||
### Calling Out Bad Architecture
|
:::note[Example]
|
||||||
|
**You:** Monolith or microservices for the MVP?
|
||||||
|
|
||||||
**You:** "Okay team, our last sprint was a disaster. The authentication service went down three times. Who screwed this up?"
|
**Architect:** Start monolith. Microservices add operating cost you don't need at a thousand users.
|
||||||
|
|
||||||
**Architect:** "The design was sound - distributed authentication with proper fallbacks. If implementation deviated from the spec..."
|
**PM:** Agreed. Time to market matters more than scaling we can't prove yet.
|
||||||
|
|
||||||
**Dev:** "I followed the architecture doc exactly. The spec didn't account for concurrent session invalidation race conditions."
|
**Dev:** Monolith, but with clean module boundaries so we can split a service out later without a rewrite.
|
||||||
|
:::
|
||||||
**PM:** "Both of you missed the bigger issue - we didn't validate session management requirements in the PRD. This is on me for not catching it."
|
|
||||||
|
## Starting a party
|
||||||
**TEA:** "And I should've caught this in integration tests. The test scenarios didn't cover concurrent invalidation."
|
|
||||||
|
Invoke the skill and say what you want; it works out whether you mean to run a party or build one.
|
||||||
### Creative Brainstorming
|
|
||||||
|
| Goal | Type this |
|
||||||
**You:** "How do we make onboarding feel magical instead of boring?"
|
| --- | --- |
|
||||||
|
| Start a party in the default mode | `/bmad-party-mode` |
|
||||||
**UX Designer:** "Start with progressive disclosure - reveal features as users need them, not all at once in a tutorial."
|
| Start in a specific mode | `/bmad-party-mode --mode auto` (also `session`, `subagent`, `agent-team`) |
|
||||||
|
| Open a saved party | `/bmad-party-mode --party code-review-crew` |
|
||||||
**Storyteller:** "What if onboarding was a story? Each step reveals a character's journey - the user IS the hero."
|
| Conjure a cast on the spot | "party mode with the bridge crew of the Enterprise" |
|
||||||
|
| Create or add a party | "party mode, create a new party" |
|
||||||
**Game Designer:** "Building on that - what if the first 'quest' is actually solving a real user problem? They learn by doing something valuable."
|
| Edit an existing party | "party mode, edit the writers' room" |
|
||||||
|
| Customize the skill | `/bmad-customize bmad-party-mode` |
|
||||||
### Technical Decision
|
|
||||||
|
## How a party runs
|
||||||
**You:** "Monolith or microservices for MVP?"
|
|
||||||
|
A party can run in four modes. One mode is active per session, and it decides who does the thinking: a single model voicing everyone, or separate agents reasoning on their own.
|
||||||
**Architect:** "Start monolith. Microservices add complexity you don't need at 1000 users."
|
|
||||||
|
| Mode | What it does | Reach for it when |
|
||||||
**PM:** "Agree. Time to market matters more than theoretical scalability."
|
| --- | --- | --- |
|
||||||
|
| `session` | Default. One model voices every persona inline. Fast and fully conversational. | Most conversations — banter, brainstorming, quick back-and-forth. |
|
||||||
**Dev:** "Monolith with clear module boundaries. We can extract services later if needed."
|
| `auto` | Voices inline for light rounds, spawns independent agents only when independence changes the answer. | You want speed most of the time but real independence on the hard rounds. |
|
||||||
|
| `subagent` | Spawns a separate agent for each persona every substantive round, so no single mind colors them all. | Honest reviews and focus groups, where the voices must not bleed together. |
|
||||||
:::tip[Better Decisions]
|
| `agent-team` | Stands the personas up as a persistent team that address each other directly. Claude Code only. | A live, hands-off round-table where the agents talk among themselves. |
|
||||||
Better decisions through diverse perspectives. Welcome to party mode.
|
|
||||||
|
The choice matters because one model voicing five personas can quietly converge: they share a mind. Spawning real agents keeps their reasoning separate, which is the entire point of a review panel or a focus group. `session` is the cheapest and most fluid. The spawning modes cost more but protect independence, and `auto` aims for both by spawning only when a round needs it.
|
||||||
|
|
||||||
|
`session` is the default, and every other mode falls back to it when a harness can't do the rest: `agent-team` drops to `subagent`, then to `session`. The configured default lives in your customization, and a runtime override wins for that session.
|
||||||
|
|
||||||
|
:::tip[Override for one session]
|
||||||
|
Start a party with `--mode subagent` (or `auto`, `agent-team`, `session`) to override the configured default just for that run.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Custom parties
|
||||||
|
|
||||||
|
Out of the box, a party uses your installed BMad agents. The larger use is building your own cast from any set of personas you can describe, then saving it to reuse. You author a party through the same skill. It detects whether you want to run one or build one, and writes the result to your overrides through [bmad-customize](../how-to/customize-bmad.md).
|
||||||
|
|
||||||
|
Party mode is customizable like every BMad skill. Run `/bmad-customize bmad-party-mode` to set its defaults directly: pin any group you've built as the default party so it loads without a flag, choose which mode it starts in, and set any house rules the room should hold for the whole session.
|
||||||
|
|
||||||
|
Two ideas do most of the work.
|
||||||
|
|
||||||
|
**Personas** are what make a member unmistakable: how they talk, what they value, how they argue, their pet peeves and blind spots. "Skeptical CFO" is a placeholder. "Won't approve anything without a payback under eighteen months, and says so in the first thirty seconds" is a persona. That detail is what gives a voice you'd recognize with the name labels hidden.
|
||||||
|
|
||||||
|
**Scenes** set the stage. A scene is one freeform line: the setting, what's happening, who's hostile to whom, who pushes hardest. The same members play it differently each time, so you define a person once and drop them into a bridge crew on duty, the same crew off-duty in the lounge, or a hostile buyer panel. Members combine into named groups, and you can pin one group as the default room.
|
||||||
|
|
||||||
|
### Shapes a party can take
|
||||||
|
|
||||||
|
| Shape | What it is |
|
||||||
|
| --- | --- |
|
||||||
|
| Themed cast | Famous investors, a TV ensemble — distinct voices gathered around a topic. |
|
||||||
|
| One-off personas | A persona or two added to the pool, no group needed. |
|
||||||
|
| Focus group from data | Hand it customer or survey data; it clusters people by what drives their behavior and builds representative personas. Pair it with `subagent` mode so the customers stay independent. |
|
||||||
|
| Review panel | Purpose-built critical lenses that argue about what matters. The shipped Code Review Crew is one. |
|
||||||
|
| Open-cast room | No fixed roster. The scene names a universe and the room is cast on the fly as the topic shifts. |
|
||||||
|
|
||||||
|
A focus group is the case that pays off most. Feed in real profiles and you get a standing panel of representative customers to test an idea against before you build it, each reacting from their own goals and budget instead of agreeing with the last voice.
|
||||||
|
|
||||||
|
## Parties you could build
|
||||||
|
|
||||||
|
A party is only personas and a scene, so the range is wide, and none of it needs a new skill or module:
|
||||||
|
|
||||||
|
- A founder squad to stress-test a startup idea.
|
||||||
|
- A compliance team to find the holes before an audit does.
|
||||||
|
- The authors of the Agile Manifesto, debating a software concept.
|
||||||
|
- A room of comedians as a writing-partner group.
|
||||||
|
- Great minds of the past, to work through a question in philosophy or untangle a hard problem.
|
||||||
|
- A business management team to plan the quarter.
|
||||||
|
|
||||||
|
These are starting points. Any set of voices you can describe becomes a party: write the personas, give the room a scene, and you have it.
|
||||||
|
|
||||||
|
## The Code Review Crew
|
||||||
|
|
||||||
|
Your default party is the agents your installed modules provide. The Code Review Crew is a custom party BMad ships alongside that default — a working template to study before you build your own, not a replacement for it. It's a review panel: five lenses that attack a change from different angles and argue about what actually matters, instead of rubber-stamping it.
|
||||||
|
|
||||||
|
| Member | Lens |
|
||||||
|
| --- | --- |
|
||||||
|
| Vex | Security — threat-models everything and names the concrete exploit path. |
|
||||||
|
| Grumbal | The adversary — assumes the code is broken and sets out to prove it. |
|
||||||
|
| Boundary | Edge cases — every branch, null, race, oversized input, odd timezone. |
|
||||||
|
| Yui | The craftsman — simplicity, naming, no needless cleverness or duplication. |
|
||||||
|
| Dana | The pragmatist — counters the perfectionists and ranks what's real versus a nit. |
|
||||||
|
|
||||||
|
The crew ships defined but inactive. The members sit in the pool and cost nothing until you summon the group, and they never crowd your default room. Run it with `subagent` mode so each lens reviews on its own before the five clash over the findings.
|
||||||
|
|
||||||
|
## Steering the conversation
|
||||||
|
|
||||||
|
You drive the room the whole way:
|
||||||
|
|
||||||
|
- Bring someone in: "Bring in the UX designer."
|
||||||
|
- Go deep on one voice: "Winston, take that apart." A direct ask is the cue for one persona to stretch out.
|
||||||
|
- Switch rooms mid-session: "Switch to the writers' room" swaps the active group and carries the thread over.
|
||||||
|
- Summon anyone by name, even a custom member who isn't in the current room.
|
||||||
|
|
||||||
|
Whichever mode is running, the orchestrator presents the result as one conversation rather than a stack of separate answers, and it keeps the personas in character — it won't break the fourth wall to narrate the mechanism.
|
||||||
|
|
||||||
|
:::tip[Mix more than one room]
|
||||||
|
You aren't limited to a single group. Pull members from several parties into the same conversation, or name a cast on the spot, and let them mix. Picture the Golden Girls thrown into an architecture review with Martin Fowler and Linus Torvalds, sparring over a change request: you can imagine how that goes.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## The room remembers
|
||||||
|
|
||||||
|
Give a party a memory and it picks up where you left off. It keeps its own record of your past sessions — the dynamics that built up between members, the threads you left open, and where earlier conversations landed. Reopen it a week later and that history is intact: two members who came to blows last time still open a little frosty, and a sharp line from a past session can resurface as an organic callback.
|
||||||
|
|
||||||
|
It's memory, not a transcript. The room carries the few things worth remembering, not a log of everything said, so the next conversation feels continuous without dragging the whole past into it. It happens on its own, in the background — nothing to save, and the room never breaks character to announce it.
|
||||||
|
|
||||||
|
A character who turns up on the fly is remembered too — a walk-on from an open-cast scene, or someone you add mid-conversation. At the end of a session the room offers to keep the new arrivals, folding them into the party so they can come back next time.
|
||||||
|
|
||||||
|
Memory is set per party. When you create or save a party you're asked whether it should remember; the default installed-agent room remembers unless you turn it off. Set or change any of this through `/bmad-customize bmad-party-mode`.
|
||||||
|
|
||||||
|
## A keepsake of the session
|
||||||
|
|
||||||
|
When you wrap up, the orchestrator offers a keepsake: a single self-contained HTML document of the session to keep or share. It lays the conversation out by persona rather than dumping a raw transcript. Decline it and the party simply ends.
|
||||||
|
|
||||||
|
:::tip[Better decisions]
|
||||||
|
The value of a party is the disagreement. Diverse perspectives in one room catch what a single line of thinking misses.
|
||||||
:::
|
:::
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ La magie se produit dans les idées 50–100. Le workflow encourage la générat
|
||||||
1. Lit l’entrée et tout document annexe lié
|
1. Lit l’entrée et tout document annexe lié
|
||||||
2. Distille en un noyau à cinq champs via un modèle configurable ; redirige l’excédent vers des fichiers compagnons correctement nommés
|
2. Distille en un noyau à cinq champs via un modèle configurable ; redirige l’excédent vers des fichiers compagnons correctement nommés
|
||||||
3. Exécute une auto-validation en deux passes (règles de cohérence, puis préservation de chaque affirmation essentielle de la source)
|
3. Exécute une auto-validation en deux passes (règles de cohérence, puis préservation de chaque affirmation essentielle de la source)
|
||||||
4. Écrit `SPEC.md`, les compagnons associés, et un `.decision-log.md` sous `{output_folder}/specs/spec-{slug}/`
|
4. Écrit `SPEC.md`, les compagnons associés, et un `.memlog.md` sous `{output_folder}/specs/spec-{slug}/`
|
||||||
|
|
||||||
La loi Spec impose huit règles : les capacités expriment à la fois l’intention et le critère de succès ; les intentions décrivent le QUOI, pas le COMMENT ; les contraintes guident réellement les décisions ; les non-objectifs sont explicites ; les signaux de succès sont concrets ; les identifiants de capacité sont stables ; chaque affirmation essentielle de la source est préservée ; la rédaction est concise.
|
La loi Spec impose huit règles : les capacités expriment à la fois l’intention et le critère de succès ; les intentions décrivent le QUOI, pas le COMMENT ; les contraintes guident réellement les décisions ; les non-objectifs sont explicites ; les signaux de succès sont concrets ; les identifiants de capacité sont stables ; chaque affirmation essentielle de la source est préservée ; la rédaction est concise.
|
||||||
|
|
||||||
|
|
@ -123,7 +123,7 @@ La loi Spec impose huit règles : les capacités expriment à la fois l’inten
|
||||||
- `slug` (optionnel) — Requis uniquement lorsque l’entrée est succincte et qu’aucun slug ne peut être dérivé du nom de fichier source
|
- `slug` (optionnel) — Requis uniquement lorsque l’entrée est succincte et qu’aucun slug ne peut être dérivé du nom de fichier source
|
||||||
- `target_spec_path` (optionnel) — Définir pour mettre à jour une spécification existante au lieu d’en créer une nouvelle
|
- `target_spec_path` (optionnel) — Définir pour mettre à jour une spécification existante au lieu d’en créer une nouvelle
|
||||||
|
|
||||||
**Sortie :** Dossier de spécification contenant `SPEC.md`, les éventuels fichiers compagnons, et un `.decision-log.md`. Les appelants en mode headless reçoivent une réponse JSON avec le statut du résultat et la liste des fichiers écrits ou modifiés.
|
**Sortie :** Dossier de spécification contenant `SPEC.md`, les éventuels fichiers compagnons, et un `.memlog.md`. Les appelants en mode headless reçoivent une réponse JSON avec le statut du résultat et la liste des fichiers écrits ou modifiés.
|
||||||
|
|
||||||
:::note[Contrat de mutation]
|
:::note[Contrat de mutation]
|
||||||
`bmad-spec` est le seul outil autorisé à écrire `SPEC.md` et les fichiers compagnons de la spécification. Les autres compétences produisent leurs propres artefacts natifs et invoquent `bmad-spec` en mode headless lorsqu’elles ont besoin d’exprimer une intention sous forme de contrat canonique ou de proposer des mises à jour.
|
`bmad-spec` est le seul outil autorisé à écrire `SPEC.md` et les fichiers compagnons de la spécification. Les autres compétences produisent leurs propres artefacts natifs et invoquent `bmad-spec` en mode headless lorsqu’elles ont besoin d’exprimer une intention sous forme de contrat canonique ou de proposer des mises à jour.
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,13 @@ Définissez ce qu’il faut construire et pour qui.
|
||||||
|
|
||||||
| Workflow | Objectif | Livrable |
|
| Workflow | Objectif | Livrable |
|
||||||
|------------|--------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
|
|------------|--------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||||
| `bmad-prd` | Créez, mettez à jour ou validez un PRD[^1] — découverte accompagnée, trois intentions en un seul skill | Création/Mise à jour : `prd.md`, `addendum.md`, `decision-log.md` ; Validation : `validation-report.html` + `.md` |
|
| `bmad-prd` | Créez, mettez à jour ou validez un PRD[^1] — découverte accompagnée, trois intentions en un seul skill | Création/Mise à jour : `prd.md`, `addendum.md`, `.memlog.md` ; Validation : `validation-report.html` + `.md` |
|
||||||
| `bmad-ux` | Concevez l’expérience utilisateur (lorsque l’UX compte) | `DESIGN.md`, `EXPERIENCE.md` |
|
| `bmad-ux` | Concevez l’expérience utilisateur (lorsque l’UX compte) | `DESIGN.md`, `EXPERIENCE.md` |
|
||||||
|
|
||||||
:::tip[Trois intentions en un seul skill]
|
:::tip[Trois intentions en un seul skill]
|
||||||
`bmad-prd` couvre l’intégralité du cycle de vie du PRD. Précisez votre intention lors de l’appel, sinon le skill vous la demandera :
|
`bmad-prd` couvre l’intégralité du cycle de vie du PRD. Précisez votre intention lors de l’appel, sinon le skill vous la demandera :
|
||||||
|
|
||||||
- **Créer** — nouveau PRD à partir de zéro via une découverte accompagnée ; produit `prd.md`, `addendum.md` et `decision-log.md`
|
- **Créer** — nouveau PRD à partir de zéro via une découverte accompagnée ; produit `prd.md`, `addendum.md` et `.memlog.md`
|
||||||
- **Mettre à jour** — réconcilie un PRD existant avec un signal de changement, en mettant en évidence les conflits avant d’appliquer les modifications
|
- **Mettre à jour** — réconcilie un PRD existant avec un signal de changement, en mettant en évidence les conflits avant d’appliquer les modifications
|
||||||
- **Valider** — évalue un PRD à l’aide d’une liste de contrôle configurable et produit un rapport de constats structuré au format HTML
|
- **Valider** — évalue un PRD à l’aide d’une liste de contrôle configurable et produit un rapport de constats structuré au format HTML
|
||||||
:::
|
:::
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ Tous les workflows de cette phase sont optionnels. [**Vous ne savez pas lequel c
|
||||||
**Pour les voies BMad Method et Enterprise :**
|
**Pour les voies BMad Method et Enterprise :**
|
||||||
|
|
||||||
1. Exécutez `bmad-prd` dans un nouveau chat — précisez votre intention (Create / Update / Validate) ou laissez le skill vous la demander
|
1. Exécutez `bmad-prd` dans un nouveau chat — précisez votre intention (Create / Update / Validate) ou laissez le skill vous la demander
|
||||||
2. Résultat : `prd.md`, `addendum.md`, `decision-log.md`
|
2. Résultat : `prd.md`, `addendum.md`, `.memlog.md`
|
||||||
|
|
||||||
:::note[Intentions de `bmad-prd`]
|
:::note[Intentions de `bmad-prd`]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
title: 페이지를 찾을 수 없음
|
||||||
|
template: splash
|
||||||
|
---
|
||||||
|
|
||||||
|
찾으려는 페이지가 없거나 이동되었습니다.
|
||||||
|
|
||||||
|
[홈으로 돌아가기](./index.md)
|
||||||
|
|
@ -0,0 +1,370 @@
|
||||||
|
---
|
||||||
|
title: "문서 스타일 가이드"
|
||||||
|
description: Google 스타일과 Diataxis 구조를 바탕으로 한 프로젝트별 문서 작성 규칙
|
||||||
|
---
|
||||||
|
|
||||||
|
이 프로젝트는 [Google Developer 문서 스타일 가이드](https://developers.google.com/style)를 따르고 [Diataxis](https://diataxis.fr/)로 콘텐츠를 구조화합니다. 아래에는 프로젝트별 규칙만 정리합니다.
|
||||||
|
|
||||||
|
## 프로젝트별 규칙
|
||||||
|
|
||||||
|
| 규칙 | 사양 |
|
||||||
|
| --- | --- |
|
||||||
|
| 가로 구분선(`---`) 사용 금지 | 읽기 흐름을 끊습니다 |
|
||||||
|
| `####` 헤더 사용 금지 | 대신 굵은 글씨나 알림 상자를 사용합니다 |
|
||||||
|
| "관련 항목" 또는 "다음:" 섹션 금지 | 사이드바가 탐색을 담당합니다 |
|
||||||
|
| 깊게 중첩된 목록 금지 | 섹션으로 나누세요 |
|
||||||
|
| 코드가 아닌 내용에 코드 블록 사용 금지 | 대화 예시는 알림 상자를 사용합니다 |
|
||||||
|
| 콜아웃용 굵은 문단 금지 | 대신 알림 상자를 사용합니다 |
|
||||||
|
| 섹션당 알림 상자 1-2개까지 | 튜토리얼은 큰 섹션당 3-4개까지 허용합니다 |
|
||||||
|
| 표 셀 / 목록 항목 | 최대 1-2문장 |
|
||||||
|
| 헤더 예산 | 문서당 `##` 8-12개, 섹션당 `###` 2-3개 |
|
||||||
|
|
||||||
|
## 알림 상자(Starlight 문법)
|
||||||
|
|
||||||
|
```md
|
||||||
|
:::tip[제목]
|
||||||
|
단축키, 모범 사례
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::note[제목]
|
||||||
|
맥락, 정의, 예시, 필수 조건
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::caution[제목]
|
||||||
|
주의 사항, 잠재적 문제
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::danger[제목]
|
||||||
|
데이터 손실, 보안 문제 같은 중대한 경고에만 사용
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
### 표준 용도
|
||||||
|
|
||||||
|
| 알림 상자 | 사용처 |
|
||||||
|
| --- | --- |
|
||||||
|
| `:::note[필수 조건]` | 시작 전 필요한 의존성 |
|
||||||
|
| `:::tip[빠른 경로]` | 문서 상단의 짧은 요약 |
|
||||||
|
| `:::caution[중요]` | 중요한 주의 사항 |
|
||||||
|
| `:::note[예시]` | 명령/응답 예시 |
|
||||||
|
|
||||||
|
## 표준 표 형식
|
||||||
|
|
||||||
|
**단계:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
| 단계 | 이름 | 내용 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 1 | 분석 | 브레인스토밍, 리서치 *(선택 사항)* |
|
||||||
|
| 2 | 계획 | 요구사항 - PRD 또는 사양 *(필수)* |
|
||||||
|
```
|
||||||
|
|
||||||
|
**스킬:**
|
||||||
|
|
||||||
|
```md
|
||||||
|
| 스킬 | 에이전트 | 목적 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `bmad-brainstorming` | 분석가 | 새 프로젝트 브레인스토밍 |
|
||||||
|
| `bmad-prd` | PM | 제품 요구사항 문서 생성 |
|
||||||
|
```
|
||||||
|
|
||||||
|
## 폴더 구조 블록
|
||||||
|
|
||||||
|
"달성한 것" 섹션에서는 다음처럼 표시합니다.
|
||||||
|
|
||||||
|
````md
|
||||||
|
```
|
||||||
|
your-project/
|
||||||
|
├── _bmad/ # BMad 설정
|
||||||
|
├── _bmad-output/
|
||||||
|
│ ├── planning-artifacts/
|
||||||
|
│ │ └── PRD.md # 요구사항 문서
|
||||||
|
│ ├── implementation-artifacts/
|
||||||
|
│ └── project-context.md # 구현 규칙 (선택 사항)
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
## 튜토리얼 구조
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장(결과를 설명하는 1-2문장)
|
||||||
|
2. 버전/모듈 안내(정보 또는 경고 알림 상자, 선택)
|
||||||
|
3. 배울 내용(결과 중심 글머리표 목록)
|
||||||
|
4. 필수 조건(정보 알림 상자)
|
||||||
|
5. 빠른 경로(tip 알림 상자 - 짧은 요약)
|
||||||
|
6. [주제] 이해하기(단계 전 맥락 - 단계/에이전트 표)
|
||||||
|
7. 설치(선택)
|
||||||
|
8. 1단계: [첫 번째 주요 작업]
|
||||||
|
9. 2단계: [두 번째 주요 작업]
|
||||||
|
10. 3단계: [세 번째 주요 작업]
|
||||||
|
11. 달성한 것(요약 + 폴더 구조)
|
||||||
|
12. 빠른 참조(스킬 표)
|
||||||
|
13. 자주 묻는 질문(FAQ 형식)
|
||||||
|
14. 도움 받기(커뮤니티 링크)
|
||||||
|
15. 핵심 요약(tip 알림 상자)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 튜토리얼 체크리스트
|
||||||
|
|
||||||
|
- [ ] 후킹 문장이 결과를 1-2문장으로 설명합니다
|
||||||
|
- [ ] "배울 내용" 섹션이 있습니다
|
||||||
|
- [ ] 필수 조건이 알림 상자에 있습니다
|
||||||
|
- [ ] 상단에 빠른 경로 요약 알림 상자가 있습니다
|
||||||
|
- [ ] 단계, 스킬, 에이전트를 표로 제시합니다
|
||||||
|
- [ ] "달성한 것" 섹션이 있습니다
|
||||||
|
- [ ] 빠른 참조 표가 있습니다
|
||||||
|
- [ ] 자주 묻는 질문 섹션이 있습니다
|
||||||
|
- [ ] 도움 받기 섹션이 있습니다
|
||||||
|
- [ ] 마지막에 핵심 요약 알림 상자가 있습니다
|
||||||
|
|
||||||
|
## 사용 가이드 구조
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장("`X` 워크플로를 사용해..." 한 문장)
|
||||||
|
2. 사용 시점(3-5개 글머리표 목록)
|
||||||
|
3. 건너뛸 시점(선택)
|
||||||
|
4. 필수 조건(note 알림 상자)
|
||||||
|
5. 단계(번호가 붙은 ### 하위 섹션)
|
||||||
|
6. 얻는 결과(생성되는 산출물)
|
||||||
|
7. 예시(선택)
|
||||||
|
8. 팁(선택)
|
||||||
|
9. 다음 단계(선택)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 사용 가이드 체크리스트
|
||||||
|
|
||||||
|
- [ ] 후킹 문장이 "`X` 워크플로를 사용해..."로 시작합니다
|
||||||
|
- [ ] "사용 시점"에 3-5개 글머리표가 있습니다
|
||||||
|
- [ ] 필수 조건이 나열되어 있습니다
|
||||||
|
- [ ] 단계는 동작 동사로 시작하는 번호가 붙은 `###` 하위 섹션입니다
|
||||||
|
- [ ] "얻는 결과"가 산출물을 설명합니다
|
||||||
|
|
||||||
|
## 개념 설명 구조
|
||||||
|
|
||||||
|
### 유형
|
||||||
|
|
||||||
|
| 유형 | 예시 |
|
||||||
|
| --- | --- |
|
||||||
|
| **인덱스/랜딩** | `core-concepts/index.md` |
|
||||||
|
| **개념** | `what-are-agents.md` |
|
||||||
|
| **기능** | `quick-dev.md` |
|
||||||
|
| **철학** | `why-solutioning-matters.md` |
|
||||||
|
| **FAQ** | `established-projects-faq.md` |
|
||||||
|
|
||||||
|
### 일반 템플릿
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장(1-2문장)
|
||||||
|
2. 개요/정의(무엇이며 왜 중요한지)
|
||||||
|
3. 핵심 개념(### 하위 섹션)
|
||||||
|
4. 비교 표(선택)
|
||||||
|
5. 사용할 때 / 사용하지 않을 때(선택)
|
||||||
|
6. 다이어그램(선택 - mermaid, 문서당 최대 1개)
|
||||||
|
7. 다음 단계(선택)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 인덱스/랜딩 페이지
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장(한 문장)
|
||||||
|
2. 콘텐츠 표(설명이 있는 링크)
|
||||||
|
3. 시작하기(번호 목록)
|
||||||
|
4. 경로 선택(선택 - 의사결정 트리)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 개념 설명 문서
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장(무엇인지)
|
||||||
|
2. 유형/범주(### 하위 섹션, 선택)
|
||||||
|
3. 주요 차이 표
|
||||||
|
4. 구성 요소/부분
|
||||||
|
5. 무엇을 사용해야 하나요?
|
||||||
|
6. 생성/커스터마이징(사용 가이드 링크)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 기능 설명 문서
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장(무엇을 하는지)
|
||||||
|
2. 빠른 정보(선택 - "적합한 경우:", "소요 시간:")
|
||||||
|
3. 사용할 때 / 사용하지 않을 때
|
||||||
|
4. 작동 방식(mermaid 다이어그램 선택)
|
||||||
|
5. 핵심 이점
|
||||||
|
6. 비교 표(선택)
|
||||||
|
7. 졸업/업그레이드 시점(선택)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 철학/근거 문서
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장(원칙)
|
||||||
|
2. 문제
|
||||||
|
3. 해결책
|
||||||
|
4. 핵심 원칙(### 하위 섹션)
|
||||||
|
5. 이점
|
||||||
|
6. 적용 시점
|
||||||
|
```
|
||||||
|
|
||||||
|
### 개념 설명 체크리스트
|
||||||
|
|
||||||
|
- [ ] 후킹 문장이 문서가 설명하는 내용을 말합니다
|
||||||
|
- [ ] 스캔하기 쉬운 `##` 섹션으로 구성합니다
|
||||||
|
- [ ] 3개 이상의 선택지가 있으면 비교 표를 사용합니다
|
||||||
|
- [ ] 다이어그램에는 명확한 라벨이 있습니다
|
||||||
|
- [ ] 절차적 질문에는 사용 가이드 링크를 제공합니다
|
||||||
|
- [ ] 문서당 알림 상자는 최대 2-3개입니다
|
||||||
|
|
||||||
|
## 참조 문서 구조
|
||||||
|
|
||||||
|
### 유형
|
||||||
|
|
||||||
|
| 유형 | 예시 |
|
||||||
|
| --- | --- |
|
||||||
|
| **인덱스/랜딩** | `workflows/index.md` |
|
||||||
|
| **카탈로그** | `agents/index.md` |
|
||||||
|
| **심층 설명** | `document-project.md` |
|
||||||
|
| **설정** | `core-tasks.md` |
|
||||||
|
| **용어집** | `glossary/index.md` |
|
||||||
|
| **종합 가이드** | `bmgd-workflows.md` |
|
||||||
|
|
||||||
|
### 참조 인덱스 페이지
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장(한 문장)
|
||||||
|
2. 콘텐츠 섹션(각 범주에 ## 사용)
|
||||||
|
- 링크와 설명이 있는 글머리표 목록
|
||||||
|
```
|
||||||
|
|
||||||
|
### 카탈로그 참조
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장
|
||||||
|
2. 항목(각 항목에 ## 사용)
|
||||||
|
- 짧은 설명(한 문장)
|
||||||
|
- **스킬:** 또는 **핵심 정보:** 형태의 평평한 목록
|
||||||
|
3. 공통/공유 섹션(## 섹션, 선택)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 항목 심층 참조
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장(한 문장 목적)
|
||||||
|
2. 빠른 정보(note 알림 상자, 선택)
|
||||||
|
- 모듈, 스킬, 입력, 출력 목록
|
||||||
|
3. 목적/개요(## 섹션)
|
||||||
|
4. 호출 방법(코드 블록)
|
||||||
|
5. 핵심 섹션(각 측면에 ## 사용)
|
||||||
|
- 하위 선택지에는 ### 사용
|
||||||
|
6. 참고/주의 사항(tip 또는 caution 알림 상자)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 설정 참조
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장
|
||||||
|
2. 목차(항목이 4개 이상이면 점프 링크)
|
||||||
|
3. 항목(각 설정/작업에 ## 사용)
|
||||||
|
- **굵은 요약** — 한 문장
|
||||||
|
- **사용 시점:** 글머리표 목록
|
||||||
|
- **작동 방식:** 번호 목록(최대 3-5개)
|
||||||
|
- **출력:** 예상 결과(선택)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 종합 참조 가이드
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 제목 + 후킹 문장
|
||||||
|
2. 개요(## 섹션)
|
||||||
|
- 구성을 보여주는 다이어그램 또는 표
|
||||||
|
3. 주요 섹션(각 단계/범주에 ## 사용)
|
||||||
|
- 항목(각 항목에 ### 사용)
|
||||||
|
- 표준 필드: 스킬, 에이전트, 입력, 출력, 설명
|
||||||
|
4. 다음 단계(선택)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 참조 체크리스트
|
||||||
|
|
||||||
|
- [ ] 후킹 문장이 문서가 참조하는 내용을 말합니다
|
||||||
|
- [ ] 구조가 참조 유형에 맞습니다
|
||||||
|
- [ ] 항목은 전체적으로 일관된 구조를 사용합니다
|
||||||
|
- [ ] 구조화/비교 데이터에는 표를 사용합니다
|
||||||
|
- [ ] 개념적 깊이가 필요한 곳에는 개념 설명 문서 링크를 둡니다
|
||||||
|
- [ ] 알림 상자는 최대 1-2개입니다
|
||||||
|
|
||||||
|
## 용어집 구조
|
||||||
|
|
||||||
|
Starlight는 헤더에서 오른쪽 "이 페이지에서" 탐색을 생성합니다.
|
||||||
|
|
||||||
|
- 범주는 `##` 헤더로 작성합니다. 오른쪽 탐색에 표시됩니다
|
||||||
|
- 용어는 개별 헤더가 아니라 표 안의 간결한 행으로 작성합니다
|
||||||
|
- 인라인 TOC는 사용하지 않습니다. 오른쪽 사이드바가 탐색을 담당합니다
|
||||||
|
|
||||||
|
### 표 형식
|
||||||
|
|
||||||
|
```md
|
||||||
|
## 범주 이름
|
||||||
|
|
||||||
|
| 용어 | 정의 |
|
||||||
|
| --- | --- |
|
||||||
|
| **에이전트** | 특정 전문성을 갖고 워크플로 전반에서 사용자를 안내하는 특화 AI 페르소나입니다. |
|
||||||
|
| **워크플로** | 산출물을 만들기 위해 AI 에이전트 활동을 조율하는 여러 단계의 안내형 프로세스입니다. |
|
||||||
|
```
|
||||||
|
|
||||||
|
### 정의 규칙
|
||||||
|
|
||||||
|
| 해야 할 것 | 하지 말 것 |
|
||||||
|
| --- | --- |
|
||||||
|
| 무엇인지 또는 무엇을 하는지로 시작합니다 | "이것은..." 또는 "이 용어는..."으로 시작합니다 |
|
||||||
|
| 1-2문장으로 유지합니다 | 여러 문단으로 설명합니다 |
|
||||||
|
| 셀 안의 용어명을 굵게 표시합니다 | 용어를 일반 텍스트로 둡니다 |
|
||||||
|
|
||||||
|
### 컨텍스트 표시
|
||||||
|
|
||||||
|
범위가 제한된 용어는 정의 시작에 이탤릭 컨텍스트를 추가합니다.
|
||||||
|
|
||||||
|
- `*빠른 흐름 전용.*`
|
||||||
|
- `*BMad Method/엔터프라이즈.*`
|
||||||
|
- `*N단계.*`
|
||||||
|
- `*BMGD.*`
|
||||||
|
- `*기존 프로젝트.*`
|
||||||
|
|
||||||
|
### 용어집 체크리스트
|
||||||
|
|
||||||
|
- [ ] 용어는 개별 헤더가 아니라 표에 있습니다
|
||||||
|
- [ ] 범주 안에서 용어를 사전순으로 정렬합니다
|
||||||
|
- [ ] 정의는 1-2문장입니다
|
||||||
|
- [ ] 컨텍스트 표시는 이탤릭입니다
|
||||||
|
- [ ] 셀 안의 용어명은 굵게 표시합니다
|
||||||
|
- [ ] "이것은..." 또는 "이 용어는..." 형태의 정의를 사용하지 않습니다
|
||||||
|
|
||||||
|
## FAQ 섹션
|
||||||
|
|
||||||
|
```md
|
||||||
|
## 질문
|
||||||
|
|
||||||
|
- [항상 아키텍처가 필요한가요?](#항상-아키텍처가-필요한가요)
|
||||||
|
- [나중에 계획을 바꿀 수 있나요?](#나중에-계획을-바꿀-수-있나요)
|
||||||
|
|
||||||
|
### 항상 아키텍처가 필요한가요?
|
||||||
|
|
||||||
|
BMad Method와 엔터프라이즈 트랙에서만 필요합니다. 빠른 흐름은 구현으로 바로 넘어갑니다.
|
||||||
|
|
||||||
|
### 나중에 계획을 바꿀 수 있나요?
|
||||||
|
|
||||||
|
예. `bmad-correct-course` 워크플로가 구현 중 범위 변경을 처리합니다.
|
||||||
|
|
||||||
|
**여기에 답이 없는 질문이 있나요?** [이슈를 열거나](...) [Discord](...)에서 물어보세요.
|
||||||
|
```
|
||||||
|
|
||||||
|
## 검증 명령
|
||||||
|
|
||||||
|
문서 변경을 제출하기 전에 다음을 실행하세요.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run docs:fix-links # 링크 형식 수정 미리보기
|
||||||
|
npm run docs:fix-links -- --write # 수정 적용
|
||||||
|
npm run docs:validate-links # 링크 존재 여부 확인
|
||||||
|
npm run docs:build # 빌드 오류 없음 확인
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
---
|
||||||
|
title: "고급 도출"
|
||||||
|
description: 구조화된 추론 방법으로 LLM이 자신의 작업을 다시 생각하게 합니다
|
||||||
|
sidebar:
|
||||||
|
order: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
LLM이 방금 생성한 결과를 다시 검토하게 만드세요. 추론 방법을 선택하면 LLM이 그 방법을 자신의 출력에 적용하고, 사용자는 개선 사항을 유지할지 결정합니다.
|
||||||
|
|
||||||
|
## 고급 도출이란?
|
||||||
|
|
||||||
|
구조화된 두 번째 검토 단계입니다. AI에게 막연히 "다시 해봐" 또는 "더 좋게 만들어"라고 말하는 대신, 특정 추론 방법을 선택하고 AI가 그 렌즈를 통해 자신의 출력을 다시 살핍니다.
|
||||||
|
|
||||||
|
이 차이는 중요합니다. 모호한 요청은 모호한 수정을 낳습니다. 이름 있는 방법은 특정한 검토 관점을 강제해 일반적인 재시도로는 놓칠 인사이트를 드러냅니다.
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
- 워크플로가 콘텐츠를 생성한 뒤 대안을 보고 싶을 때
|
||||||
|
- 출력은 괜찮아 보이지만 더 깊이가 있을 것 같을 때
|
||||||
|
- 가정을 스트레스 테스트하거나 약점을 찾고 싶을 때
|
||||||
|
- 다시 생각하는 과정이 도움이 되는 중요도가 높은 콘텐츠일 때
|
||||||
|
|
||||||
|
워크플로는 결정 지점에서 고급 도출을 제안합니다. LLM이 무언가를 생성한 뒤 실행할지 묻습니다.
|
||||||
|
|
||||||
|
## 작동 방식
|
||||||
|
|
||||||
|
1. LLM이 콘텐츠에 관련 있는 방법 5개를 제안합니다
|
||||||
|
2. 하나를 고릅니다(또는 다른 선택지를 보려고 다시 섞습니다)
|
||||||
|
3. 방법이 적용되고 개선 사항이 표시됩니다
|
||||||
|
4. 수락하거나 버리고, 반복하거나 계속합니다
|
||||||
|
|
||||||
|
## 내장 방법
|
||||||
|
|
||||||
|
수십 가지 추론 방법을 사용할 수 있습니다. 예시는 다음과 같습니다.
|
||||||
|
|
||||||
|
- **사전 실패 분석** - 프로젝트가 이미 실패했다고 가정하고 이유를 역추적합니다
|
||||||
|
- **제1원칙 사고** - 가정을 걷어내고 근거 사실에서 다시 세웁니다
|
||||||
|
- **역전 사고** - 실패를 보장하는 방법을 묻고, 그 일을 피합니다
|
||||||
|
- **레드 팀 vs 블루 팀** - 자신의 작업을 공격한 뒤 방어합니다
|
||||||
|
- **소크라테스식 질문** - 모든 주장에 "왜?"와 "어떻게 알아?"를 던집니다
|
||||||
|
- **제약 제거** - 모든 제약을 제거해 무엇이 바뀌는지 보고, 선택적으로 다시 추가합니다
|
||||||
|
- **이해관계자 매핑** - 각 이해관계자 관점에서 다시 평가합니다
|
||||||
|
- **유추 추론** - 다른 도메인의 유사점을 찾아 그 교훈을 적용합니다
|
||||||
|
|
||||||
|
그 밖에도 훨씬 많습니다. AI는 콘텐츠에 가장 관련 있는 선택지를 고르고, 사용자는 실행할 방법을 선택합니다.
|
||||||
|
|
||||||
|
:::tip[시작점]
|
||||||
|
사전 실패 분석은 어떤 사양이나 계획에도 좋은 첫 선택입니다. 표준 리뷰가 놓치는 공백을 꾸준히 찾아냅니다.
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
title: "적대적 리뷰"
|
||||||
|
description: “괜찮아 보이네”라는 식의 대충 넘어가는 검토를 방지하는 논리적 추론 기법
|
||||||
|
sidebar:
|
||||||
|
order: 9
|
||||||
|
---
|
||||||
|
|
||||||
|
문제를 반드시 찾게 만들어 더 깊은 분석을 강제합니다.
|
||||||
|
|
||||||
|
## 적대적 리뷰란?
|
||||||
|
|
||||||
|
리뷰어가 *반드시* 이슈를 찾아야 하는 리뷰 기법입니다. "좋아 보입니다"는 허용되지 않습니다. 리뷰어는 문제가 존재한다고 가정하고, 냉정한 태도로 그것을 찾아냅니다.
|
||||||
|
|
||||||
|
부정적이 되자는 뜻이 아닙니다. 제출물을 도장 찍듯 승인하는 대충 훑기가 아니라 실제 분석을 강제하기 위한 것입니다.
|
||||||
|
|
||||||
|
**핵심 규칙:** 이슈를 찾아야 합니다. 발견 항목이 0개면 중단하고 다시 분석하거나 이유를 설명합니다.
|
||||||
|
|
||||||
|
## 왜 효과적인가
|
||||||
|
|
||||||
|
일반 리뷰는 확증 편향에 취약합니다. 작업을 훑고, 눈에 띄는 것이 없으면 승인합니다. "문제를 찾아라"라는 요구는 이 패턴을 끊습니다.
|
||||||
|
|
||||||
|
- **철저함을 강제** - 충분히 열심히 살펴 이슈를 찾기 전까지 승인할 수 없습니다
|
||||||
|
- **빠진 것을 잡아냄** - "여기에 없는 것은 무엇인가?"가 자연스러운 질문이 됩니다
|
||||||
|
- **신호 품질 향상** - 발견 사항이 막연한 우려가 아니라 구체적이고 실행 가능해집니다
|
||||||
|
- **정보 비대칭** - 원래 의사결정 과정을 보지 않은 새 컨텍스트에서 검토해 의도가 아니라 산출물을 평가합니다
|
||||||
|
|
||||||
|
## 사용 위치
|
||||||
|
|
||||||
|
적대적 리뷰는 코드 리뷰, 구현 준비 상태 점검, 사양 검증 등 BMad 워크플로 전반에 나타납니다. 어떤 때는 필수 단계이고, 어떤 때는 고급 도출이나 파티 모드처럼 선택 사항입니다. 검토가 필요한 산출물에 맞춰 패턴이 적응합니다.
|
||||||
|
|
||||||
|
## 사람의 필터링 필요
|
||||||
|
|
||||||
|
AI는 문제를 찾도록 *지시*받았으므로 문제를 찾습니다. 실제로는 존재하지 않을 때도 그렇습니다. 사소한 지적을 이슈처럼 포장하거나, 의도를 오해하거나, 아예 환각성 발견 사항을 낼 수 있습니다.
|
||||||
|
|
||||||
|
**무엇이 실제인지 사용자가 결정합니다.** 각 발견 사항을 검토하고 노이즈를 버리고 중요한 것을 고치세요.
|
||||||
|
|
||||||
|
## 예시
|
||||||
|
|
||||||
|
다음 대신:
|
||||||
|
|
||||||
|
> "인증 구현은 괜찮아 보입니다. 승인합니다."
|
||||||
|
|
||||||
|
적대적 리뷰는 다음처럼 나옵니다.
|
||||||
|
|
||||||
|
> 1. **HIGH** - `login.ts:47` - 실패한 로그인 시도에 속도 제한 없음
|
||||||
|
> 2. **HIGH** - 세션 토큰이 localStorage에 저장됨(XSS 취약)
|
||||||
|
> 3. **MEDIUM** - 비밀번호 검증이 클라이언트 측에서만 수행됨
|
||||||
|
> 4. **MEDIUM** - 실패한 로그인 시도에 대한 감사 로깅 없음
|
||||||
|
> 5. **LOW** - 매직 넘버 `3600`은 `SESSION_TIMEOUT_SECONDS`가 되어야 함
|
||||||
|
|
||||||
|
첫 번째 리뷰는 보안 취약점을 놓칠 수 있습니다. 두 번째는 네 가지를 잡았습니다.
|
||||||
|
|
||||||
|
## 반복과 수확 체감
|
||||||
|
|
||||||
|
발견 사항을 처리한 뒤 다시 실행하는 것도 고려하세요. 두 번째 실행은 대개 더 많은 것을 잡아냅니다. 세 번째도 항상 쓸모없지는 않습니다. 하지만 각 실행에는 시간이 들고, 언젠가는 사소한 지적과 거짓 발견 사항만 남는 수확 체감 구간에 들어갑니다.
|
||||||
|
|
||||||
|
:::tip[더 나은 리뷰]
|
||||||
|
문제가 존재한다고 가정하세요. 잘못된 것뿐 아니라 빠진 것을 찾으세요.
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
---
|
||||||
|
title: "분석 단계: 아이디어에서 기반까지"
|
||||||
|
description: 브레인스토밍, 리서치, 제품 개요, PRFAQ가 무엇이며 언제 쓰는지 설명합니다
|
||||||
|
sidebar:
|
||||||
|
order: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
분석 단계(단계 1)는 제품을 만들기로 확정하기 전에 명확하게 생각하도록 돕습니다. 이 단계의 모든 도구는 선택 사항이지만, 분석을 완전히 건너뛰면 PRD가 인사이트가 아니라 가정 위에 세워집니다.
|
||||||
|
|
||||||
|
## 왜 계획 전에 분석이 필요한가?
|
||||||
|
|
||||||
|
PRD는 "무엇을 만들고 왜 만드는가?"에 답합니다. 모호한 생각을 넣으면 모호한 PRD가 나오고, 이후 모든 문서가 그 모호함을 상속합니다. 약한 PRD 위에 세운 아키텍처는 잘못된 기술적 베팅을 합니다. 약한 아키텍처에서 나온 스토리는 엣지 케이스를 놓칩니다. 비용은 누적됩니다.
|
||||||
|
|
||||||
|
분석 도구는 PRD를 날카롭게 만들기 위해 존재합니다. 창의적 탐색, 시장 현실, 고객 명확성, 실행 가능성 등 서로 다른 각도에서 문제를 검토해 PM 에이전트와 마주 앉을 때 무엇을 누구를 위해 만드는지 알게 합니다.
|
||||||
|
|
||||||
|
## 도구들
|
||||||
|
|
||||||
|
### 브레인스토밍
|
||||||
|
|
||||||
|
**무엇인가요.** 검증된 아이디어 발상 기법을 사용하는 안내형 창의 세션입니다. AI는 아이디어를 대신 생성하지 않고, 구조화된 연습으로 사용자 안의 아이디어를 끌어내는 코치 역할을 합니다.
|
||||||
|
|
||||||
|
**왜 있나요.** 원석 같은 아이디어는 요구사항에 고정되기 전에 발전할 공간이 필요합니다. 브레인스토밍은 그 공간을 만듭니다. 문제 도메인은 있지만 명확한 해결책이 없거나, 확정하기 전에 여러 방향을 탐색하고 싶을 때 특히 유용합니다.
|
||||||
|
|
||||||
|
**언제 쓰나요.** 만들고 싶은 것에 대한 막연한 감은 있지만 개념이 아직 굳지 않았을 때 사용합니다. 또는 개념은 있지만 대안과 비교해 압박 테스트하고 싶을 때 사용합니다.
|
||||||
|
|
||||||
|
세션 작동 방식은 [브레인스토밍](./brainstorming.md)을 참고하세요.
|
||||||
|
|
||||||
|
### 리서치(시장, 도메인, 기술)
|
||||||
|
|
||||||
|
**무엇인가요.** 아이디어의 서로 다른 차원을 조사하는 세 가지 집중 연구 워크플로입니다. 시장 조사는 경쟁자, 트렌드, 사용자 반응을 봅니다. 도메인 조사는 주제 전문성과 용어를 쌓습니다. 기술 조사는 실현 가능성, 아키텍처 선택지, 구현 접근을 평가합니다.
|
||||||
|
|
||||||
|
**왜 있나요.** 가정 위에 만드는 것은 아무도 필요로 하지 않는 것을 만드는 가장 빠른 길입니다. 리서치는 개념을 현실에 연결합니다. 이미 어떤 경쟁자가 있는지, 사용자가 실제로 무엇에 어려움을 겪는지, 기술적으로 가능한지, 산업별 제약이 무엇인지 확인합니다.
|
||||||
|
|
||||||
|
**언제 쓰나요.** 낯선 도메인에 들어가거나, 경쟁자가 있을 것 같지만 아직 파악하지 않았거나, 검증하지 않은 기술 능력에 개념이 의존할 때 사용합니다. 하나만 실행해도, 둘을 조합해도, 세 가지를 모두 실행해도 됩니다. 각각 독립적으로 의미가 있습니다.
|
||||||
|
|
||||||
|
### 제품 개요
|
||||||
|
|
||||||
|
**무엇인가요.** 제품 개념의 1-2페이지 요약을 만드는 안내형 발견 세션입니다. AI는 협업형 비즈니스 분석가로서 비전, 대상 독자, 가치 제안, 범위를 표현하도록 돕습니다.
|
||||||
|
|
||||||
|
**왜 있나요.** 제품 개요는 계획으로 들어가는 가벼운 경로입니다. 전략적 비전을 구조화된 형식으로 포착해 PRD 작성에 직접 공급합니다. 이미 개념에 확신이 있을 때 가장 잘 맞습니다. 고객, 문제, 대략 만들고 싶은 것을 알고 있을 때 제품 개요가 그 생각을 정리하고 날카롭게 합니다.
|
||||||
|
|
||||||
|
**언제 쓰나요.** 개념이 비교적 명확하고 PRD를 만들기 전에 효율적으로 문서화하고 싶을 때 사용합니다. 방향에 확신이 있고 가정을 강하게 도전받을 필요가 없을 때 적합합니다.
|
||||||
|
|
||||||
|
### PRFAQ Working Backwards(워킹 백워드)
|
||||||
|
|
||||||
|
**무엇인가요.** Amazon의 워킹 백워드 방법론을 대화형 챌린지로 적용한 것입니다. 코드 한 줄이 존재하기 전에 완성된 제품을 발표하는 보도자료를 쓰고, 고객과 이해관계자가 물을 가장 어려운 질문에 답합니다. AI는 집요하지만 건설적인 제품 코치로 행동합니다.
|
||||||
|
|
||||||
|
**왜 있나요.** PRFAQ는 계획으로 들어가는 엄격한 경로입니다. 모든 주장을 방어하게 만들어 고객 우선의 명확성을 강제합니다. 설득력 있는 보도자료를 쓸 수 없다면 제품은 준비되지 않은 것입니다. 고객 FAQ 답변이 공백을 드러내면, 그 공백은 구현 중 훨씬 늦고 비싸게 발견했을 것입니다. 이 관문은 약한 생각을 가장 싸게 고칠 수 있는 초기에 드러냅니다.
|
||||||
|
|
||||||
|
**언제 쓰나요.** 리소스를 투입하기 전에 개념을 스트레스 테스트하고 싶을 때 사용합니다. 사용자가 실제로 관심을 가질지 확신이 없거나, 명확하고 방어 가능한 가치 제안을 말할 수 있는지 검증하고 싶을 때, 또는 워킹 백워드의 규율로 생각을 날카롭게 하고 싶을 때 적합합니다.
|
||||||
|
|
||||||
|
## 무엇을 사용해야 하나요?
|
||||||
|
|
||||||
|
| 상황 | 권장 도구 |
|
||||||
|
| --- | --- |
|
||||||
|
| "막연한 아이디어가 있는데 어디서 시작할지 모르겠어요" | 브레인스토밍 |
|
||||||
|
| "결정하기 전에 시장을 이해해야 해요" | 리서치 |
|
||||||
|
| "만들고 싶은 건 알아요. 문서화만 필요해요" | 제품 개요 |
|
||||||
|
| "이 아이디어가 정말 만들 가치가 있는지 확인하고 싶어요" | PRFAQ |
|
||||||
|
| "탐색하고, 검증하고, 문서화하고 싶어요" | 브레인스토밍 → 리서치 → PRFAQ 또는 제품 개요 |
|
||||||
|
|
||||||
|
제품 개요와 PRFAQ는 둘 다 PRD 입력을 만듭니다. 얼마나 강한 챌린지를 원하는지에 따라 고르세요. 제품 개요는 협업형 발견 과정이고, PRFAQ는 더 엄격한 검증 관문입니다. 둘 다 같은 목적지로 가지만 PRFAQ는 그 개념이 그 단계로 갈 준비가 되었는지 시험합니다.
|
||||||
|
|
||||||
|
:::tip[확실하지 않나요?]
|
||||||
|
`bmad-help`를 실행하고 상황을 설명하세요. 이미 한 일과 달성하려는 것에 따라 적절한 시작점을 추천합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 분석 후에는 무엇이 일어나나요?
|
||||||
|
|
||||||
|
분석 출력은 단계 2(계획)로 직접 이어집니다. PRD 워크플로는 제품 개요, PRFAQ 문서, 리서치 발견 사항, 브레인스토밍 보고서를 입력으로 받아 사용자가 만든 모든 것을 구조화된 요구사항으로 종합합니다. 분석을 더 많이 할수록 PRD는 더 날카로워집니다.
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
title: "브레인스토밍"
|
||||||
|
description: 60가지 이상의 검증된 아이디어 도출 기법을 활용한 참여형 창의 세션
|
||||||
|
sidebar:
|
||||||
|
order: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
안내에 따라 직접 탐색하며 창의력을 마음껏 펼쳐보세요.
|
||||||
|
|
||||||
|
## 브레인스토밍이란?
|
||||||
|
|
||||||
|
`bmad-brainstorming`을 실행하면 아이디어를 대신 만들어 주는 AI가 아니라, 당신 안의 아이디어를 끌어내는 창의 촉진자를 얻게 됩니다. AI는 코치와 가이드로 행동하며 검증된 기법을 사용해 최고의 생각이 떠오를 조건을 만듭니다.
|
||||||
|
|
||||||
|
**잘 맞는 경우:**
|
||||||
|
|
||||||
|
- 창의적 막힘 돌파
|
||||||
|
- 제품 또는 기능 아이디어 생성
|
||||||
|
- 새로운 각도에서 문제 탐색
|
||||||
|
- 날것의 개념을 실행 계획으로 발전
|
||||||
|
|
||||||
|
## 작동 방식
|
||||||
|
|
||||||
|
1. **준비** - 주제, 목표, 제약 정의
|
||||||
|
2. **접근 방식 선택** - 직접 기법을 고르거나, AI 추천을 받거나, 무작위로 진행하거나, 점진적 흐름을 따릅니다
|
||||||
|
3. **진행** - 탐색 질문과 협업형 코칭으로 기법을 진행합니다
|
||||||
|
4. **정리** - 아이디어를 주제로 묶고 우선순위를 정합니다
|
||||||
|
5. **실행** - 핵심 아이디어에 다음 단계와 성공 지표를 연결합니다
|
||||||
|
|
||||||
|
모든 내용은 나중에 참고하거나 이해관계자와 공유할 수 있는 세션 문서에 기록됩니다.
|
||||||
|
|
||||||
|
:::note[당신의 아이디어]
|
||||||
|
모든 아이디어는 당신에게서 나옵니다. 워크플로는 통찰이 생기는 조건을 만들 뿐입니다. 출처는 당신입니다.
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
---
|
||||||
|
title: "체크포인트 미리보기"
|
||||||
|
description: 목적에서 세부 사항에 이르기까지의 변경 과정을 단계별로 안내하는, LLM을 활용한 인간 중심 검토
|
||||||
|
sidebar:
|
||||||
|
order: 8
|
||||||
|
---
|
||||||
|
|
||||||
|
`bmad-checkpoint-preview`는 LLM이 보조하는 대화형 human-in-the-loop 리뷰 워크플로입니다. 코드 변경을 목적과 컨텍스트에서 세부 사항까지 안내해, 출시할지, 다시 작업할지, 더 파고들지에 대해 충분한 정보를 바탕으로 판단할 수 있게 합니다.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 일반적인 흐름
|
||||||
|
|
||||||
|
`bmad-quick-dev`를 실행합니다. 의도를 명확히 하고, 사양을 만들고, 변경을 구현합니다. 완료되면 사양 파일에 리뷰 경로를 붙이고 에디터에서 엽니다. 사양을 보니 여러 모듈에 걸쳐 20개 파일이 변경되었습니다.
|
||||||
|
|
||||||
|
diff를 눈으로 훑을 수도 있습니다. 하지만 20개 파일쯤 되면 눈대중 리뷰가 흔들리기 시작합니다. 흐름을 놓치고, 떨어진 두 변경 사이의 연결을 놓치거나, 충분히 이해하지 못한 것을 승인할 수 있습니다. 그래서 "checkpoint"라고 말하면 LLM이 변경을 따라가게 해 줍니다.
|
||||||
|
|
||||||
|
자율 구현에서 인간 판단으로 돌아오는 이 전환이 주된 사용 사례입니다. 빠른 개발은 최소 감독으로 오래 실행됩니다. 체크포인트 미리보기는 사용자가 다시 운전대를 잡는 지점입니다.
|
||||||
|
|
||||||
|
## 왜 존재하나요?
|
||||||
|
|
||||||
|
코드 리뷰에는 두 실패 모드가 있습니다. 하나는 리뷰어가 diff를 훑고 눈에 띄는 것이 없어 승인하는 경우입니다. 다른 하나는 모든 파일을 꼼꼼히 읽지만 흐름을 잃는 경우입니다. 나무는 보지만 숲을 놓칩니다. 둘 다 같은 결과를 낳습니다. 중요한 것을 잡지 못한 리뷰입니다.
|
||||||
|
|
||||||
|
근본 문제는 순서입니다. 원시 diff는 파일 순서로 변경을 보여주지만, 이 순서는 이해가 쌓이는 순서와 거의 일치하지 않습니다. 왜 필요한지 알기 전에 도우미 함수를 보고, 어떤 기능을 지원하는지 알기 전에 스키마 변경을 봅니다. 리뷰어는 흩어진 단서에서 작성자의 의도를 재구성해야 하고, 그 재구성 과정에서 집중력이 무너집니다.
|
||||||
|
|
||||||
|
체크포인트 미리보기는 재구성 작업을 LLM에게 맡겨 이 문제를 해결합니다. diff, 사양(있다면), 주변 코드베이스를 읽고 `git diff`가 아니라 이해를 위해 설계된 순서로 변경을 제시합니다.
|
||||||
|
|
||||||
|
## 작동 방식
|
||||||
|
|
||||||
|
워크플로는 다섯 단계입니다. 각 단계는 이전 단계 위에 쌓이며 "이게 뭐지?"에서 "출시해도 되나?"로 점진적으로 이동합니다.
|
||||||
|
|
||||||
|
### 1. 방향 잡기
|
||||||
|
|
||||||
|
워크플로는 변경(PR, 커밋, 브랜치, 사양 파일, 현재 Git 상태)을 식별하고 한 줄 의도 요약과 영역 통계를 생성합니다. 변경 파일 수, 건드린 모듈, 논리 줄 수, 경계 넘나듦, 새 공개 인터페이스 등입니다.
|
||||||
|
|
||||||
|
이 단계는 "내가 보고 있는 게 맞나?"를 확인하는 순간입니다. 코드를 읽기 전에 리뷰어는 올바른 것을 보고 있는지 확인하고 범위 기대치를 맞춥니다.
|
||||||
|
|
||||||
|
### 2. 둘러보기
|
||||||
|
|
||||||
|
변경은 파일이 아니라 **관심사** 기준으로 구성됩니다. "입력 검증"이나 "API 계약" 같은 응집력 있는 설계 의도입니다. 각 관심사에는 왜 이 접근을 택했는지 짧은 설명과 리뷰어가 코드에서 따라갈 수 있는 클릭 가능한 `path:line` 지점이 붙습니다.
|
||||||
|
|
||||||
|
이 단계는 설계 판단입니다. 리뷰어는 코드가 정확한지가 아니라 시스템에 맞는 접근인지 평가합니다. 관심사는 하향식으로 배치됩니다. 가장 높은 수준의 의도가 먼저 나오고 보조 구현이 뒤따릅니다. 리뷰어는 아직 보지 않은 것에 대한 참조를 만나지 않습니다.
|
||||||
|
|
||||||
|
### 3. 상세 검토
|
||||||
|
|
||||||
|
리뷰어가 설계를 이해한 뒤 워크플로는 실수했을 때 영향 범위가 가장 큰 2-5개 지점을 드러냅니다. 이들은 `[auth]`, `[schema]`, `[billing]`, `[public API]`, `[security]` 같은 위험 범주로 태그되고, 틀렸을 때 얼마나 많이 깨지는지 기준으로 정렬됩니다.
|
||||||
|
|
||||||
|
이것은 버그 찾기가 아닙니다. 자동화 테스트와 CI가 정확성을 다룹니다. 상세 검토는 위험 인식을 활성화합니다. "틀렸을 때 비용이 가장 큰 곳은 여기입니다." 특정 영역을 더 깊게 보고 싶다면 "이 영역을 더 파고들어 줘"라고 말해 정확성에 초점을 맞춘 재리뷰를 요청할 수 있습니다.
|
||||||
|
|
||||||
|
사양이 적대적 리뷰 루프를 거쳤다면 그 발견 사항도 여기서 드러납니다. 고쳐진 버그가 아니라, 리뷰 루프가 리뷰어가 알아야 한다고 표시한 결정입니다.
|
||||||
|
|
||||||
|
### 4. 테스트
|
||||||
|
|
||||||
|
변경이 작동하는 것을 수동으로 관찰하는 방법 2-5개를 제안합니다. 자동화 테스트 명령이 아니라 어떤 테스트 모음도 주지 못하는 확신을 만드는 수동 관찰입니다. 시도할 UI 상호작용, 실행할 CLI 명령, 보낼 API 요청과 각 예상 결과가 포함됩니다.
|
||||||
|
|
||||||
|
사용자에게 보이는 동작이 없다면 그렇다고 말합니다. 가짜 확인 작업은 만들지 않습니다.
|
||||||
|
|
||||||
|
### 5. 마무리
|
||||||
|
|
||||||
|
리뷰어가 결정을 내립니다. 승인, 재작업, 계속 논의 중 하나입니다. PR을 승인한다면 워크플로가 `gh pr review --approve`를 도울 수 있습니다. 재작업한다면 문제가 접근 방식, 사양, 구현 중 어디에서 왔는지 진단하고 특정 코드 위치와 연결된 실행 가능한 피드백 초안을 돕습니다.
|
||||||
|
|
||||||
|
## 보고서가 아니라 대화입니다
|
||||||
|
|
||||||
|
워크플로는 각 단계를 최종 답이 아니라 출발점으로 제시합니다. 단계 사이 또는 단계 도중에도 LLM과 대화하고, 질문하고, 구성 방식에 이의를 제기하고, 다른 스킬을 불러 다른 관점을 얻을 수 있습니다.
|
||||||
|
|
||||||
|
- **"오류 처리를 고급 도출로 다시 검토해 줘"** - 특정 영역 분석을 다시 생각하고 다듬게 합니다
|
||||||
|
- **"이 스키마 마이그레이션이 안전한지 파티 모드로 토론해 줘"** - 집중 토론에 여러 에이전트 관점을 불러옵니다
|
||||||
|
- **"코드 리뷰 실행"** - 적대적 리뷰와 엣지 케이스 분석을 포함한 구조화된 에이전트 기반 발견 사항을 생성합니다
|
||||||
|
|
||||||
|
체크포인트 워크플로는 선형 경로에 가두지 않습니다. 구조가 필요할 때는 구조를 주고, 탐색하고 싶을 때는 여지를 남깁니다. 다섯 단계는 전체 그림을 보게 하기 위한 것이지만, 각 단계에서 얼마나 깊게 들어갈지와 어떤 도구를 가져올지는 전적으로 사용자에게 달려 있습니다.
|
||||||
|
|
||||||
|
## 리뷰 경로
|
||||||
|
|
||||||
|
둘러보기 단계는 **권장 리뷰 순서**가 있을 때 가장 잘 작동합니다. 이는 사양 작성자가 리뷰어를 변경으로 안내하기 위해 쓴 지점 목록입니다. 사양에 이 정보가 있으면 워크플로가 그대로 사용합니다.
|
||||||
|
|
||||||
|
작성자가 만든 경로가 없으면 워크플로가 diff와 코드베이스 컨텍스트에서 생성합니다. 생성된 경로는 작성자가 만든 경로보다 품질이 낮지만, 파일 순서로 변경을 읽는 것보다는 훨씬 낫습니다.
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
주요 시나리오는 `bmad-quick-dev`에서의 인계입니다. 구현이 끝났고, 리뷰 경로가 붙은 사양 파일이 에디터에 열려 있으며, 출시 여부를 결정해야 합니다. "checkpoint"라고 말하면 됩니다.
|
||||||
|
|
||||||
|
단독으로도 동작합니다.
|
||||||
|
|
||||||
|
- **PR 리뷰** - 특히 몇 개 파일을 넘거나 여러 영역에 걸친 변경이 있을 때
|
||||||
|
- **변경 온보딩** - 직접 작성하지 않은 브랜치에서 무슨 일이 있었는지 이해해야 할 때
|
||||||
|
- **스프린트 리뷰** - 스프린트 상태 파일에서 `review`로 표시된 스토리를 집어올 수 있습니다
|
||||||
|
|
||||||
|
"checkpoint" 또는 "이 변경을 따라가며 설명해 줘"라고 호출하세요. 어떤 터미널에서도 작동하지만 IDE(VS Code, Cursor 등) 안에서 더 편하게 사용할 수 있습니다. 워크플로가 모든 단계에서 `path:line` 참조를 생성하고, IDE 내장 터미널에서는 이들이 클릭 가능하므로 리뷰 경로를 따라 파일 사이를 이동할 수 있습니다.
|
||||||
|
|
||||||
|
## 아닌 것
|
||||||
|
|
||||||
|
체크포인트 미리보기는 자동화 리뷰의 대체물이 아닙니다. 린터, 타입 검사기, 테스트 모음을 실행하지 않습니다. 심각도 점수를 붙이거나 통과/실패 결정을 만들지 않습니다. 사람이 가장 중요한 곳에 판단을 적용하도록 돕는 읽기 가이드입니다.
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
---
|
||||||
|
title: "기존 프로젝트 FAQ"
|
||||||
|
description: 기존 프로젝트에서 BMad Method를 사용할 때의 일반 질문
|
||||||
|
sidebar:
|
||||||
|
order: 13
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad Method(BMM)로 기존 프로젝트에서 작업할 때 자주 묻는 질문에 빠르게 답합니다.
|
||||||
|
|
||||||
|
## 질문
|
||||||
|
|
||||||
|
- [프로젝트 문서화를 먼저 실행해야 하나요?](#프로젝트-문서화를-먼저-실행해야-하나요)
|
||||||
|
- [프로젝트 문서화 실행을 잊었다면 어떻게 하나요?](#프로젝트-문서화-실행을-잊었다면-어떻게-하나요)
|
||||||
|
- [기존 프로젝트에 빠른 흐름을 사용할 수 있나요?](#기존-프로젝트에-빠른-흐름을-사용할-수-있나요)
|
||||||
|
- [기존 코드가 모범 사례를 따르지 않으면 어떻게 하나요?](#기존-코드가-모범-사례를-따르지-않으면-어떻게-하나요)
|
||||||
|
|
||||||
|
### 프로젝트 문서화를 먼저 실행해야 하나요?
|
||||||
|
|
||||||
|
특히 다음 상황에서는 강력히 권장합니다.
|
||||||
|
|
||||||
|
- 기존 문서가 없습니다
|
||||||
|
- 문서가 오래되었습니다
|
||||||
|
- AI 에이전트가 기존 코드에 대한 컨텍스트가 필요합니다
|
||||||
|
|
||||||
|
`docs/index.md`를 포함한 포괄적이고 최신 문서가 있거나, 에이전트가 기존 시스템을 바탕으로 작업할 만큼 다른 도구나 기법으로 충분한 발견 과정을 제공할 예정이라면 건너뛸 수 있습니다.
|
||||||
|
|
||||||
|
### 프로젝트 문서화 실행을 잊었다면 어떻게 하나요?
|
||||||
|
|
||||||
|
걱정하지 마세요. 언제든 실행할 수 있습니다. 프로젝트 도중이나 나중에 실행해 문서를 최신 상태로 유지할 수도 있습니다.
|
||||||
|
|
||||||
|
### 기존 프로젝트에 빠른 흐름을 사용할 수 있나요?
|
||||||
|
|
||||||
|
네. 빠른 흐름은 기존 프로젝트에서 잘 작동합니다. 다음을 수행합니다.
|
||||||
|
|
||||||
|
- 기존 기술 스택 자동 감지
|
||||||
|
- 기존 코드 패턴 분석
|
||||||
|
- 관례 감지 및 확인 요청
|
||||||
|
- 기존 코드를 존중하는, 맥락이 충분히 담긴 사양 생성
|
||||||
|
|
||||||
|
기존 코드베이스의 버그 수정과 작은 기능에 특히 잘 맞습니다.
|
||||||
|
|
||||||
|
### 기존 코드가 모범 사례를 따르지 않으면 어떻게 하나요?
|
||||||
|
|
||||||
|
빠른 흐름은 관례를 감지하고 묻습니다. "이 기존 관례를 따를까요?" 사용자가 결정합니다.
|
||||||
|
|
||||||
|
- **예** → 현재 코드베이스와의 일관성 유지
|
||||||
|
- **아니요** → 새 표준 수립(사양에 이유를 문서화)
|
||||||
|
|
||||||
|
BMM은 선택을 존중합니다. 현대화를 강제하지 않지만 필요한 제안은 합니다.
|
||||||
|
|
||||||
|
**여기에 답이 없는 질문이 있나요?** [GitHub Issue](https://github.com/bmad-code-org/BMAD-METHOD/issues)를 열거나 [Discord](https://discord.gg/gk8jAdXWmj)에서 물어보세요. 추가하겠습니다.
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
---
|
||||||
|
title: "포렌식 조사"
|
||||||
|
description: bmad-investigate가 모든 이슈를 현장처럼 다루고, 증거를 등급화하며, 엔지니어가 바로 행동할 수 있는 구조화된 사례 파일을 만드는 방법
|
||||||
|
sidebar:
|
||||||
|
order: 10
|
||||||
|
---
|
||||||
|
|
||||||
|
`bmad-investigate`에 충돌 로그, 스택 추적, 또는 단순히 "예전엔 됐는데 지금은 안 돼요"를 건네면, 스킬은 실행되는 동안 조사자의 규율을 적용합니다. 바로 고치기 시작하지 않습니다. 사례 파일을 엽니다.
|
||||||
|
|
||||||
|
모든 발견 사항은 등급이 매겨집니다. 모든 가설은 상태를 가집니다. 잘못된 방향도 지우지 않고 남깁니다. 산출물은 다른 엔지니어가 아무 배경 없이 집어 들어도 이해할 수 있는 문서입니다.
|
||||||
|
|
||||||
|
이 페이지는 조사가 왜 별도의 규율인지, 그리고 일반 개발 워크플로가 주지 못하는 것을 이 스킬이 어떤 방식으로 제공하는지 설명합니다.
|
||||||
|
|
||||||
|
## "그냥 디버깅해"의 문제
|
||||||
|
|
||||||
|
일반 디버깅은 세 가지를 섞습니다. 증거를 보고, 원인을 추론하고, 이론을 시험하기 위해 코드를 바꿉니다. 이것들이 섞이면 두 가지 실패 모드가 나타납니다.
|
||||||
|
|
||||||
|
첫 번째는 **서사 고착**입니다. 처음 그럴듯한 이야기가 작업 가설이 되고, 모든 관찰이 거기에 맞춰 끼워집니다. 누군가 포기하고 처음부터 다시 시작할 때까지 버그는 고쳐지지 않습니다. 몇 시간 뒤에야 말입니다.
|
||||||
|
|
||||||
|
두 번째는 **증거 망각**입니다. 무언가를 추적하고 배제했지만 왜 배제했는지 적지 않았습니다. 이틀 뒤 새로운 눈으로 같은 것을 다시 추적합니다. 더 나쁘게는 동료가 버그를 넘겨받아 이미 제거한 막다른 경로를 다시 실행합니다.
|
||||||
|
|
||||||
|
이 스킬의 설계는 이 둘에 대한 직접적인 응답입니다.
|
||||||
|
|
||||||
|
## 증거 등급화
|
||||||
|
|
||||||
|
조사의 모든 발견 사항은 세 가지 중 하나입니다.
|
||||||
|
|
||||||
|
- **Confirmed(확인됨).** 로그, 코드, 덤프에서 직접 관찰되었고 특정 참조(`path:line`, 로그 타임스탬프, 커밋 해시)로 인용됩니다. 누군가 "어떻게 알아?"라고 물으면 인용을 가리킵니다.
|
||||||
|
- **Deduced(추론됨).** 확인된 증거에서 논리적으로 따릅니다. 추론 사슬이 표시됩니다. 사슬의 한 단계가 틀리면 추론도 틀리고, 어느 단계인지 볼 수 있습니다.
|
||||||
|
- **Hypothesized(가설).** 그럴듯하지만 확인되지 않았습니다. 무엇이 확인하거나 반박할지와 무엇이 닫을지를 미리 선언합니다. 가설은 명시적으로 *사실이 아닙니다*.
|
||||||
|
|
||||||
|
등급화는 겸손해 보이기 위한 것이 아닙니다. 사례 파일을 읽을 수 있게 만들기 위한 것입니다. 독자는 `Confirmed` 섹션에서 무엇이 사실인지, `Deduced` 섹션에서 무엇이 따라오는지, `Hypothesized` 섹션에서 무엇이 아직 열려 있는지 훑어볼 수 있습니다. 이 셋의 혼동이 조사가 빙빙 도는 가장 흔한 이유입니다.
|
||||||
|
|
||||||
|
## 기준점 먼저 확보하기
|
||||||
|
|
||||||
|
조사는 이론에서 시작하지 않습니다. 하나의 확인된 증거에서 시작해 바깥으로 확장합니다. 그 기준점은 특정 오류 메시지, 스택 프레임, 타임스탬프가 있는 로그 항목일 수 있습니다.
|
||||||
|
|
||||||
|
이는 흔한 조사 방식과 반대입니다. 누군가 직감을 갖고 이론을 세운 뒤 그것을 지지하는 증거를 찾습니다. 직감이 맞을 수도 있지만, 그 *방법*은 확증 편향을 기본값으로 만들기 때문에 취약합니다.
|
||||||
|
|
||||||
|
기준점은 추론이 흐려질 때 돌아갈 수 있는 사실입니다. 추론이 이상한 곳으로 가면 기준점까지 되돌아가 다른 갈래를 시도할 수 있습니다. 기준점이 없으면 어느 단계를 되돌려야 하는지 알 수 없습니다.
|
||||||
|
|
||||||
|
증거가 부족하면 스킬은 그렇게 말하고 가설 주도 탐색으로 전환합니다. 가능한 것에서 가설을 만들고, 각각을 시험할 증거를 식별하며, 우선순위가 있는 데이터 수집 목록을 제시합니다. 빠진 증거 자체도 발견 사항입니다.
|
||||||
|
|
||||||
|
## 가설 규율
|
||||||
|
|
||||||
|
가설은 사례 파일에서 절대 삭제되지 않습니다. 증거가 확인하거나 반박하면 **Status** 필드가 `Open`에서 `Confirmed` 또는 `Refuted`로 바뀌고, 어떤 증거가 결론을 냈는지 **Resolution**이 설명합니다.
|
||||||
|
|
||||||
|
이 규칙에는 비용이 있습니다. 사례 파일이 길어집니다. 하지만 이점도 큽니다. 전체 추론 이력이 산출물의 일부가 됩니다. 여섯 달 뒤 비슷한 버그가 나타나면 다음 조사자는 원래 사례 파일을 읽고 어떤 경로가 이미 제거되었고 왜 그런지 볼 수 있습니다. 그 이력이 없으면 새 조사자마다 같은 막다른 경로를 다시 실행합니다.
|
||||||
|
|
||||||
|
현재의 조사자에게도 규율을 부여합니다. 틀린 가설을 지울 수 없다면, 인용된 증거로 반박해야 합니다. 불편해졌다고 조용히 떨어뜨리는 선택지는 사라집니다.
|
||||||
|
|
||||||
|
## 전제에 도전하기
|
||||||
|
|
||||||
|
사용자의 문제 설명은 사실이 아니라 가설입니다. "캐시가 깨졌다"는 사용자가 *믿는 것*입니다. 스킬은 그 전제를 중심으로 조사를 세우기 전에 기술적 주장을 독립적으로 검증합니다. 증거가 전제와 모순되면 보고서가 직접 그렇게 말합니다.
|
||||||
|
|
||||||
|
이것이 포렌식 감각입니다. 목격자 진술은 데이터이지 진실이 아닙니다. 때로 보고된 버그는 진짜지만 이름표가 틀립니다. 때로 설명된 증상은 다른 원인의 파생 결과입니다. 전제를 절대적 진실로 받아들이는 조사는 잘못된 결함을 진단하고, 버그는 약간 다른 형태로 돌아옵니다.
|
||||||
|
|
||||||
|
## 상황에 맞춘 조사 흐름
|
||||||
|
|
||||||
|
스킬은 두 가지 모드가 아니라 하나의 절차입니다. 입력이 요구하는 결함 추적과 영역 탐색의 비율을 계속 맞춥니다.
|
||||||
|
|
||||||
|
증상 기반 사례(티켓, 충돌, 오류 메시지, "예전엔 됐다")는 가설 추적, 타임라인 재구성, 수정 방향에 무게를 둡니다. 증상 없는 사례(만지기 전 모듈 이해, 재사용성 평가, 정신 모델 구축)는 I/O 매핑, 제어 흐름 필터링, 검증 계획에 무게를 둡니다. 실제 사례 대부분은 그 사이 어딘가에 있고, 사례 파일은 증거가 요구한 균형을 반영합니다.
|
||||||
|
|
||||||
|
사례가 어디에 있든 원칙은 같습니다. 먼저 기준점 확보, 증거 등급화, 가설 추적, 절대 지우지 않기입니다. 출력은 항상 `{implementation_artifacts}/investigations/{slug}-investigation.md`이며, 해당 사례에 적용되지 않는 섹션은 비어 있거나 생략됩니다.
|
||||||
|
|
||||||
|
깊은 버그가 더 넓은 하위 시스템 이해를 요구할 때 절차는 I/O 매핑, 제어 흐름 필터링, 출력에서 역추적하기, 구성 요소 간 경계 추적 기법을 한 흐름 안에 통합합니다. 영역 모델은 같은 사례 파일에 들어갑니다. 모드 전환은 없습니다.
|
||||||
|
|
||||||
|
## 방법론은 스킬 안에 있습니다
|
||||||
|
|
||||||
|
조사자의 원칙은 스킬 자체의 속성입니다. `bmad-investigate`를 호출한 사람은 실행되는 동안 방법론과 커뮤니케이션 스타일을 채택합니다. 냉정한 정확성, 증거 우선 언어, 회피 없는 표현, 사례 파일 중심의 구성입니다. 스킬이 끝나면 호출자는 이전 말투로 돌아갑니다. 페르소나 교체가 아니라 스킬 원칙에서 오는 말투 전환입니다.
|
||||||
|
|
||||||
|
조사와 구현은 서로 다른 감각을 보상하기 때문에 중요합니다. 조사자는 느리고 정확합니다. 구현자는 빠르고 자신감 있습니다. 같은 세션에서 둘을 모두 하려 하면 둘 다 애매해지는 경향이 있습니다. 스킬은 별도 정체성으로 컨텍스트를 전환하지 않고, 진행 흐름 안에서 조사자의 태도를 적용합니다.
|
||||||
|
|
||||||
|
## 얻는 것
|
||||||
|
|
||||||
|
완성된 조사 파일:
|
||||||
|
|
||||||
|
- `Confirmed` 발견 사항(인용 포함)을 `Deductions` 및 `Hypotheses`와 분리합니다
|
||||||
|
- 형성된 모든 가설을 최종 `Status`와 `Resolution`과 함께 보존합니다
|
||||||
|
- 여러 증거 소스에서 이벤트 타임라인을 재구성합니다
|
||||||
|
- 데이터 공백과 그것이 무엇을 해결할지 식별합니다
|
||||||
|
- 증거에 기반한 실행 가능한 결론을 제공합니다
|
||||||
|
- 근본 원인이 식별되면 재현 계획을 포함합니다
|
||||||
|
- 아직 탐색할 경로의 조사 백로그를 유지합니다
|
||||||
|
|
||||||
|
그 자리에 없던 엔지니어에게 건네도 무슨 일이 있었고, 무엇을 알고 있으며, 무엇이 아직 불확실한지 이해해야 합니다. 기준은 그것입니다.
|
||||||
|
|
||||||
|
## 더 큰 아이디어
|
||||||
|
|
||||||
|
오늘날 대부분의 "AI 디버깅"은 증거, 추론, 코드 변경을 그럴듯한 텍스트의 한 흐름으로 섞습니다. 신호는 찾기 어렵고, 막다른 경로는 반복되며, 사례 파일이 있더라도 아무도 읽고 싶지 않은 채팅 로그처럼 보이는 경우가 많습니다.
|
||||||
|
|
||||||
|
`bmad-investigate`는 조사를 고유한 산출물이 있는 규율로 다룹니다. 증거에는 등급이 있습니다. 가설에는 상태가 있습니다. 잘못된 방향은 지워지지 않고 문서화됩니다. 사례 파일은 세션보다 오래 살아남습니다.
|
||||||
|
|
||||||
|
이미 본 적 있는 것처럼 보이는 다음 버그가 나타났을 때, 빈 프롬프트가 아니라 시작할 곳이 생깁니다.
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
---
|
||||||
|
title: "이름 있는 에이전트"
|
||||||
|
description: BMad 에이전트가 이름, 페르소나, 커스터마이징 영역을 갖는 이유와 메뉴 기반 또는 프롬프트 기반 대안보다 무엇을 가능하게 하는지
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
"Mary, 브레인스토밍하자"라고 말하면 Mary가 활성화됩니다. 그녀는 설정한 언어로 당신의 이름을 부르고, 고유한 페르소나로 인사합니다. `bmad-help`가 언제나 가능하다고 알려줍니다. 그리고 의도가 명확했기 때문에 메뉴를 건너뛰고 바로 브레인스토밍으로 들어갑니다.
|
||||||
|
|
||||||
|
이 페이지는 실제로 무엇이 일어나고 있고 왜 BMad가 이렇게 설계되었는지 설명합니다.
|
||||||
|
|
||||||
|
## 세 축
|
||||||
|
|
||||||
|
BMad의 에이전트 모델은 서로 조합되는 세 가지 기본 요소 위에 놓여 있습니다.
|
||||||
|
|
||||||
|
| 기본 요소 | 제공하는 것 | 위치 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| **스킬** | 기능 - 어시스턴트가 할 수 있는 구체적인 일(브레인스토밍, PRD 초안 작성, 스토리 구현) | `.claude/skills/{skill-name}/SKILL.md` 또는 IDE별 동등 경로 |
|
||||||
|
| **이름 있는 에이전트** | 페르소나의 연속성 - 일관된 목소리, 원칙, 시각적 단서로 관련 스킬 메뉴를 묶는 알아볼 수 있는 정체성 | 디렉터리가 `bmad-agent-*`로 시작하는 스킬 |
|
||||||
|
| **커스터마이징** | 우리 방식으로 맞추기 - 에이전트 동작을 재구성하고, MCP 통합을 추가하고, 템플릿을 교체하고, 조직 관례를 겹쳐 적용하는 오버라이드 | `_bmad/custom/{skill-name}.toml`(팀 오버라이드) 및 `.user.toml`(개인, git에서 무시됨) |
|
||||||
|
|
||||||
|
세 요소 중 하나라도 빠지면 경험이 무너집니다.
|
||||||
|
|
||||||
|
- 에이전트 없는 스킬 → 사용자가 이름이나 코드로 탐색해야 하는 기능 목록
|
||||||
|
- 스킬 없는 에이전트 → 할 일이 없는 페르소나
|
||||||
|
- 커스터마이징 없음 → 모든 사용자가 같은 기본 제공 동작을 받고, 조직별 필요에는 포크를 강요받음
|
||||||
|
|
||||||
|
## 이름 있는 에이전트가 주는 것
|
||||||
|
|
||||||
|
BMad는 BMad Method의 단계에 맞춘 여섯 이름 있는 에이전트를 제공합니다.
|
||||||
|
|
||||||
|
| 에이전트 | 단계 | 모듈 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 📊 **Mary**, 비즈니스 분석가 | 분석 | 시장 조사, 브레인스토밍, 제품 개요, PRFAQ |
|
||||||
|
| 📚 **Paige**, 기술 작성자 | 분석 | 프로젝트 문서화, 다이어그램, 문서 검증 |
|
||||||
|
| 📋 **John**, 제품 관리자 | 계획 | PRD 작성, 에픽/스토리 분해, 구현 준비 상태 점검 |
|
||||||
|
| 🎨 **Sally**, UX 디자이너 | 계획 | UX 설계 사양 |
|
||||||
|
| 🏗️ **Winston**, 시스템 아키텍트 | 솔루션 설계 | 기술 아키텍처, 정렬 점검 |
|
||||||
|
| 💻 **Amelia**, 시니어 엔지니어 | 구현 | 스토리 실행, 빠른 개발, 코드 리뷰, 스프린트 계획 |
|
||||||
|
|
||||||
|
각 에이전트는 하드코딩된 정체성(이름, 역할명, 도메인)과 커스터마이즈 가능한 계층(역할, 원칙, 커뮤니케이션 스타일, 아이콘, 메뉴)을 가집니다. Mary의 원칙을 다시 쓰거나 메뉴 항목을 추가할 수는 있지만 이름을 바꿀 수는 없습니다. 이는 의도적입니다. 이름 인식은 커스터마이징 후에도 유지되므로, 팀이 Mary의 동작을 어떻게 조정했든 "Mary"는 항상 분석가를 활성화합니다.
|
||||||
|
|
||||||
|
## 활성화 흐름
|
||||||
|
|
||||||
|
이름 있는 에이전트를 호출하면 여덟 단계가 순서대로 실행됩니다.
|
||||||
|
|
||||||
|
1. **에이전트 블록 해석** - 제공된 `customize.toml`을 팀 및 개인 오버라이드와 병합합니다. Python 병합 스크립트가 표준 라이브러리 `tomllib`을 사용합니다
|
||||||
|
2. **사전 단계 실행** - 팀이 설정한 사전 동작
|
||||||
|
3. **페르소나 채택** - 하드코딩된 정체성과 커스터마이즈된 역할, 커뮤니케이션 스타일, 원칙
|
||||||
|
4. **지속 사실 로드** - 조직 규칙, 컴플라이언스 메모, `file:` 접두사로 로드되는 파일(예: `file:{project-root}/docs/project-context.md`)
|
||||||
|
5. **설정 로드** - 사용자 이름, 커뮤니케이션 언어, 출력 언어, 산출물 경로
|
||||||
|
6. **인사** - 설정 언어로 개인화된 인사를 하고, 누가 말하는지 한눈에 보이도록 에이전트 이모지 접두사를 포함합니다
|
||||||
|
7. **추가 단계 실행** - 팀이 설정한 인사 후 설정
|
||||||
|
8. **바로 실행 또는 메뉴 표시** - 첫 메시지가 메뉴 항목에 매핑되면 바로 이동하고, 아니면 메뉴를 보여주고 입력을 기다립니다
|
||||||
|
|
||||||
|
8단계는 의도와 기능이 만나는 곳입니다. "Mary, 브레인스토밍하자"는 `bmad-brainstorming`이 Mary 메뉴의 `BP`와 명확히 맞으므로 메뉴 표시를 건너뜁니다. 모호하게 말하면 확인 절차가 아니라 한 번 짧게 묻습니다. 맞는 것이 없으면 일반 대화를 계속합니다.
|
||||||
|
|
||||||
|
## 왜 그냥 메뉴가 아닌가요?
|
||||||
|
|
||||||
|
메뉴는 사용자가 도구에 반쯤 맞춰야 합니다. 브레인스토밍이 PM 에이전트가 아니라 분석가 에이전트의 `BP` 코드 아래 있다는 것을 기억하고, 어떤 페르소나가 어떤 기능을 갖는지 알아야 합니다. 도구가 사용자에게 떠넘기는 인지 부담입니다.
|
||||||
|
|
||||||
|
이름 있는 에이전트는 이를 뒤집습니다. 자연스러운 말로 원하는 것을 누구에게 할지 말합니다. 에이전트는 자신이 누구이고 무엇을 하는지 압니다. 의도가 충분히 명확하면 그냥 진행합니다.
|
||||||
|
|
||||||
|
메뉴는 여전히 대체 경로로 있습니다. 탐색할 때는 보여주고, 필요 없을 때는 건너뜁니다.
|
||||||
|
|
||||||
|
## 왜 그냥 빈 프롬프트가 아닌가요?
|
||||||
|
|
||||||
|
빈 프롬프트는 사용자가 마법 단어를 안다고 가정합니다. "브레인스토밍을 도와줘"는 될 수 있지만 "내 SaaS 아이디어를 같이 발전시켜 보자"는 안 될 수 있고, 결과는 표현 방식에 의존합니다. 사용자가 프롬프트 엔지니어링을 책임지게 됩니다.
|
||||||
|
|
||||||
|
이름 있는 에이전트는 자유를 제한하지 않으면서 구조를 제공합니다. 페르소나는 일관되고, 기능은 발견하기 쉬우며, `bmad-help`는 명령 하나로 언제든 호출할 수 있습니다. 에이전트가 무엇을 할 수 있는지 추측할 필요도, 사용 설명서가 필요하지도 않습니다.
|
||||||
|
|
||||||
|
## 커스터마이징은 일급 기능입니다
|
||||||
|
|
||||||
|
커스터마이징 모델이 있어야 이 방식이 개별 개발자를 넘어 확장됩니다.
|
||||||
|
|
||||||
|
모든 에이전트는 합리적인 기본값이 담긴 `customize.toml`을 제공합니다. 팀은 `_bmad/custom/bmad-agent-{role}.toml`에 오버라이드를 커밋합니다. 개인은 `.user.toml`(git에서 무시됨)에 개인 선호를 겹쳐 적용할 수 있습니다. 병합 스크립트는 활성화 시점에 세 파일을 예측 가능한 구조 규칙으로 병합합니다.
|
||||||
|
|
||||||
|
대부분의 사용자는 이 파일을 직접 작성하지 않습니다. `bmad-customize` 스킬은 대상을 고르고, 에이전트와 워크플로 중 범위를 선택하고, 오버라이드를 작성하고, 병합을 검증하는 과정을 안내합니다. 그래서 TOML에 익숙한 사람만이 아니라 자신의 의도를 이해하는 누구나 커스터마이징 영역에 접근할 수 있습니다.
|
||||||
|
|
||||||
|
구체적 예: 팀이 Amelia에게 라이브러리 문서는 항상 Context7 MCP 도구를 사용하고 로컬 에픽 목록에 스토리가 없으면 Linear를 대체 경로로 사용하라고 하는 단일 파일을 커밋합니다. Amelia가 실행하는 모든 개발 워크플로(dev-story, quick-dev, create-story, code-review)가 소스 편집이나 워크플로별 중복 없이 이 동작을 상속합니다.
|
||||||
|
|
||||||
|
교차 관심사를 위한 두 번째 커스터마이징 영역도 있습니다. 중앙 `_bmad/config.toml`과 `_bmad/config.user.toml`(둘 다 설치 프로그램 소유, 각 모듈의 `module.yaml`에서 재구성됨), 그리고 오버라이드용 `_bmad/custom/config.toml`(팀, 커밋됨)과 `_bmad/custom/config.user.toml`(개인, git에서 무시됨)입니다. 여기에 **에이전트 명단**이 있습니다. `bmad-party-mode`, `bmad-retrospective`, `bmad-advanced-elicitation`처럼 명단을 사용하는 스킬이 누가 가능하고 어떻게 표현될지 알기 위해 읽는 가벼운 설명자입니다. 팀 오버라이드로 에이전트를 조직 전체에서 다시 표현하고, `.user.toml` 오버라이드로 가상 목소리(Kirk, Spock, 도메인 전문가 페르소나)를 개인 실험으로 추가할 수 있습니다. 스킬 폴더를 건드리지 않습니다. 스킬별 파일은 Mary가 활성화될 때 *어떻게 행동하는지*를 조정하고, 중앙 설정은 다른 스킬이 명단에서 Mary를 *어떻게 보는지*를 조정합니다.
|
||||||
|
|
||||||
|
전체 커스터마이징 영역과 작동 예시는 다음을 참고하세요.
|
||||||
|
|
||||||
|
- [BMad 커스터마이징 방법](../how-to/customize-bmad.md) - 무엇을 커스터마이즈할 수 있고 병합이 어떻게 동작하는지의 참조
|
||||||
|
- [조직을 위해 BMad 확장하기](../how-to/expand-bmad-for-your-org.md) - 에이전트 전반 규칙, 워크플로 관례, 외부 게시, 템플릿 교체, 에이전트 명단 커스터마이징을 다루는 여섯 가지 실전 레시피
|
||||||
|
- `bmad-customize` 스킬 - 의도를 올바른 위치의 검증된 오버라이드 파일로 바꿔 주는 안내형 작성 도우미
|
||||||
|
|
||||||
|
## 더 큰 아이디어
|
||||||
|
|
||||||
|
오늘날 대부분의 AI 어시스턴트는 메뉴이거나 프롬프트입니다. 둘 다 인지 부하를 사용자에게 넘깁니다. 이름 있는 에이전트와 커스터마이즈 가능한 스킬은 이미 일을 아는 팀원과 대화하게 해 주고, 조직이 포크 없이 그 팀원을 조정하게 합니다.
|
||||||
|
|
||||||
|
다음에 "Mary, 브레인스토밍하자"라고 입력했을 때 그녀가 바로 진행한다면, 무엇이 일어나지 않았는지 보세요. 슬래시 명령도, 탐색해야 할 메뉴도, 그녀가 무엇을 할 수 있는지 어색하게 상기시키는 일도 없었습니다. 바로 그 부재가 설계의 핵심입니다.
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
title: "파티 모드"
|
||||||
|
description: 다중 에이전트 협업 - 모든 AI 에이전트를 하나의 대화에 모읍니다
|
||||||
|
sidebar:
|
||||||
|
order: 11
|
||||||
|
---
|
||||||
|
|
||||||
|
모든 AI 에이전트를 하나의 대화에 모으세요.
|
||||||
|
|
||||||
|
## 파티 모드란?
|
||||||
|
|
||||||
|
`bmad-party-mode`를 실행하면 PM, 아키텍트, 개발자, UX 디자이너 등 필요한 AI 팀 전체가 한 대화방에 모입니다. 파티 모드가 논의를 조율하고 메시지마다 설치된 에이전트 중 적합한 에이전트를 선택합니다. 에이전트들은 각 페르소나에 맞게 답하고, 동의하거나 반대하며, 서로의 아이디어를 이어받아 발전시킵니다.
|
||||||
|
|
||||||
|
대화는 원하는 만큼 계속됩니다. 후속 질문을 묻고, 답에 반박하고, 토론 방향을 바꿀 수 있습니다. 끝날 때까지 에이전트들과 실제 주고받는 대화를 합니다.
|
||||||
|
|
||||||
|
**잘 맞는 경우:**
|
||||||
|
|
||||||
|
- 절충이 필요한 큰 결정
|
||||||
|
- 브레인스토밍 세션
|
||||||
|
- 문제가 생겼을 때의 사후 분석
|
||||||
|
- 스프린트 회고와 계획
|
||||||
|
|
||||||
|
## 예시
|
||||||
|
|
||||||
|
### 나쁜 아키텍처 지적하기
|
||||||
|
|
||||||
|
**사용자:** "좋아요 팀, 지난 스프린트는 엉망이었어요. 인증 서비스가 세 번이나 내려갔습니다. 어디서 문제가 생겼나요?"
|
||||||
|
|
||||||
|
**아키텍트:** "설계 자체는 건전했습니다. 분산 인증과 적절한 대체 경로가 있었죠. 구현이 사양에서 벗어났다면..."
|
||||||
|
|
||||||
|
**개발자:** "저는 아키텍처 문서를 그대로 따랐습니다. 사양이 동시 세션 무효화 경쟁 조건을 다루지 않았어요."
|
||||||
|
|
||||||
|
**PM:** "두 분 모두 더 큰 이슈를 놓쳤습니다. PRD에서 세션 관리 요구사항을 검증하지 않았어요. 그걸 잡지 못한 건 제 책임입니다."
|
||||||
|
|
||||||
|
**TEA:** "통합 테스트에서 제가 잡았어야 했습니다. 테스트 시나리오가 동시 무효화를 다루지 않았어요."
|
||||||
|
|
||||||
|
### 창의적 브레인스토밍
|
||||||
|
|
||||||
|
**사용자:** "온보딩이 지루하지 않고 특별하게 느껴지게 하려면 어떻게 해야 할까요?"
|
||||||
|
|
||||||
|
**UX 디자이너:** "점진적 공개부터 시작하세요. 기능을 튜토리얼에서 한꺼번에 보여주지 말고, 사용자가 필요로 할 때 드러내는 겁니다."
|
||||||
|
|
||||||
|
**스토리텔러:** "온보딩이 하나의 이야기라면 어떨까요? 각 단계가 캐릭터의 여정을 드러내고, 사용자가 바로 그 주인공이 되는 겁니다."
|
||||||
|
|
||||||
|
**게임 디자이너:** "그 아이디어를 이어가 보죠. 첫 번째 '퀘스트'가 실제 사용자 문제를 해결하는 일이라면 어떨까요? 사용자는 가치 있는 일을 해내며 배웁니다."
|
||||||
|
|
||||||
|
### 기술 결정
|
||||||
|
|
||||||
|
**사용자:** "MVP에는 모놀리스가 좋을까요, 마이크로서비스가 좋을까요?"
|
||||||
|
|
||||||
|
**아키텍트:** "모놀리스로 시작하세요. 사용자 1,000명 규모에서는 마이크로서비스가 필요 없는 복잡성을 더합니다."
|
||||||
|
|
||||||
|
**PM:** "동의합니다. 이론적인 확장성보다 출시 속도가 더 중요합니다."
|
||||||
|
|
||||||
|
**개발자:** "명확한 모듈 경계를 둔 모놀리스가 좋겠습니다. 필요해지면 나중에 서비스를 분리할 수 있습니다."
|
||||||
|
|
||||||
|
:::tip[더 나은 결정]
|
||||||
|
다양한 관점을 통해 더 나은 결정을 내립니다. 파티 모드에 오신 것을 환영합니다.
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
---
|
||||||
|
title: "에이전트 충돌 방지"
|
||||||
|
description: 여러 에이전트가 시스템을 구현할 때 아키텍처가 충돌을 방지하는 방법
|
||||||
|
sidebar:
|
||||||
|
order: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
여러 AI 에이전트가 시스템의 서로 다른 부분을 구현하면 충돌하는 기술 결정을 내릴 수 있습니다. 아키텍처 문서화는 공유 표준을 세워 이를 방지합니다.
|
||||||
|
|
||||||
|
## 일반적인 충돌 유형
|
||||||
|
|
||||||
|
### API 스타일 충돌
|
||||||
|
|
||||||
|
아키텍처가 없으면:
|
||||||
|
|
||||||
|
- 에이전트 A는 REST와 `/users/{id}`를 사용합니다
|
||||||
|
- 에이전트 B는 GraphQL 뮤테이션을 사용합니다
|
||||||
|
- 결과: 일관되지 않은 API 패턴과 혼란스러운 API 사용 경험
|
||||||
|
|
||||||
|
아키텍처가 있으면:
|
||||||
|
|
||||||
|
- ADR이 명시합니다. "모든 클라이언트-서버 통신에는 GraphQL을 사용"
|
||||||
|
- 모든 에이전트가 같은 패턴을 따릅니다
|
||||||
|
|
||||||
|
### 데이터베이스 설계 충돌
|
||||||
|
|
||||||
|
아키텍처가 없으면:
|
||||||
|
|
||||||
|
- 에이전트 A는 snake_case 컬럼명을 사용합니다
|
||||||
|
- 에이전트 B는 camelCase 컬럼명을 사용합니다
|
||||||
|
- 결과: 일관되지 않은 스키마와 혼란스러운 쿼리
|
||||||
|
|
||||||
|
아키텍처가 있으면:
|
||||||
|
|
||||||
|
- 표준 문서가 이름 규칙을 명시합니다
|
||||||
|
- 모든 에이전트가 같은 패턴을 따릅니다
|
||||||
|
|
||||||
|
### 상태 관리 충돌
|
||||||
|
|
||||||
|
아키텍처가 없으면:
|
||||||
|
|
||||||
|
- 에이전트 A는 전역 상태에 Redux를 사용합니다
|
||||||
|
- 에이전트 B는 React 컨텍스트를 사용합니다
|
||||||
|
- 결과: 여러 상태 관리 방식과 복잡성
|
||||||
|
|
||||||
|
아키텍처가 있으면:
|
||||||
|
|
||||||
|
- ADR이 상태 관리 방식을 명시합니다
|
||||||
|
- 모든 에이전트가 일관되게 구현합니다
|
||||||
|
|
||||||
|
## 아키텍처가 충돌을 방지하는 방법
|
||||||
|
|
||||||
|
### 1. ADR을 통한 명시적 결정
|
||||||
|
|
||||||
|
모든 중요한 기술 선택은 다음과 함께 문서화됩니다.
|
||||||
|
|
||||||
|
- 컨텍스트(왜 이 결정이 중요한가)
|
||||||
|
- 고려한 대안(어떤 선택지가 있는가)
|
||||||
|
- 결정(무엇을 선택했는가)
|
||||||
|
- 근거(왜 선택했는가)
|
||||||
|
- 결과(받아들인 절충)
|
||||||
|
|
||||||
|
### 2. FR/NFR별 지침
|
||||||
|
|
||||||
|
아키텍처는 각 기능 요구사항을 기술적 접근에 연결합니다.
|
||||||
|
|
||||||
|
- FR-001: 사용자 관리 → GraphQL 뮤테이션
|
||||||
|
- FR-002: 모바일 앱 → 최적화된 쿼리
|
||||||
|
|
||||||
|
### 3. 표준과 관례
|
||||||
|
|
||||||
|
다음을 명시적으로 문서화합니다.
|
||||||
|
|
||||||
|
- 디렉터리 구조
|
||||||
|
- 이름 규칙
|
||||||
|
- 코드 구성
|
||||||
|
- 테스트 패턴
|
||||||
|
|
||||||
|
## 공유 컨텍스트로서의 아키텍처
|
||||||
|
|
||||||
|
아키텍처를 구현 전 모든 에이전트가 읽는 공유 컨텍스트로 생각하세요.
|
||||||
|
|
||||||
|
```text
|
||||||
|
PRD: "무엇을 만들 것인가"
|
||||||
|
↓
|
||||||
|
아키텍처: "어떻게 만들 것인가"
|
||||||
|
↓
|
||||||
|
에이전트 A가 아키텍처를 읽음 → 에픽 1 구현
|
||||||
|
에이전트 B가 아키텍처를 읽음 → 에픽 2 구현
|
||||||
|
에이전트 C가 아키텍처를 읽음 → 에픽 3 구현
|
||||||
|
↓
|
||||||
|
결과: 일관된 구현
|
||||||
|
```
|
||||||
|
|
||||||
|
## 주요 ADR 주제
|
||||||
|
|
||||||
|
충돌을 방지하는 일반적인 결정:
|
||||||
|
|
||||||
|
| 주제 | 예시 결정 |
|
||||||
|
| --- | --- |
|
||||||
|
| API 스타일 | GraphQL vs REST vs gRPC |
|
||||||
|
| 데이터베이스 | PostgreSQL vs MongoDB |
|
||||||
|
| 인증 | JWT vs 세션 |
|
||||||
|
| 상태 관리 | Redux vs 컨텍스트 vs Zustand |
|
||||||
|
| 스타일링 | CSS Modules vs Tailwind vs Styled Components |
|
||||||
|
| 테스트 | Jest + Playwright vs Vitest + Cypress |
|
||||||
|
|
||||||
|
## 피해야 할 안티패턴
|
||||||
|
|
||||||
|
:::caution[흔한 실수]
|
||||||
|
- **암묵적 결정** - "API 스타일은 하면서 정하자"는 태도는 일관성 부족으로 이어집니다
|
||||||
|
- **과도한 문서화** - 모든 사소한 선택을 문서화하면 분석 마비가 생깁니다
|
||||||
|
- **오래된 아키텍처** - 한 번 쓰고 업데이트하지 않은 문서는 에이전트가 오래된 패턴을 따르게 합니다
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::tip[올바른 접근]
|
||||||
|
- 에픽 경계를 넘는 결정을 문서화하세요
|
||||||
|
- 충돌이 생기기 쉬운 영역에 집중하세요
|
||||||
|
- 배운 것을 반영해 아키텍처를 업데이트하세요
|
||||||
|
- 중요한 변경에는 `bmad-correct-course`를 사용하세요
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,160 @@
|
||||||
|
---
|
||||||
|
title: "프로젝트 컨텍스트"
|
||||||
|
description: project-context.md가 프로젝트 규칙과 선호도로 AI 에이전트를 안내하는 방법
|
||||||
|
sidebar:
|
||||||
|
order: 12
|
||||||
|
---
|
||||||
|
|
||||||
|
`project-context.md` 파일은 AI 에이전트를 위한 프로젝트 구현 가이드입니다. 다른 개발 체계의 "헌장"처럼 모든 워크플로에서 일관된 코드 생성을 보장하는 규칙, 패턴, 선호 사항을 포착합니다.
|
||||||
|
|
||||||
|
## 하는 일
|
||||||
|
|
||||||
|
AI 에이전트는 구현 중 계속 결정을 내립니다. 어떤 패턴을 따를지, 코드를 어떻게 구조화할지, 어떤 관례를 사용할지 등입니다. 명확한 안내가 없으면 다음이 일어날 수 있습니다.
|
||||||
|
|
||||||
|
- 코드베이스와 맞지 않는 범용 모범 사례를 따릅니다
|
||||||
|
- 스토리마다 일관되지 않은 결정을 내립니다
|
||||||
|
- 프로젝트별 요구사항이나 제약을 놓칩니다
|
||||||
|
|
||||||
|
`project-context.md` 파일은 에이전트가 알아야 할 것을 간결하고 LLM에 최적화된 형식으로 문서화해 이 문제를 해결합니다.
|
||||||
|
|
||||||
|
## 작동 방식
|
||||||
|
|
||||||
|
모든 구현 워크플로는 `project-context.md`가 있으면 자동으로 로드합니다. 아키텍트 워크플로도 아키텍처를 설계할 때 기술 선호 사항을 존중하기 위해 이 파일을 로드합니다.
|
||||||
|
|
||||||
|
**이 워크플로들이 로드합니다:**
|
||||||
|
|
||||||
|
- `bmad-create-architecture` - 솔루션 설계 중 기술 선호 사항을 존중합니다
|
||||||
|
- `bmad-create-story` - 프로젝트 패턴으로 스토리 작성을 안내합니다
|
||||||
|
- `bmad-dev-story` - 구현 결정을 안내합니다
|
||||||
|
- `bmad-code-review` - 프로젝트 표준과 비교해 검증합니다
|
||||||
|
- `bmad-quick-dev` - 사양을 구현할 때 패턴을 적용합니다
|
||||||
|
- `bmad-sprint-planning`, `bmad-retrospective`, `bmad-correct-course` - 프로젝트 전반의 컨텍스트를 제공합니다
|
||||||
|
|
||||||
|
## 언제 만들까요?
|
||||||
|
|
||||||
|
`project-context.md` 파일은 프로젝트 어느 단계에서든 유용합니다.
|
||||||
|
|
||||||
|
| 시나리오 | 만들 시점 | 목적 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| **새 프로젝트, 아키텍처 전** | `bmad-create-architecture` 전에 수동 작성 | 아키텍트가 기술 선호 사항을 존중하도록 문서화 |
|
||||||
|
| **새 프로젝트, 아키텍처 후** | `bmad-generate-project-context` 또는 수동 작성 | 구현 에이전트를 위해 아키텍처 결정 포착 |
|
||||||
|
| **기존 프로젝트** | `bmad-generate-project-context`로 생성 | 기존 패턴을 발견해 에이전트가 기존 관례를 따르게 함 |
|
||||||
|
| **빠른 흐름 프로젝트** | `bmad-quick-dev` 전 또는 중 | 빠른 구현이 패턴을 존중하도록 보장 |
|
||||||
|
|
||||||
|
:::tip[권장]
|
||||||
|
새 프로젝트에서 강한 기술 선호 사항이 있다면 아키텍처 전에 수동으로 만드세요. 그렇지 않다면 아키텍처 후 생성해 그 결정을 포착하세요.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 무엇이 들어가나요?
|
||||||
|
|
||||||
|
파일에는 두 주요 섹션이 있습니다.
|
||||||
|
|
||||||
|
### 기술 스택과 버전
|
||||||
|
|
||||||
|
프로젝트가 사용하는 프레임워크, 언어, 도구를 구체적 버전과 함께 문서화합니다.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## 기술 스택과 버전
|
||||||
|
|
||||||
|
- Node.js 20.x, TypeScript 5.3, React 18.2
|
||||||
|
- 상태 관리: Zustand(Redux 아님)
|
||||||
|
- 테스트: Vitest, Playwright, MSW
|
||||||
|
- 스타일링: 커스텀 디자인 토큰을 사용하는 Tailwind CSS
|
||||||
|
```
|
||||||
|
|
||||||
|
### 중요한 구현 규칙
|
||||||
|
|
||||||
|
에이전트가 놓칠 수 있는 패턴과 관례를 문서화합니다.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## 중요한 구현 규칙
|
||||||
|
|
||||||
|
**TypeScript 설정:**
|
||||||
|
- 엄격 모드 사용 - 명시적 승인 없이 `any` 타입 금지
|
||||||
|
- 공개 API에는 `interface`, 유니언/인터섹션에는 `type` 사용
|
||||||
|
|
||||||
|
**코드 구성:**
|
||||||
|
- 컴포넌트는 `/src/components/`에 두고 `.test.tsx`를 함께 배치
|
||||||
|
- 재사용 가능한 순수 함수는 `/src/lib/` 유틸리티에 배치
|
||||||
|
- API 호출은 `apiClient` 싱글턴 사용 - 직접 fetch 금지
|
||||||
|
|
||||||
|
**테스트 패턴:**
|
||||||
|
- 단위 테스트는 구현 세부사항이 아니라 비즈니스 로직에 집중
|
||||||
|
- 통합 테스트는 MSW로 API 응답을 모킹
|
||||||
|
- E2E 테스트는 중요한 사용자 여정만 다룸
|
||||||
|
|
||||||
|
**프레임워크별 규칙:**
|
||||||
|
- 모든 비동기 작업은 일관된 오류 처리를 위해 `handleError` 래퍼 사용
|
||||||
|
- 기능 플래그는 `@/lib/flags`의 `featureFlag()`로 접근
|
||||||
|
- 새 라우트는 `/src/app/`의 파일 기반 라우팅 패턴을 따름
|
||||||
|
```
|
||||||
|
|
||||||
|
코드 스니펫을 읽고 에이전트가 추론하지 못할 **겉으로 잘 드러나지 않는 것**에 집중하세요. 보편적으로 적용되는 표준 관행은 문서화하지 마세요.
|
||||||
|
|
||||||
|
## 파일 만들기
|
||||||
|
|
||||||
|
세 가지 선택지가 있습니다.
|
||||||
|
|
||||||
|
### 수동 작성
|
||||||
|
|
||||||
|
`_bmad-output/project-context.md`에 파일을 만들고 규칙을 추가합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 프로젝트 루트에서
|
||||||
|
mkdir -p _bmad-output
|
||||||
|
touch _bmad-output/project-context.md
|
||||||
|
```
|
||||||
|
|
||||||
|
기술 스택과 구현 규칙을 편집하세요. 아키텍트와 구현 워크플로가 자동으로 찾아 로드합니다.
|
||||||
|
|
||||||
|
### 아키텍처 후 생성
|
||||||
|
|
||||||
|
아키텍처를 완료한 뒤 `bmad-generate-project-context` 워크플로를 실행합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bmad-generate-project-context
|
||||||
|
```
|
||||||
|
|
||||||
|
이 워크플로는 아키텍처 문서와 프로젝트 파일을 스캔해 내려진 결정을 담은 컨텍스트 파일을 생성합니다.
|
||||||
|
|
||||||
|
### 기존 프로젝트용 생성
|
||||||
|
|
||||||
|
기존 프로젝트에서는 `bmad-generate-project-context`를 실행해 기존 패턴을 발견합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bmad-generate-project-context
|
||||||
|
```
|
||||||
|
|
||||||
|
워크플로가 코드베이스를 분석해 관례를 식별한 뒤 검토하고 다듬을 수 있는 컨텍스트 파일을 생성합니다.
|
||||||
|
|
||||||
|
## 왜 중요한가
|
||||||
|
|
||||||
|
`project-context.md`가 없으면 에이전트는 프로젝트에 맞지 않는 가정을 할 수 있습니다.
|
||||||
|
|
||||||
|
| 컨텍스트 없음 | 컨텍스트 있음 |
|
||||||
|
| --- | --- |
|
||||||
|
| 일반 패턴 사용 | 기존 관례 따름 |
|
||||||
|
| 스토리마다 일관되지 않은 스타일 | 일관된 구현 |
|
||||||
|
| 프로젝트별 제약을 놓칠 수 있음 | 모든 기술 요구사항 존중 |
|
||||||
|
| 각 에이전트가 독립적으로 결정 | 모든 에이전트가 같은 규칙에 맞춰 동작 |
|
||||||
|
|
||||||
|
특히 다음에 중요합니다.
|
||||||
|
|
||||||
|
- **빠른 흐름** - PRD와 아키텍처를 건너뛰므로 컨텍스트 파일이 공백을 채웁니다
|
||||||
|
- **팀 프로젝트** - 모든 에이전트가 같은 표준을 따르게 합니다
|
||||||
|
- **기존 프로젝트** - 기존 패턴을 깨뜨리지 않게 합니다
|
||||||
|
|
||||||
|
## 편집과 업데이트
|
||||||
|
|
||||||
|
`project-context.md` 파일은 살아 있는 문서입니다. 다음 때 업데이트하세요.
|
||||||
|
|
||||||
|
- 아키텍처 결정이 바뀝니다
|
||||||
|
- 새 관례가 확립됩니다
|
||||||
|
- 구현 중 패턴이 진화합니다
|
||||||
|
- 에이전트 동작에서 공백을 발견합니다
|
||||||
|
|
||||||
|
언제든 수동으로 편집하거나, 큰 변경 후 `bmad-generate-project-context`를 다시 실행해 업데이트할 수 있습니다.
|
||||||
|
|
||||||
|
:::note[파일 위치]
|
||||||
|
기본 위치는 `_bmad-output/project-context.md`입니다. 워크플로는 그곳을 검색하고, 프로젝트 어디에 있든 `**/project-context.md`도 확인합니다.
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
---
|
||||||
|
title: "빠른 개발"
|
||||||
|
description: 출력 품질을 보호하는 체크포인트를 포기하지 않고 사람이 개입하는 검토의 마찰을 줄입니다
|
||||||
|
sidebar:
|
||||||
|
order: 7
|
||||||
|
---
|
||||||
|
|
||||||
|
의도를 넣으면 코드 변경이 나오고, 사람이 개입하는 검토 단계는 가능한 한 적게 사용합니다. 품질은 희생하지 않습니다.
|
||||||
|
|
||||||
|
모델이 체크포인트 사이에서 더 오래 실행되게 한 뒤, 작업이 인간 판단 없이 안전하게 계속될 수 없거나 최종 결과를 리뷰할 때만 사람을 다시 불러옵니다.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 왜 존재하나요?
|
||||||
|
|
||||||
|
사람이 개입하는 검토 단계는 필요하지만 비용이 큽니다.
|
||||||
|
|
||||||
|
현재 LLM은 여전히 예측 가능한 방식으로 실패합니다. 의도를 잘못 읽고, 공백을 자신 있게 추측으로 채우고, 관련 없는 작업으로 흐름이 새며, 잡음 많은 리뷰 출력을 만듭니다. 동시에 지속적인 인간 개입은 개발 속도를 제한합니다. 사람의 주의력이 병목이 됩니다.
|
||||||
|
|
||||||
|
`bmad-quick-dev`는 이 절충점을 다시 조정합니다. 워크플로가 안전을 위한 충분히 강한 경계를 만든 뒤에는 모델이 더 긴 구간을 감독 없이 실행하도록 신뢰합니다.
|
||||||
|
|
||||||
|
## 핵심 설계
|
||||||
|
|
||||||
|
### 1. 먼저 의도를 압축합니다
|
||||||
|
|
||||||
|
워크플로는 사람과 모델이 요청을 하나의 일관된 목표로 압축하는 것에서 시작합니다. 입력은 거친 의도 표현일 수 있지만, 워크플로가 자율적으로 실행되기 전에는 실행 가능한 만큼 작고, 명확하고, 모순이 없어야 합니다.
|
||||||
|
|
||||||
|
의도는 다양한 형태로 올 수 있습니다. 몇 문구, 버그 추적기 링크, 계획 모드 출력, 채팅 세션에서 복사한 텍스트, 또는 BMAD의 `epics.md`에 있는 스토리 번호일 수 있습니다. 마지막 경우 워크플로는 BMAD 스토리 추적 규칙을 이해하지는 않지만, 스토리 자체를 가져와 실행할 수 있습니다.
|
||||||
|
|
||||||
|
이 워크플로는 인간 통제를 없애지 않습니다. 통제를 소수의 가치가 큰 순간으로 옮깁니다.
|
||||||
|
|
||||||
|
- **의도 명확화** - 정돈되지 않은 요청을 숨은 모순 없는 하나의 일관된 목표로 바꿉니다
|
||||||
|
- **사양 승인** - 고정된 이해가 만들 올바른 것인지 확인합니다
|
||||||
|
- **최종 결과 검토** - 최종 결과를 받아들일 수 있는지 사람이 결정하는 핵심 체크포인트입니다
|
||||||
|
|
||||||
|
### 2. 가장 작은 안전한 경로를 선택합니다
|
||||||
|
|
||||||
|
목표가 명확해지면 워크플로는 정말 한 번에 처리 가능한 변경인지, 더 완전한 경로가 필요한지 결정합니다. 작고 영향 범위가 거의 없는 변경은 바로 구현으로 갈 수 있습니다. 그 밖의 모든 것은 모델이 더 오래 혼자 실행되기 전에 더 강한 경계를 갖도록 계획을 거칩니다.
|
||||||
|
|
||||||
|
### 3. 더 적은 감독으로 더 오래 실행합니다
|
||||||
|
|
||||||
|
경로 결정 이후 모델은 더 많은 작업을 스스로 수행할 수 있습니다. 더 완전한 경로에서는 승인된 사양이 모델이 적은 감독으로 실행하는 경계가 되며, 이것이 설계의 핵심입니다.
|
||||||
|
|
||||||
|
### 4. 올바른 계층에서 실패를 진단합니다
|
||||||
|
|
||||||
|
의도가 틀려 구현이 틀렸다면 코드 패치는 잘못된 수정입니다. 사양이 약해서 코드가 틀렸다면 diff 패치도 잘못된 수정입니다. 워크플로는 실패가 시스템에 들어온 계층을 진단하고, 그 계층으로 돌아가 다시 생성하도록 설계되었습니다.
|
||||||
|
|
||||||
|
리뷰 발견 사항은 문제가 의도, 사양 생성, 로컬 구현 중 어디에서 왔는지 결정하는 데 쓰입니다. 정말 로컬 문제만 로컬 패치를 받습니다.
|
||||||
|
|
||||||
|
### 5. 필요할 때만 사람을 다시 부릅니다
|
||||||
|
|
||||||
|
의도 인터뷰는 사람이 개입하는 과정이지만 반복 체크포인트와는 다른 중단입니다. 워크플로는 반복 체크포인트를 최소화하려 합니다. 초기 구체화 이후 사람은 워크플로가 판단 없이 안전하게 계속할 수 없을 때와 마지막 리뷰 시점에 주로 돌아옵니다.
|
||||||
|
|
||||||
|
- **의도 공백 해소** - 리뷰가 워크플로가 의도를 안전하게 추론할 수 없었음을 보여줄 때 다시 들어옵니다
|
||||||
|
|
||||||
|
나머지는 더 긴 자율 실행 후보입니다. 이 절충은 의도적입니다. 오래된 패턴은 지속적인 감독에 더 많은 사람의 주의력을 씁니다. 빠른 개발은 모델에 더 많은 신뢰를 주지만, 사람의 판단이 가장 큰 효과를 내는 순간을 위해 주의력을 아낍니다.
|
||||||
|
|
||||||
|
## 리뷰 시스템이 중요한 이유
|
||||||
|
|
||||||
|
리뷰 단계는 버그를 찾기 위해서만 있는 것이 아닙니다. 추진력을 잃지 않고 수정을 올바른 경로로 보내기 위해 있습니다.
|
||||||
|
|
||||||
|
이 워크플로는 하위 에이전트를 생성할 수 있거나, 적어도 명령줄로 다른 LLM을 호출하고 결과를 기다릴 수 있는 플랫폼에서 가장 잘 동작합니다. 플랫폼이 기본으로 지원하지 않는다면 이를 수행하는 스킬을 추가할 수 있습니다. 컨텍스트 없는 하위 에이전트는 리뷰 설계의 핵심입니다.
|
||||||
|
|
||||||
|
에이전트 기반 리뷰는 보통 두 방식으로 잘못됩니다.
|
||||||
|
|
||||||
|
- 발견 사항이 너무 많아 사람이 노이즈를 걸러야 합니다.
|
||||||
|
- 관련 없는 이슈를 끌어들여 현재 변경의 흐름을 깨고, 모든 실행을 즉석 정리 작업으로 바꿉니다.
|
||||||
|
|
||||||
|
빠른 개발은 리뷰를 분류 작업으로 다뤄 둘 다 해결합니다.
|
||||||
|
|
||||||
|
어떤 발견 사항은 현재 변경에 속합니다. 어떤 발견 사항은 그렇지 않습니다. 발견 사항이 현재 작업과 인과적으로 연결되지 않은 부수적 이슈라면, 워크플로는 즉시 처리하도록 강제하지 않고 미룰 수 있습니다. 이렇게 하면 실행이 집중되고, 무작위로 뻗는 곁가지가 검토 여력을 소모하지 않습니다.
|
||||||
|
|
||||||
|
분류는 때때로 완벽하지 않습니다. 괜찮습니다. 수천 개의 낮은 가치 리뷰 댓글로 사람을 압도하는 것보다 일부 발견 사항을 잘못 판단하는 편이 보통 낫습니다. 이 시스템은 모든 이슈를 빠짐없이 회수하는 것보다 신호 품질을 최적화합니다.
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
---
|
||||||
|
title: 'Web Bundles'
|
||||||
|
description: Google Gemini Gems와 ChatGPT Custom GPT용으로 패키징된 BMad 스킬
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad의 계획 작업은 웹 LLM 구독 환경에서 실행하고, 만들어진 산출물은 IDE로 가져오세요.
|
||||||
|
|
||||||
|
## Web Bundle이란?
|
||||||
|
|
||||||
|
Web bundle은 **Google Gemini Gem** 또는 **ChatGPT Custom GPT**로 설치할 수 있게 다시 패키징한 BMad 스킬입니다. 각 번들에는 지식 파일로 업로드하는 `SKILL.md` 프로토콜, Gem 또는 GPT 지침에 붙여 넣는 `INSTRUCTIONS.md` 블록, 그리고 스킬에 필요한 데이터 파일(CSV, 템플릿, 검증 체크리스트, 추가로 점진 공개되는 콘텐츠)이 포함됩니다. 페르소나는 붙여 넣은 지침에 있고, 프로토콜은 지식 파일에 있습니다. 프로토콜을 건드리지 않고도 페르소나를 바꿀 수 있습니다.
|
||||||
|
|
||||||
|
설치가 원클릭은 아니지만 단계는 안내됩니다. **[bmadcode.com/web-bundles](https://bmadcode.com/web-bundles/)에서 설치하세요**. 이 사이트는 모든 번들을 카드 그리드로 보여 주고, Gemini와 ChatGPT 설치 단계를 페이지 안에서 안내하며, ZIP 다운로드를 제공합니다. 이것이 지원되는 설치 경로입니다. 전체 카탈로그에서 패턴이 같으므로 하나만 설치해 보면 다음 번들은 기계적으로 진행할 수 있습니다.
|
||||||
|
|
||||||
|
BMad V4에도 web bundle이 있었습니다. V6에서는 현재 Gem과 Custom GPT 플랫폼, Canvas, Deep Research, 이미지 생성을 염두에 두고 다시 작성해 되살렸습니다.
|
||||||
|
|
||||||
|
## 사용하는 이유
|
||||||
|
|
||||||
|
계획 작업과 구현 작업에는 서로 다른 도구가 어울립니다. Web bundle은 각 작업을 가장 잘 맞는 곳에서 하게 해 줍니다.
|
||||||
|
|
||||||
|
| 관심사 | Web LLM(Gem 또는 GPT) | IDE(Claude Code, Cursor) |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 비용 모델 | 정액 구독 | 토큰 사용량 과금 |
|
||||||
|
| 강점 | 대화, Canvas, Deep Research, 이미지 | 파일, 터미널, 코드베이스 컨텍스트 |
|
||||||
|
| 가장 적합한 작업 | 브레인스토밍, brief, PRD, 리서치 | 구현, 리팩터링, 코드 리뷰 |
|
||||||
|
|
||||||
|
전체 PRD나 시장 리서치 대화를 IDE에서 진행하면 토큰을 많이 쓰지만, Gem이나 Custom GPT에서는 이미 가진 구독 비용 안에서 처리할 수 있습니다. 다듬어진 산출물은 저장소에 넣고 Claude Code나 Cursor가 이어받으면 됩니다.
|
||||||
|
|
||||||
|
:::tip[웹에서 계획하고 IDE에서 빌드하세요]
|
||||||
|
작업이 길어질수록 비용 절감 효과가 커집니다. Gem에서 PRFAQ 한 번과 리서치 세 라운드를 돌리는 것은 추가 비용이 없지만, 같은 작업을 IDE에서 하면 실제 지출이 됩니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 카탈로그에 있는 것
|
||||||
|
|
||||||
|
현재 번들 세트는 분석과 계획 단계를 다룹니다.
|
||||||
|
|
||||||
|
| Bundle | Phase | Persona lineage |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Brainstorming Coach | Analysis | Osborn(기본), Minto(교체) |
|
||||||
|
| Product Brief Coach | Analysis | Mary(BMad 분석가) |
|
||||||
|
| PRFAQ Coach | Analysis | Working Backwards(Bezos) |
|
||||||
|
| PRD Coach | Planning | Cagan |
|
||||||
|
| UX Coach | Planning | Norman |
|
||||||
|
| Market & Industry Research | Analysis | Porter와 Christensen |
|
||||||
|
|
||||||
|
각 번들은 소유 BMad 에이전트가 있는 경우 그 에이전트에서 물려받은 기본 페르소나와, 목소리 변경 패턴을 보여 주는 대비용 교체 예시를 함께 담고 있습니다.
|
||||||
|
|
||||||
|
## 세션 작동 방식
|
||||||
|
|
||||||
|
1. **Gem 또는 Custom GPT를 엽니다.** 페르소나가 캐릭터에 맞게 인사하고 대화형 발견을 시작합니다.
|
||||||
|
2. **범위를 발견합니다.** 페르소나는 무엇을 하려는지, 이미 가진 것이 무엇인지, 어떤 제약이 있는지 묻습니다. 양식 채우기가 아닙니다.
|
||||||
|
3. **Canvas에서 작업합니다.** 프로토콜은 세션 시작 시 Canvas를 열고 계속 업데이트합니다. Mermaid 다이어그램과 HTML 테이블도 글과 함께 들어갑니다.
|
||||||
|
4. **인계합니다.** 작업이 끝나면 저장소에 붙여 넣거나, 내보내거나, 다음 단계를 위해 IDE의 BMad 스킬에 전달할 수 있는 Canvas 문서가 생깁니다.
|
||||||
|
|
||||||
|
Deep Research를 통합한 번들(현재 Market & Industry Research)은 세션 중간에 Gemini 또는 ChatGPT의 Deep Research 모드에 붙여 넣을 brief를 작성하고, 반환된 보고서를 다시 받아들입니다.
|
||||||
|
|
||||||
|
## Web bundle을 사용할 때
|
||||||
|
|
||||||
|
- 프로젝트의 앞단 사고를 진행하고 있고, 페르소나, Canvas, Deep Research를 갖춘 집중 도구가 필요합니다.
|
||||||
|
- IDE 토큰 지출은 실제 코딩에 남겨 두고 싶습니다.
|
||||||
|
- IDE 설정이 없는 협업자와 계획 산출물을 공유해야 합니다.
|
||||||
|
|
||||||
|
## IDE에 머무를 때
|
||||||
|
|
||||||
|
- 작업이 저장소의 코드를 읽거나 수정해야 합니다.
|
||||||
|
- 이미 구현 중이고 컨텍스트를 유지하고 싶습니다.
|
||||||
|
- Gemini Advanced 또는 ChatGPT Plus 구독이 없습니다.
|
||||||
|
|
||||||
|
## 업데이트와 커스터마이징
|
||||||
|
|
||||||
|
번들은 계속 발전합니다. 새 버전의 번들을 가져올 때 일반적으로 바뀌는 것은 지식 파일(`SKILL.md` 프로토콜과 첨부 템플릿, CSV, 검증 체크리스트)입니다. 업데이트를 적용하려면 Gem 또는 Custom GPT에 그 파일들을 다시 업로드하세요. 지침 블록은 보통 바뀌지 않습니다.
|
||||||
|
|
||||||
|
팀이나 자신의 목소리에 맞게 번들을 커스터마이징하려면 지식 파일이 아니라 Gem 또는 GPT에 붙여 넣은 **지침 블록**에서 하세요. 지침 블록은 페르소나, 선호 사항, 로컬 오버라이드가 있는 곳입니다. 지식 파일은 번들이 제공하는 프로토콜입니다. 커스터마이징을 지침 블록에 두면 이후 업데이트는 첨부 파일을 교체하는 작업이 되고, 수정 사항을 다시 병합하는 일이 되지 않습니다.
|
||||||
|
|
||||||
|
:::tip[지침을 커스터마이징하고 지식 파일을 첨부하세요]
|
||||||
|
페르소나 교체, 기본 사용자 이름, 팀별 가드레일, 선호 표현은 모두 붙여 넣은 지침 블록에 둡니다. 지식 파일은 그대로 두어야 변경 사항을 잃지 않고 새로 고칠 수 있습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 직접 만들기
|
||||||
|
|
||||||
|
Web bundle은 `bmad-os-skill-to-bundle` 유틸리티 스킬을 사용해 BMad 스킬에서 생성합니다. 어떤 BMad 스킬 폴더든 지정하면 소유 에이전트에서 페르소나를 상속한 번들 파일을 만듭니다.
|
||||||
|
|
||||||
|
모든 번들은 [bmadcode.com/web-bundles](https://bmadcode.com/web-bundles/)에서 설치할 수 있습니다.
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
---
|
||||||
|
title: "솔루션 설계가 중요한 이유"
|
||||||
|
description: 다중 에픽 프로젝트에서 솔루션 설계 단계가 중요한 이유
|
||||||
|
sidebar:
|
||||||
|
order: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
단계 3(솔루션 설계)은 계획 단계의 **무엇을** 만들지를 **어떻게** 만들지로 바꿉니다. 구현이 시작되기 전에 아키텍처 결정을 문서화해 다중 에픽 프로젝트에서 에이전트 충돌을 방지합니다.
|
||||||
|
|
||||||
|
## 솔루션 설계가 없을 때의 문제
|
||||||
|
|
||||||
|
```text
|
||||||
|
에이전트 1은 에픽 1을 REST API로 구현
|
||||||
|
에이전트 2는 에픽 2를 GraphQL로 구현
|
||||||
|
결과: 일관되지 않은 API 설계와 통합 난이도 증가
|
||||||
|
```
|
||||||
|
|
||||||
|
여러 에이전트가 공유 아키텍처 지침 없이 시스템의 서로 다른 부분을 구현하면 서로 충돌하는 독립적 기술 결정을 내릴 수 있습니다.
|
||||||
|
|
||||||
|
## 솔루션 설계가 있을 때의 해결책
|
||||||
|
|
||||||
|
```text
|
||||||
|
아키텍처 워크플로가 결정: "모든 API에 GraphQL 사용"
|
||||||
|
모든 에이전트가 아키텍처 결정을 따름
|
||||||
|
결과: 일관된 구현, 충돌 없음
|
||||||
|
```
|
||||||
|
|
||||||
|
기술 결정을 명시적으로 문서화하면 모든 에이전트가 일관되게 구현하고 통합이 단순해집니다.
|
||||||
|
|
||||||
|
## 솔루션 설계 vs 계획
|
||||||
|
|
||||||
|
| 측면 | 계획 (단계 2) | 솔루션 설계 (단계 3) |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 질문 | 무엇을, 왜? | 어떻게? 그리고 어떤 작업 단위로? |
|
||||||
|
| 출력 | FRs/NFRs(요구사항) | 아키텍처 + 에픽/스토리 |
|
||||||
|
| 에이전트 | PM | 아키텍트 → PM |
|
||||||
|
| 대상 | 이해관계자 | 개발자 |
|
||||||
|
| 문서 | PRD(기능/비기능 요구사항) | 아키텍처 + 에픽 파일 |
|
||||||
|
| 수준 | 비즈니스 로직 | 기술 설계 + 작업 분해 |
|
||||||
|
|
||||||
|
## 핵심 원칙
|
||||||
|
|
||||||
|
**기술 결정을 명시적으로 문서화**해 모든 에이전트가 일관되게 구현하도록 합니다.
|
||||||
|
|
||||||
|
이것은 다음을 방지합니다.
|
||||||
|
|
||||||
|
- API 스타일 충돌(REST vs GraphQL)
|
||||||
|
- 데이터베이스 설계 불일치
|
||||||
|
- 상태 관리 방식 차이
|
||||||
|
- 이름 규칙 불일치
|
||||||
|
- 보안 접근 방식 차이
|
||||||
|
|
||||||
|
## 솔루션 설계가 필요한 때
|
||||||
|
|
||||||
|
| 트랙 | 솔루션 설계 필요 여부 |
|
||||||
|
| --- | --- |
|
||||||
|
| 빠른 흐름 | 아니요 - 완전히 건너뜁니다 |
|
||||||
|
| BMad Method 단순 | 선택 사항 |
|
||||||
|
| BMad Method 복잡 | 예 |
|
||||||
|
| 엔터프라이즈 | 예 |
|
||||||
|
|
||||||
|
:::tip[경험칙]
|
||||||
|
서로 다른 에이전트가 구현할 수 있는 여러 에픽이 있다면 솔루션 설계가 필요합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 건너뛸 때의 비용
|
||||||
|
|
||||||
|
복잡한 프로젝트에서 솔루션 설계를 건너뛰면 다음으로 이어집니다.
|
||||||
|
|
||||||
|
- 스프린트 중 발견되는 **통합 이슈**
|
||||||
|
- 충돌하는 구현으로 인한 **재작업**
|
||||||
|
- 전체적으로 **더 긴 개발 시간**
|
||||||
|
- 일관되지 않은 패턴에서 생기는 **기술 부채**
|
||||||
|
|
||||||
|
:::caution[비용 배율]
|
||||||
|
방향이 어긋나는 문제를 솔루션 설계에서 잡는 것이 구현 중 발견하는 것보다 10배 빠릅니다.
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,387 @@
|
||||||
|
---
|
||||||
|
title: 'BMad 커스터마이징 방법'
|
||||||
|
description: 업데이트 호환성을 유지하면서 에이전트와 워크플로를 커스터마이징합니다
|
||||||
|
sidebar:
|
||||||
|
order: 8
|
||||||
|
---
|
||||||
|
|
||||||
|
설치된 파일을 수정하지 않고 에이전트 페르소나를 조정하고, 도메인 컨텍스트를 주입하고, 기능을 추가하고, 워크플로 동작을 설정하세요. 커스터마이징은 업데이트 후에도 유지됩니다.
|
||||||
|
|
||||||
|
:::tip[TOML을 직접 쓰고 싶지 않나요? `bmad-customize`를 사용하세요]
|
||||||
|
`bmad-customize` 스킬은 이 문서에서 설명하는 **스킬별 에이전트/워크플로 오버라이드 영역**을 안내형으로 작성해 주는 도우미입니다. 설치된 항목 중 무엇을 커스터마이즈할 수 있는지 스캔하고, 의도에 맞는 영역(에이전트 또는 워크플로)을 고르게 하고, 오버라이드 파일을 작성하고, 병합이 적용되었는지 검증합니다. 중앙 설정 오버라이드(`_bmad/custom/config.toml`)는 v1 범위 밖이므로 아래 중앙 설정 섹션에 따라 직접 작성해야 합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
- 에이전트의 성격이나 커뮤니케이션 스타일을 바꾸고 싶습니다
|
||||||
|
- 에이전트가 계속 기억할 사실이 필요합니다(예: "우리 조직은 AWS만 사용")
|
||||||
|
- 매 세션 시작 시 에이전트가 반드시 수행해야 하는 절차적 단계를 추가하고 싶습니다
|
||||||
|
- 자체 스킬이나 프롬프트를 실행하는 커스텀 메뉴 항목을 추가하고 싶습니다
|
||||||
|
- 팀 공통 커스터마이징은 git에 커밋하고, 개인 선호는 그 위에 덧씌우고 싶습니다
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
|
||||||
|
- 프로젝트에 BMad 설치([BMad 설치 방법](./install-bmad.md) 참고)
|
||||||
|
- PATH의 Python 3.11+(병합 스크립트용, stdlib `tomllib`만 사용하며 `pip install`, `uv`, virtualenv 불필요)
|
||||||
|
- TOML 파일을 편집할 텍스트 에디터
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 작동 방식
|
||||||
|
|
||||||
|
커스터마이즈 가능한 모든 스킬은 기본값이 들어 있는 `customize.toml` 파일을 제공합니다. 이 파일은 스킬의 전체 커스터마이징 영역을 정의합니다. 무엇을 바꿀 수 있는지 보려면 이 파일을 읽으세요. 이 파일은 직접 편집하지 않습니다. 대신 바꾸려는 필드만 담은 오버라이드 파일을 만듭니다.
|
||||||
|
|
||||||
|
### 3계층 오버라이드 모델
|
||||||
|
|
||||||
|
```text
|
||||||
|
우선순위 1(승리): _bmad/custom/{skill-name}.user.toml (개인, git 무시)
|
||||||
|
우선순위 2: _bmad/custom/{skill-name}.toml (팀/조직, 커밋)
|
||||||
|
우선순위 3(마지막): 스킬 자체 customize.toml (기본값)
|
||||||
|
```
|
||||||
|
|
||||||
|
`_bmad/custom/` 폴더는 처음엔 비어 있습니다. 누군가 실제로 커스터마이즈할 때만 파일이 생깁니다.
|
||||||
|
|
||||||
|
### 병합 규칙(필드명이 아니라 모양 기준)
|
||||||
|
|
||||||
|
병합 스크립트는 네 가지 구조 규칙을 적용합니다. 필드명은 특별 취급되지 않습니다. 값의 구조가 동작을 결정합니다.
|
||||||
|
|
||||||
|
| 모양 | 규칙 |
|
||||||
|
| --- | --- |
|
||||||
|
| 스칼라 값(문자열, 정수, 불리언, 실수) | 오버라이드가 이깁니다 |
|
||||||
|
| 테이블 | 깊은 병합(재귀적으로 이 규칙을 적용) |
|
||||||
|
| 모든 항목이 **같은** 식별자 필드(`code` 또는 `id`)를 공유하는 테이블 배열 | 해당 키로 병합합니다. 같은 키는 **제자리에서 교체**, 새 키는 **추가**됩니다 |
|
||||||
|
| 그 밖의 배열(스칼라 값, 식별자가 없는 테이블, `code`와 `id`가 섞인 배열) | **추가**됩니다. 기본값, 팀, 사용자 순서입니다 |
|
||||||
|
|
||||||
|
**삭제 메커니즘은 없습니다.** 오버라이드는 기본값 항목을 지울 수 없습니다. 기본 메뉴 항목을 숨겨야 한다면 같은 `code`로 동작 없는 설명이나 프롬프트를 넣어 덮어쓰세요. 배열을 더 깊게 재구성해야 한다면 스킬을 포크하세요.
|
||||||
|
|
||||||
|
**`code` / `id` 관례.** BMad는 테이블 배열의 병합 키로 `code`(예: `"BP"`, `"R1"` 같은 짧은 식별자)와 `id`(더 긴 안정 식별자)를 사용합니다. 직접 만든 테이블 배열이 추가 전용이 아니라 키로 교체 가능해야 한다면 한 가지 관례만 고르고 전체 배열에서 일관되게 사용하세요. 일부 항목은 `code`, 일부 항목은 `id`를 쓰면 키 병합 대신 추가 방식으로 처리됩니다.
|
||||||
|
|
||||||
|
### 일부 에이전트 필드는 읽기 전용입니다
|
||||||
|
|
||||||
|
`agent.name`과 `agent.title`은 기준 메타데이터로 `customize.toml`에 있지만, 에이전트의 SKILL.md는 런타임에 이를 읽지 않습니다. 정체성은 하드코딩되어 있습니다. 오버라이드 파일에 `name = "Bob"`을 넣어도 효과가 없습니다. 정말 다른 이름의 에이전트가 필요하다면 스킬 폴더를 복사해 이름을 바꾸고 커스텀 스킬로 배포하세요.
|
||||||
|
|
||||||
|
## 단계
|
||||||
|
|
||||||
|
### 1. 스킬의 커스터마이징 영역 찾기
|
||||||
|
|
||||||
|
설치된 디렉터리에서 스킬의 `customize.toml`을 확인합니다. PM 에이전트 예:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.claude/skills/bmad-agent-pm/customize.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
경로는 IDE별로 다릅니다. Cursor는 `.agents/skills/`, Cline은 `.cline/skills/`를 사용합니다.
|
||||||
|
|
||||||
|
이 파일이 기준 스키마입니다. 읽기 전용 정체성 필드를 제외하고 보이는 모든 필드는 커스터마이즈할 수 있습니다.
|
||||||
|
|
||||||
|
### 2. 오버라이드 파일 만들기
|
||||||
|
|
||||||
|
프로젝트 루트에 `_bmad/custom/` 디렉터리가 없다면 만듭니다. 그런 다음 스킬 이름을 딴 파일을 만듭니다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
_bmad/custom/
|
||||||
|
bmad-agent-pm.toml # 팀 오버라이드(git에 커밋)
|
||||||
|
bmad-agent-pm.user.toml # 개인 선호(git에서 무시)
|
||||||
|
```
|
||||||
|
|
||||||
|
:::caution[전체 `customize.toml`을 복사하지 마세요]
|
||||||
|
오버라이드 파일은 **희소**입니다. 바꾸는 필드만 포함하세요. 생략한 필드는 아래 계층(팀은 기본값에서, 사용자는 팀 또는 기본값에서) 자동 상속됩니다.
|
||||||
|
|
||||||
|
전체 `customize.toml`을 오버라이드로 복사하면 해롭습니다. 다음 업데이트가 새 기본값을 제공해도 오버라이드 파일이 옛 값을 고정하기 때문에 릴리스마다 조용히 어긋납니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
**예시 - 아이콘을 바꾸고 원칙 하나 추가:**
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-agent-pm.toml
|
||||||
|
# 바꾸는 필드만 둡니다. 나머지는 모두 상속됩니다.
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
icon = "🏥"
|
||||||
|
principles = [
|
||||||
|
"FDA 감사를 통과할 수 없는 것은 출시하지 않습니다.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
이 설정은 새 원칙을 기본값에 추가하고(제공된 원칙은 그대로 유지), 아이콘을 교체합니다. 나머지 필드는 제공된 값으로 남습니다.
|
||||||
|
|
||||||
|
### 3. 필요한 항목 커스터마이즈하기
|
||||||
|
|
||||||
|
아래 예시는 BMad의 평면 에이전트 스키마를 가정합니다. 필드는 `[agent]` 아래에 직접 위치하며 중첩된 `metadata`나 `persona` 하위 테이블은 없습니다.
|
||||||
|
|
||||||
|
**스칼라 값(icon, 역할, 정체성, communication_style).** 스칼라 값 오버라이드가 이깁니다. 바꾸는 필드만 설정하면 됩니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-agent-pm.toml
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
icon = "🏥"
|
||||||
|
role = "규제 대상 헬스케어 도메인의 제품 발견을 이끕니다."
|
||||||
|
communication_style = "정밀하고 규제를 의식하며, 초반부터 컴플라이언스 관점의 질문을 던집니다."
|
||||||
|
```
|
||||||
|
|
||||||
|
**영구 사실, 원칙, 활성화 후크(추가 배열).** 아래 네 배열은 추가 전용입니다. 팀 항목은 기본값 뒤에 실행되고, 사용자 항목은 마지막에 실행됩니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[agent]
|
||||||
|
# 에이전트가 세션 내내 염두에 둘 정적 사실입니다. 조직 규칙, 도메인
|
||||||
|
# 상수, 사용자 선호 등이 여기에 들어갑니다. 런타임 메모리 사이드카와는 다릅니다.
|
||||||
|
#
|
||||||
|
# 각 항목은 문장 그대로이거나, 내용을 사실로 로드하는 `file:` 참조입니다
|
||||||
|
# glob 패턴도 지원합니다.
|
||||||
|
persistent_facts = [
|
||||||
|
"우리 조직은 AWS만 사용합니다. GCP나 Azure를 제안하지 마세요.",
|
||||||
|
"모든 PRD는 엔지니어링 착수 전에 법무 승인을 받아야 합니다.",
|
||||||
|
"대상 사용자는 환자가 아니라 임상의입니다. 예시도 그에 맞춰 구성하세요.",
|
||||||
|
"file:{project-root}/docs/compliance/hipaa-overview.md",
|
||||||
|
"file:{project-root}/_bmad/custom/company-glossary.md",
|
||||||
|
]
|
||||||
|
|
||||||
|
# 에이전트의 가치 체계에 추가합니다
|
||||||
|
principles = [
|
||||||
|
"FDA 감사를 통과할 수 없는 것은 출시하지 않습니다.",
|
||||||
|
"사용자 가치를 먼저, 컴플라이언스는 항상 지킵니다.",
|
||||||
|
]
|
||||||
|
|
||||||
|
# 표준 활성화(페르소나, persistent_facts, 설정, 인사) 전에 실행합니다.
|
||||||
|
activation_steps_prepend = [
|
||||||
|
"{project-root}/docs/compliance/를 스캔하고 HIPAA 관련 문서를 컨텍스트로 로드하세요.",
|
||||||
|
]
|
||||||
|
|
||||||
|
# 인사 후, 메뉴 전에 실행합니다.
|
||||||
|
activation_steps_append = [
|
||||||
|
"{project-root}/_bmad/custom/company-glossary.md가 있으면 읽으세요.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
두 후크는 역할이 다릅니다. Prepend는 인사 전에 실행되어 인사 자체를 개인화하는 데 필요한 컨텍스트를 로드할 수 있습니다. Append는 인사 후 실행되어 무거운 스캔이 끝날 때까지 사용자가 빈 화면만 보지 않게 합니다.
|
||||||
|
|
||||||
|
**메뉴 커스터마이징(`code`로 병합).** 메뉴는 테이블 배열입니다. 각 항목에는 `code` 필드가 있으므로 병합 스크립트는 코드로 병합합니다. 같은 코드는 제자리에서 교체되고, 새 코드는 추가됩니다.
|
||||||
|
|
||||||
|
TOML 테이블 배열 문법은 항목마다 `[[agent.menu]]`를 사용합니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# 기존 CE 항목을 커스텀 스킬로 교체
|
||||||
|
[[agent.menu]]
|
||||||
|
code = "CE"
|
||||||
|
description = "우리 전달 프레임워크로 에픽 생성"
|
||||||
|
skill = "custom-create-epics"
|
||||||
|
|
||||||
|
# 새 항목 추가(기본값에는 RC 코드가 없음)
|
||||||
|
[[agent.menu]]
|
||||||
|
code = "RC"
|
||||||
|
description = "컴플라이언스 사전 점검 실행"
|
||||||
|
prompt = """
|
||||||
|
{project-root}/_bmad/custom/compliance-checklist.md를 읽고
|
||||||
|
{planning_artifacts}의 모든 문서를 그 기준에 맞춰 스캔하세요.
|
||||||
|
공백이 있으면 관련 규제 조항을 인용해 보고하세요.
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
각 메뉴 항목은 `skill`(등록된 스킬 호출) 또는 `prompt`(텍스트 직접 실행) 중 정확히 하나를 가집니다. 오버라이드에 나열하지 않은 항목은 기본값을 유지합니다.
|
||||||
|
|
||||||
|
**파일 참조.** `persistent_facts`, `activation_steps_prepend`/`activation_steps_append`, 메뉴 항목의 `prompt`처럼 텍스트가 파일을 가리켜야 할 때는 `{project-root}`를 기준으로 한 전체 경로를 사용하세요. 파일이 `_bmad/custom/`에서 오버라이드 옆에 있더라도 `{project-root}/_bmad/custom/info.md`처럼 전체 경로를 적습니다.
|
||||||
|
|
||||||
|
### 4. 개인 vs 팀
|
||||||
|
|
||||||
|
**팀 파일**(`bmad-agent-pm.toml`): git에 커밋합니다. 조직 전체에 공유됩니다. 컴플라이언스 규칙, 회사 페르소나, 커스텀 기능에 사용합니다.
|
||||||
|
|
||||||
|
**개인 파일**(`bmad-agent-pm.user.toml`): 자동으로 git에서 무시됩니다. 말투 조정, 개인 워크플로 선호 사항, 에이전트가 기억해야 하는 개인 사실에 사용합니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-agent-pm.user.toml
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
persistent_facts = [
|
||||||
|
"선택지를 제시할 때 항상 대략적인 복잡도 추정(낮음/중간/높음)을 포함하세요.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 해석이 작동하는 방식
|
||||||
|
|
||||||
|
활성화 시 에이전트의 SKILL.md가 공유 Python 스크립트를 실행해 3계층 병합을 수행하고 해석된 블록을 JSON으로 반환합니다. 스크립트는 Python 표준 라이브러리의 `tomllib`만 사용하므로 기본 `python3`이면 충분합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 {project-root}/_bmad/scripts/resolve_customization.py \
|
||||||
|
--skill {skill-root} \
|
||||||
|
--key agent
|
||||||
|
```
|
||||||
|
|
||||||
|
**요구사항**: Python 3.11+(이전 버전에는 `tomllib`이 없습니다). `pip install`, `uv`, virtualenv는 필요 없습니다. `python3 --version`으로 확인하세요. Homebrew 없는 macOS나 Ubuntu 22.04 같은 플랫폼은 기본 `python3`이 3.10 이하일 수 있으므로 3.11+를 별도 설치해야 할 수 있습니다.
|
||||||
|
|
||||||
|
`--skill`은 스킬이 설치된 디렉터리(`customize.toml`이 있는 위치)를 가리킵니다. 스킬 이름은 디렉터리의 basename에서 파생되며, 스크립트는 `_bmad/custom/{skill-name}.toml`과 `{skill-name}.user.toml`을 자동으로 찾습니다.
|
||||||
|
|
||||||
|
유용한 호출:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 전체 에이전트 블록 해석
|
||||||
|
python3 {project-root}/_bmad/scripts/resolve_customization.py \
|
||||||
|
--skill /abs/path/to/bmad-agent-pm \
|
||||||
|
--key agent
|
||||||
|
|
||||||
|
# 단일 필드 해석
|
||||||
|
python3 {project-root}/_bmad/scripts/resolve_customization.py \
|
||||||
|
--skill /abs/path/to/bmad-agent-pm \
|
||||||
|
--key agent.icon
|
||||||
|
|
||||||
|
# 전체 덤프
|
||||||
|
python3 {project-root}/_bmad/scripts/resolve_customization.py \
|
||||||
|
--skill /abs/path/to/bmad-agent-pm
|
||||||
|
```
|
||||||
|
|
||||||
|
출력은 항상 JSON입니다. 특정 플랫폼에서 스크립트를 사용할 수 없다면 SKILL.md는 에이전트에게 세 TOML 파일을 직접 읽고 같은 병합 규칙을 적용하라고 지시합니다.
|
||||||
|
|
||||||
|
## 워크플로 커스터마이징
|
||||||
|
|
||||||
|
`bmad-product-brief`처럼 여러 단계 프로세스를 구동하는 워크플로(스킬)도 에이전트와 같은 오버라이드 메커니즘을 공유합니다. 커스터마이즈 가능한 영역은 `[agent]` 대신 `[workflow]` 아래에 있습니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-product-brief.toml
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
activation_steps_prepend = [
|
||||||
|
"Load {project-root}/docs/product/north-star-principles.md as context.",
|
||||||
|
]
|
||||||
|
|
||||||
|
activation_steps_append = []
|
||||||
|
|
||||||
|
persistent_facts = [
|
||||||
|
"모든 개요에는 명시적인 규제 위험 섹션이 포함되어야 합니다.",
|
||||||
|
"file:{project-root}/docs/compliance/product-brief-checklist.md",
|
||||||
|
]
|
||||||
|
|
||||||
|
on_complete = "개요를 세 개의 글머리표로 요약하고 gws-gmail-send 스킬로 이메일 발송을 제안하세요."
|
||||||
|
```
|
||||||
|
|
||||||
|
동일한 필드 관례가 에이전트/워크플로 경계를 넘습니다. `activation_steps_prepend`/`activation_steps_append`, `persistent_facts`(`file:` 참조 포함), 그리고 키 기반 병합용 `code`/`id`가 있는 메뉴 스타일 `[[...]]` 테이블이 모두 같은 방식으로 동작합니다. 병합 스크립트는 최상위 키와 관계없이 네 구조 규칙을 적용합니다. SKILL.md 참조는 네임스페이스를 따릅니다: `{workflow.activation_steps_prepend}`, `{workflow.persistent_facts}`, `{workflow.on_complete}`. 워크플로가 노출하는 추가 필드(출력 경로, 토글, 리뷰 설정, 단계 플래그 등)도 같은 구조 기반 병합 규칙을 따릅니다. 무엇을 커스터마이즈할 수 있는지는 워크플로의 `customize.toml`을 읽으세요.
|
||||||
|
|
||||||
|
### 활성화 순서
|
||||||
|
|
||||||
|
커스터마이즈 가능한 워크플로는 후크가 언제 실행되는지 알 수 있도록 고정된 순서로 활성화됩니다.
|
||||||
|
|
||||||
|
1. `[workflow]` 블록 해석(기본값 → 팀 → 사용자 병합)
|
||||||
|
2. `activation_steps_prepend`를 순서대로 실행
|
||||||
|
3. 실행의 기반 컨텍스트로 `persistent_facts` 로드
|
||||||
|
4. 설정(`_bmad/bmm/config.yaml`) 로드 및 표준 변수(프로젝트 이름, 언어, 경로, 날짜) 해석
|
||||||
|
5. 사용자에게 인사
|
||||||
|
6. `activation_steps_append`를 순서대로 실행
|
||||||
|
|
||||||
|
6단계 이후 워크플로 본문이 시작됩니다. 인사를 개인화하기 전에 컨텍스트가 필요하면 `activation_steps_prepend`를 사용하고, 설정이 무거워 사용자에게 인사를 먼저 보여주고 싶다면 `activation_steps_append`를 사용하세요.
|
||||||
|
|
||||||
|
### 현재 초기 단계의 범위
|
||||||
|
|
||||||
|
커스터마이징은 점진적으로 출시됩니다. 위에서 문서화한 `activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`는 모든 커스터마이즈 가능한 워크플로가 노출하는 **기준 영역**이며 버전 간 안정적으로 유지됩니다. 오늘 당장 사전/사후 단계 주입, 기반 컨텍스트 고정, 후속 작업 트리거 같은 큰 단위의 제어를 제공합니다.
|
||||||
|
|
||||||
|
시간이 지나면 개별 워크플로가 실제로 하는 일에 맞춘 **더 세밀한 커스터마이징 지점**을 노출할 것입니다. 단계별 토글, 단계 플래그, 출력 템플릿 경로, 리뷰 게이트 같은 것들입니다. 그런 항목이 추가되면 기준 필드를 대체하지 않고 그 위에 쌓이므로 오늘 작성한 커스터마이징은 계속 동작합니다.
|
||||||
|
|
||||||
|
아직 노출되지 않은 세밀한 조절점이 필요하다면 `activation_steps_*`와 `persistent_facts`로 동작을 조정하거나, 원하는 커스터마이징 지점을 구체적으로 설명하는 이슈를 열어 주세요.
|
||||||
|
|
||||||
|
## 중앙 설정
|
||||||
|
|
||||||
|
스킬별 `customize.toml`은 **깊은 동작**(후크, 메뉴, persistent_facts, 단일 에이전트/워크플로의 페르소나 오버라이드)을 다룹니다. 별도 영역은 **공유 상태**를 다룹니다. 설치 답변과 `bmad-party-mode`, `bmad-retrospective`, `bmad-advanced-elicitation` 같은 외부 스킬이 사용하는 에이전트 명단입니다. 이 영역은 프로젝트 루트의 네 TOML 파일에 있습니다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
_bmad/config.toml (설치 프로그램 소유) 팀 범위: 설치 답변 + 에이전트 명단
|
||||||
|
_bmad/config.user.toml (설치 프로그램 소유) 사용자 범위: user_name, 언어, 스킬 수준
|
||||||
|
_bmad/custom/config.toml (사람이 작성) 팀 오버라이드(git에 커밋)
|
||||||
|
_bmad/custom/config.user.toml (사람이 작성) 개인 오버라이드(git에서 무시)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4계층 병합
|
||||||
|
|
||||||
|
```text
|
||||||
|
우선순위 1(승리): _bmad/custom/config.user.toml
|
||||||
|
우선순위 2: _bmad/custom/config.toml
|
||||||
|
우선순위 3: _bmad/config.user.toml
|
||||||
|
우선순위 4(기반): _bmad/config.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
스킬별 커스터마이즈와 같은 구조 규칙을 사용합니다. 스칼라 값 오버라이드, 테이블 깊은 병합, `code`/`id` 키 기반 배열 병합, 그 밖의 배열 추가입니다.
|
||||||
|
|
||||||
|
### 무엇이 어디에 있나요?
|
||||||
|
|
||||||
|
설치 프로그램은 `module.yaml`의 각 프롬프트에 선언된 `scope:`에 따라 답변을 나눕니다.
|
||||||
|
|
||||||
|
- `[core]`와 `[modules.<code>]` 섹션 - 설치 답변입니다. `team` 범위는 `_bmad/config.toml`에, `user` 범위는 `_bmad/config.user.toml`에 들어갑니다.
|
||||||
|
- `[agents.<code>]` - 각 모듈의 `module.yaml` `agents:` 블록에서 추출한 에이전트 핵심 정보(코드, 이름, 직함, 아이콘, 설명, 팀)입니다. 항상 팀 범위입니다.
|
||||||
|
|
||||||
|
### 편집 규칙
|
||||||
|
|
||||||
|
- `_bmad/config.toml`과 `_bmad/config.user.toml`은 **설치할 때마다 재생성**됩니다. 읽기 전용 출력으로 취급하세요. 직접 수정하면 다음 설치에서 덮어쓰입니다. 설치 답변을 지속적으로 바꾸려면 설치 프로그램을 다시 실행하거나 `_bmad/custom/config.toml`에서 값을 덮어쓰세요.
|
||||||
|
- `_bmad/custom/config.toml`과 `_bmad/custom/config.user.toml`은 설치 프로그램이 **절대 건드리지 않습니다**. 커스텀 에이전트, 에이전트 설명자 오버라이드, 팀 강제 설정, 설치 답변과 무관하게 고정하려는 값을 넣는 올바른 영역입니다.
|
||||||
|
|
||||||
|
### 예시 - 에이전트 리브랜딩
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/config.toml (git에 커밋, 모든 개발자에게 적용)
|
||||||
|
|
||||||
|
[agents.bmad-agent-pm]
|
||||||
|
description = "헬스케어 PM - 규제를 의식하고 이해관계자 중심이며, FDA 관점의 질문을 먼저 던집니다."
|
||||||
|
icon = "🏥"
|
||||||
|
```
|
||||||
|
|
||||||
|
병합 스크립트가 설치 프로그램이 작성한 `[agents.bmad-agent-pm]` 위로 병합합니다. `bmad-party-mode`와 명단을 사용하는 스킬은 새 설명을 자동으로 사용합니다.
|
||||||
|
|
||||||
|
### 예시 - 가상 에이전트 추가
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/config.user.toml (개인용, git에서 무시)
|
||||||
|
|
||||||
|
[agents.kirk]
|
||||||
|
team = "startrek"
|
||||||
|
name = "Captain James T. Kirk"
|
||||||
|
title = "우주선 선장"
|
||||||
|
icon = "🖖"
|
||||||
|
description = "대담하고 규칙을 굽힐 줄 아는 지휘관입니다. 극적인 쉼표를 두고 말하며 지휘의 무게를 소리 내어 생각합니다."
|
||||||
|
```
|
||||||
|
|
||||||
|
스킬 폴더가 없어도 핵심 정보만으로 파티 모드가 Kirk를 하나의 목소리로 생성할 수 있습니다. `team` 필드로 필터링해 엔터프라이즈 승무원만 라운드테이블에 초대할 수 있습니다.
|
||||||
|
|
||||||
|
### 예시 - 모듈 설치 설정 오버라이드
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/config.toml
|
||||||
|
|
||||||
|
[modules.bmm]
|
||||||
|
planning_artifacts = "/shared/org-planning-artifacts"
|
||||||
|
```
|
||||||
|
|
||||||
|
오버라이드는 각 개발자가 로컬 설치 중 답한 값보다 우선합니다. 팀 관례를 고정할 때 유용합니다.
|
||||||
|
|
||||||
|
### 어떤 영역을 사용할까요?
|
||||||
|
|
||||||
|
| 필요 | 사용 |
|
||||||
|
| --- | --- |
|
||||||
|
| 모든 개발 워크플로에 MCP 도구 호출 추가 | 스킬별: `_bmad/custom/bmad-agent-dev.toml` `persistent_facts` |
|
||||||
|
| 에이전트에 메뉴 항목 추가 | 스킬별: `_bmad/custom/bmad-agent-{role}.toml` `[[agent.menu]]` |
|
||||||
|
| 워크플로의 출력 템플릿 교체 | 스킬별: `_bmad/custom/{workflow}.toml` 스칼라 값 오버라이드 |
|
||||||
|
| 에이전트 공개 설명자 리브랜딩 | **중앙**: `_bmad/custom/config.toml` `[agents.<code>]` |
|
||||||
|
| 커스텀 또는 가상 에이전트를 명단에 추가 | **중앙**: `_bmad/custom/config.*.toml` 새 `[agents.<code>]` 항목 |
|
||||||
|
| 팀 강제 설치 설정 고정 | **중앙**: `_bmad/custom/config.toml` `[modules.<code>]` 또는 `[core]` |
|
||||||
|
|
||||||
|
필요에 따라 한 프로젝트에서 두 영역을 함께 사용하세요.
|
||||||
|
|
||||||
|
## 실전 예시
|
||||||
|
|
||||||
|
에이전트가 실행하는 모든 워크플로에 걸친 동작 조정, 조직 관례 강제, Confluence와 Jira로 출력 게시, 에이전트 명단 커스터마이즈, 출력 템플릿 교체 같은 엔터프라이즈 지향 레시피는 [조직을 위해 BMad 확장하기](./expand-bmad-for-your-org.md)를 참고하세요.
|
||||||
|
|
||||||
|
## 문제 해결
|
||||||
|
|
||||||
|
**커스터마이징이 보이지 않나요?**
|
||||||
|
|
||||||
|
- 파일이 `_bmad/custom/`에 올바른 스킬 이름으로 있는지 확인하세요
|
||||||
|
- TOML 문법을 확인하세요. 문자열은 따옴표가 필요하고, 테이블 헤더는 `[section]`, 테이블 배열은 `[[section]]`입니다. 테이블의 스칼라 값 또는 배열 키는 해당 테이블의 `[[subtables]]`보다 먼저 와야 합니다
|
||||||
|
- 에이전트의 경우 커스터마이징은 `[agent]` 아래에 있습니다. 그 헤더 아래에 쓴 필드는 다른 테이블 헤더가 시작될 때까지 `agent`에 속합니다
|
||||||
|
- `agent.name`과 `agent.title`은 읽기 전용입니다. 오버라이드해도 효과가 없습니다
|
||||||
|
|
||||||
|
**업데이트가 커스터마이징을 망가뜨렸나요?**
|
||||||
|
|
||||||
|
- 전체 `customize.toml`을 오버라이드 파일에 복사했나요? **하지 마세요.** 오버라이드 파일은 바꾸는 필드만 포함해야 합니다. 전체 복사는 옛 기본값을 고정하고 릴리스마다 조용히 어긋납니다. 오버라이드를 변경분만 남기도록 줄이세요.
|
||||||
|
|
||||||
|
**무엇을 커스터마이즈할 수 있는지 봐야 하나요?**
|
||||||
|
|
||||||
|
- `bmad-customize` 스킬을 실행하세요. 프로젝트에 설치된 모든 커스터마이즈 가능한 스킬을 열거하고, 이미 오버라이드가 있는 항목을 보여주며, 추가 또는 업데이트 과정을 안내합니다
|
||||||
|
- 또는 스킬의 `customize.toml`을 직접 읽으세요. `name`과 `title`을 제외하고 모든 필드가 커스터마이즈 가능합니다
|
||||||
|
|
||||||
|
**초기화가 필요하나요?**
|
||||||
|
|
||||||
|
- `_bmad/custom/`에서 오버라이드 파일을 삭제하세요. 스킬은 내장 기본값으로 돌아갑니다
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
---
|
||||||
|
title: '기존 프로젝트'
|
||||||
|
description: 기존 코드베이스에서 BMad Method를 사용하는 방법
|
||||||
|
sidebar:
|
||||||
|
order: 7
|
||||||
|
---
|
||||||
|
|
||||||
|
기존 프로젝트와 레거시 코드베이스에서 작업할 때 BMad Method를 효과적으로 사용하세요.
|
||||||
|
|
||||||
|
이 가이드는 BMad Method로 기존 프로젝트에 적응하는 핵심 워크플로를 다룹니다.
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
|
||||||
|
- BMad Method 설치(`npx bmad-method install`)
|
||||||
|
- 작업하려는 기존 코드베이스
|
||||||
|
- AI 기반 IDE(Claude Code 또는 Cursor) 접근 권한
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 1단계: 완료된 계획 산출물 정리
|
||||||
|
|
||||||
|
BMad 과정으로 모든 PRD 에픽과 스토리를 완료했다면 해당 파일을 정리하세요. 필요하다면 보관하거나 삭제하거나 버전 기록에 의존하세요. 다음 위치에 이 파일들을 계속 두지 마세요.
|
||||||
|
|
||||||
|
- `docs/`
|
||||||
|
- `_bmad-output/planning-artifacts/`
|
||||||
|
- `_bmad-output/implementation-artifacts/`
|
||||||
|
|
||||||
|
## 2단계: 프로젝트 컨텍스트 만들기
|
||||||
|
|
||||||
|
:::tip[기존 프로젝트에 권장]
|
||||||
|
`project-context.md`를 생성해 기존 코드베이스의 패턴과 규칙을 포착하세요. 이렇게 하면 변경을 구현할 때 AI 에이전트가 이미 자리 잡은 관례를 따릅니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
프로젝트 컨텍스트 생성 워크플로를 실행합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bmad-generate-project-context
|
||||||
|
```
|
||||||
|
|
||||||
|
이 워크플로는 코드베이스를 스캔해 다음을 식별합니다.
|
||||||
|
|
||||||
|
- 기술 스택과 버전
|
||||||
|
- 코드 구성 패턴
|
||||||
|
- 명명 규칙
|
||||||
|
- 테스트 접근 방식
|
||||||
|
- 프레임워크별 패턴
|
||||||
|
|
||||||
|
생성된 파일을 검토하고 다듬거나, 원한다면 `_bmad-output/project-context.md`에 직접 만들 수 있습니다.
|
||||||
|
|
||||||
|
[프로젝트 컨텍스트 자세히 알아보기](../explanation/project-context.md)
|
||||||
|
|
||||||
|
## 3단계: 품질 높은 프로젝트 문서 유지
|
||||||
|
|
||||||
|
`docs/` 폴더에는 프로젝트를 정확하게 나타내는 간결하고 잘 구성된 문서가 있어야 합니다.
|
||||||
|
|
||||||
|
- 의도와 비즈니스 근거
|
||||||
|
- 비즈니스 규칙
|
||||||
|
- 아키텍처
|
||||||
|
- 그 밖의 관련 프로젝트 정보
|
||||||
|
|
||||||
|
복잡한 프로젝트라면 `bmad-document-project` 워크플로 사용을 고려하세요. 전체 프로젝트를 스캔하고 실제 현재 상태를 문서화하는 실행 시 선택 가능한 변형을 제공합니다.
|
||||||
|
|
||||||
|
## 4단계: 도움 받기
|
||||||
|
|
||||||
|
### BMad 도움말: 시작점
|
||||||
|
|
||||||
|
**다음에 무엇을 해야 할지 확실하지 않을 때 언제든 `bmad-help`를 실행하세요.** 이 지능형 가이드는 다음을 수행합니다.
|
||||||
|
|
||||||
|
- 프로젝트를 검사해 이미 완료된 작업을 확인합니다
|
||||||
|
- 설치된 모듈을 기준으로 선택지를 보여줍니다
|
||||||
|
- 자연어 질문을 이해합니다
|
||||||
|
|
||||||
|
```
|
||||||
|
bmad-help 기존 Rails 앱이 있는데 어디서 시작하면 좋나요?
|
||||||
|
bmad-help 빠른 흐름과 전체 BMad Method는 무엇이 다른가요?
|
||||||
|
bmad-help 사용할 수 있는 워크플로를 보여 주세요
|
||||||
|
```
|
||||||
|
|
||||||
|
BMad 도움말은 **모든 워크플로 끝에서 자동으로 실행되어** 다음에 무엇을 해야 할지 명확히 안내합니다.
|
||||||
|
|
||||||
|
### 접근 방식 선택
|
||||||
|
|
||||||
|
변경 범위에 따라 두 가지 주요 선택지가 있습니다.
|
||||||
|
|
||||||
|
| 범위 | 권장 접근 방식 |
|
||||||
|
| --- | --- |
|
||||||
|
| **작은 업데이트나 추가** | `bmad-quick-dev`를 실행해 의도 정리, 계획, 구현, 리뷰를 하나의 워크플로에서 처리합니다. 전체 4단계 BMad Method는 과할 가능성이 큽니다. |
|
||||||
|
| **큰 변경이나 추가** | 필요한 만큼만 엄격하게 적용하면서 BMad Method로 시작합니다. |
|
||||||
|
|
||||||
|
### PRD 작성 중
|
||||||
|
|
||||||
|
제품 개요를 만들거나 바로 PRD로 들어갈 때 에이전트가 다음을 하도록 확인하세요.
|
||||||
|
|
||||||
|
- 기존 프로젝트 문서를 찾고 분석합니다
|
||||||
|
- 현재 시스템에 대한 적절한 컨텍스트를 읽습니다
|
||||||
|
|
||||||
|
에이전트를 명시적으로 안내할 수 있지만 목표는 새 기능이 기존 시스템과 잘 통합되게 하는 것입니다.
|
||||||
|
|
||||||
|
### UX 고려 사항
|
||||||
|
|
||||||
|
UX 작업은 선택 사항입니다. 결정 기준은 프로젝트에 UX가 있는지가 아니라 다음입니다.
|
||||||
|
|
||||||
|
- UX 변경을 작업할 예정인지
|
||||||
|
- 의미 있는 새 UX 디자인이나 패턴이 필요한지
|
||||||
|
|
||||||
|
만족스러운 기존 화면을 단순히 업데이트하는 정도라면 전체 UX 과정은 필요하지 않습니다.
|
||||||
|
|
||||||
|
### 아키텍처 고려 사항
|
||||||
|
|
||||||
|
아키텍처를 진행할 때 아키텍트가 다음을 하도록 확인하세요.
|
||||||
|
|
||||||
|
- 적절한 문서 파일을 사용합니다
|
||||||
|
- 기존 코드베이스를 스캔합니다
|
||||||
|
|
||||||
|
여기서는 특히 주의하세요. 이미 있는 것을 다시 만들거나 기존 아키텍처와 어긋나는 결정을 방지해야 합니다.
|
||||||
|
|
||||||
|
## 더 보기
|
||||||
|
|
||||||
|
- **[빠른 수정](./quick-fixes.md)** - 버그 수정과 임시 변경
|
||||||
|
- **[기존 프로젝트 FAQ](../explanation/established-projects-faq.md)** - 기존 프로젝트 작업에 대한 일반 질문
|
||||||
|
|
@ -0,0 +1,332 @@
|
||||||
|
---
|
||||||
|
title: '조직을 위해 BMad 확장하기'
|
||||||
|
description: 포크 없이 BMad를 재구성하는 여섯 가지 커스터마이징 패턴 - 에이전트 전반 규칙, 워크플로 관례, 외부 게시, 템플릿 교체, 에이전트 명단 변경, 고급 통합 패턴
|
||||||
|
sidebar:
|
||||||
|
order: 11
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad의 커스터마이징 영역을 사용하면 설치된 파일을 수정하거나 스킬을 포크하지 않고도 조직에 맞게 동작을 바꿀 수 있습니다. 이 가이드는 대부분의 엔터프라이즈 요구를 다루는 여섯 가지 레시피를 소개합니다.
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
|
||||||
|
- 프로젝트에 BMad 설치([BMad 설치 방법](./install-bmad.md) 참고)
|
||||||
|
- 커스터마이징 모델 이해([BMad 커스터마이징 방법](./customize-bmad.md) 참고)
|
||||||
|
- PATH의 Python 3.11+(병합 스크립트용, stdlib만 사용하며 `pip install` 불필요)
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::tip[이 레시피 적용하기]
|
||||||
|
아래 **스킬별 레시피**(레시피 1-4)는 `bmad-customize` 스킬을 실행하고 의도를 설명해 적용할 수 있습니다. 스킬이 적절한 영역을 고르고 오버라이드 파일을 작성하고 병합을 검증합니다. 레시피 5(에이전트 명단에 대한 중앙 설정 오버라이드)는 v1 스킬 범위 밖이라 직접 작성해야 합니다. 이 문서의 레시피는 *무엇을* 오버라이드할지의 참고 기준이고, `bmad-customize`는 에이전트/워크플로 영역의 *방법*을 처리합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 3계층 모델
|
||||||
|
|
||||||
|
레시피를 고르기 전에 오버라이드가 어디에 들어가는지 알아두세요.
|
||||||
|
|
||||||
|
| 계층 | 오버라이드 위치 | 범위 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| **에이전트**(예: Amelia, Mary, John) | `_bmad/custom/bmad-agent-{role}.toml`의 `[agent]` 섹션 | 에이전트를 통해 실행되는 **모든 워크플로**에 페르소나와 함께 이동 |
|
||||||
|
| **워크플로**(예: 제품 개요, PRD 생성) | `_bmad/custom/{workflow-name}.toml`의 `[workflow]` 섹션 | 해당 워크플로 실행에만 적용 |
|
||||||
|
| **중앙 설정** | `_bmad/custom/config.toml`의 `[agents.*]`, `[core]`, `[modules.*]` | 에이전트 명단(파티 모드, 회고, 도출에서 누가 가능한지), 조직 전체로 고정된 설치 시 설정 |
|
||||||
|
|
||||||
|
경험칙: 규칙이 엔지니어의 모든 개발 작업에 적용되어야 한다면 **개발자 에이전트**를 커스터마이즈하세요. 제품 개요를 쓸 때만 적용된다면 **제품 개요 워크플로**를 커스터마이즈하세요. *방에 누가 있는지*를 바꾸는 일(에이전트 이름 변경, 커스텀 목소리 추가, 공유 산출물 경로 강제)은 **중앙 설정**을 편집하세요.
|
||||||
|
|
||||||
|
## 레시피 1: 에이전트가 실행하는 모든 워크플로에 규칙 적용
|
||||||
|
|
||||||
|
**사용 사례:** 에이전트를 통해 실행되는 모든 워크플로가 같은 도구 사용과 외부 시스템 통합 규칙을 상속하도록 표준화합니다. 가장 영향력이 큰 패턴입니다.
|
||||||
|
|
||||||
|
**예시: Amelia 개발자 에이전트가 라이브러리 문서는 항상 Context7을 사용하고, 에픽 목록에 스토리가 없으면 Linear를 대체 경로로 사용합니다.**
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-agent-dev.toml
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
|
||||||
|
# 모든 활성화에 적용됩니다. Amelia가 실행하는 모든 스킬
|
||||||
|
# 스토리 구현, 빠른 개발, 스토리 생성, 코드 리뷰, QA 생성으로 이어집니다.
|
||||||
|
persistent_facts = [
|
||||||
|
"라이브러리 문서(React, TypeScript, Zod, Prisma 등)를 찾을 때는 학습 데이터 지식에 의존하기 전에 context7 MCP 도구(`mcp__context7__resolve_library_id`, 이후 `mcp__context7__get_library_docs`)를 호출하세요. 최신 문서가 기억된 API보다 우선합니다.",
|
||||||
|
"스토리 참조를 {planning_artifacts}/epics-and-stories.md에서 찾을 수 없으면 사용자에게 확인을 요청하기 전에 스토리 ID나 제목으로 Linear의 `mcp__linear__search_issues`를 검색하세요. Linear가 일치 항목을 반환하면 권위 있는 스토리 소스로 취급하세요.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**왜 동작하나요:** 두 문장이 조직의 모든 개발 워크플로를 재구성합니다. 워크플로마다 반복하지 않아도 되고 소스 변경도 없습니다. 저장소를 가져오는 모든 새 엔지니어가 자동으로 관례를 상속합니다.
|
||||||
|
|
||||||
|
**팀 파일 vs 개인 파일:**
|
||||||
|
|
||||||
|
- `bmad-agent-dev.toml`: git에 커밋하고 팀 전체에 적용합니다
|
||||||
|
- `bmad-agent-dev.user.toml`: git에서 무시되며 개인 선호를 위에 덧씌웁니다
|
||||||
|
|
||||||
|
## 레시피 2: 특정 워크플로 안에서 조직 관례 강제
|
||||||
|
|
||||||
|
**사용 사례:** 워크플로 출력의 *내용*이 컴플라이언스, 감사, 후속 사용자의 요구를 만족하도록 만듭니다.
|
||||||
|
|
||||||
|
**예시: 모든 제품 개요에 컴플라이언스 필드가 포함되고 에이전트가 조직의 게시 관례를 압니다.**
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-product-brief.toml
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
|
||||||
|
persistent_facts = [
|
||||||
|
"모든 개요에는 '소유자', '대상 릴리스', '보안 리뷰 상태' 필드가 포함되어야 합니다.",
|
||||||
|
"비상업용 개요(내부 도구, 리서치 프로젝트)도 사용자 가치 섹션은 포함해야 하지만 시장 차별화는 생략할 수 있습니다.",
|
||||||
|
"file:{project-root}/docs/enterprise/brief-publishing-conventions.md",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**일어나는 일:** 사실 목록은 워크플로 활성화 3단계에서 로드됩니다. 에이전트가 제품 개요를 작성할 때 필수 필드와 엔터프라이즈 관례 문서를 알고 있습니다. 기본값(`file:{project-root}/**/project-context.md`)도 추가 방식이므로 계속 로드됩니다.
|
||||||
|
|
||||||
|
## 레시피 3: 완료된 출력을 외부 시스템에 게시
|
||||||
|
|
||||||
|
**사용 사례:** 워크플로가 출력을 만든 뒤 엔터프라이즈 기록 시스템(Confluence, Notion, SharePoint)에 자동 게시하고 후속 작업(Jira, Linear, Asana)을 엽니다.
|
||||||
|
|
||||||
|
**예시: 제품 개요를 Confluence에 자동 게시하고 선택적으로 Jira 에픽 생성을 제안합니다.**
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-product-brief.toml
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
|
||||||
|
# 종료 후크입니다. 스칼라 값 오버라이드는 빈 기본값 전체를 교체합니다.
|
||||||
|
on_complete = """
|
||||||
|
게시하고 후속 작업을 제안하세요:
|
||||||
|
|
||||||
|
1. 이전 단계에서 확정된 개요 파일 경로를 읽습니다.
|
||||||
|
2. 다음 인자로 `mcp__atlassian__confluence_create_page`를 호출합니다:
|
||||||
|
- space: "PRODUCT"
|
||||||
|
- parent: "Product Briefs"
|
||||||
|
- title: 개요 제목
|
||||||
|
- body: 개요의 Markdown 내용
|
||||||
|
반환된 페이지 URL을 기록합니다.
|
||||||
|
3. 사용자에게 "개요가 Confluence에 게시되었습니다: <url>"이라고 알립니다.
|
||||||
|
4. "이 개요에 대한 Jira 에픽을 지금 만들까요?"라고 묻습니다.
|
||||||
|
5. 사용자가 동의하면 다음 인자로 `mcp__atlassian__jira_create_issue`를 호출합니다:
|
||||||
|
- type: "Epic"
|
||||||
|
- project: "PROD"
|
||||||
|
- summary: 개요 제목
|
||||||
|
- description: 짧은 요약과 Confluence 페이지 링크
|
||||||
|
에픽 키와 URL을 보고합니다.
|
||||||
|
6. 동의하지 않으면 깔끔하게 종료합니다.
|
||||||
|
|
||||||
|
어느 MCP 도구든 실패하면 실패를 보고하고 개요 경로를 출력한 뒤
|
||||||
|
사용자에게 수동 게시를 요청하세요.
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
**왜 `activation_steps_append`가 아니라 `on_complete`인가요:** `on_complete`는 워크플로의 주 출력이 작성된 뒤 마지막 단계에서 정확히 한 번 실행됩니다. 산출물 게시에는 이 시점이 맞습니다. `activation_steps_append`는 워크플로가 일을 시작하기 전에 매 활성화마다 실행됩니다.
|
||||||
|
|
||||||
|
**절충점:**
|
||||||
|
|
||||||
|
- **Confluence 게시 작업은 비파괴적**이며 완료 시 항상 실행됩니다
|
||||||
|
- **Jira 에픽 생성은 팀 전체에 보이고 스프린트 계획 신호를 만들기 때문에** 사용자 확인으로 통제합니다
|
||||||
|
- **안전한 대체 경로:** MCP 도구가 실패하면 조용히 출력을 버리지 말고 사용자에게 맡깁니다
|
||||||
|
|
||||||
|
## 레시피 4: 자체 출력 템플릿으로 교체
|
||||||
|
|
||||||
|
**사용 사례:** 기본 출력 구조가 조직의 예상 형식과 맞지 않거나, 같은 저장소의 서로 다른 조직이 다른 템플릿을 필요로 합니다.
|
||||||
|
|
||||||
|
**예시: product-brief 워크플로가 엔터프라이즈 소유 템플릿을 보게 합니다.**
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-product-brief.toml
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
brief_template = "{project-root}/docs/enterprise/brief-template.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
**작동 방식:** 워크플로의 `customize.toml`은 `brief_template = "resources/brief-template.md"`(스킬 루트 기준 경로)를 제공합니다. 오버라이드는 `{project-root}` 아래 파일을 가리키므로 에이전트가 제공된 템플릿 대신 당신의 템플릿을 4단계에서 읽습니다.
|
||||||
|
|
||||||
|
**템플릿 작성 팁:**
|
||||||
|
|
||||||
|
- 템플릿은 `{project-root}/docs/` 또는 `{project-root}/_bmad/custom/templates/`에 두어 오버라이드 파일과 함께 버전 관리합니다
|
||||||
|
- 제공된 템플릿과 같은 구조 관례(섹션 헤딩, 프런트매터)를 사용하세요. 에이전트는 그 구조에 적응합니다
|
||||||
|
- 다중 조직 저장소에서는 `.user.toml`로 개별 팀이 커밋된 팀 파일을 건드리지 않고 자체 템플릿을 가리키게 할 수 있습니다
|
||||||
|
|
||||||
|
## 레시피 5: 에이전트 명단 커스터마이즈
|
||||||
|
|
||||||
|
**사용 사례:** 소스를 수정하거나 포크하지 않고 `bmad-party-mode`, `bmad-retrospective`, `bmad-advanced-elicitation` 같은 명단 기반 스킬에서 *방에 누가 있는지* 바꿉니다. 세 가지 흔한 변형은 다음과 같습니다.
|
||||||
|
|
||||||
|
### 5a. BMad 에이전트를 조직 전체에서 리브랜딩
|
||||||
|
|
||||||
|
실제 에이전트마다 설치 프로그램이 `module.yaml`에서 합성한 설명자가 있습니다. 이를 오버라이드하면 명단을 사용하는 모든 스킬에서 목소리와 표현 방식을 바꿀 수 있습니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/config.toml (커밋됨 - 모든 개발자에게 적용)
|
||||||
|
|
||||||
|
[agents.bmad-agent-analyst]
|
||||||
|
description = "규제를 의식하는 비즈니스 분석가 Mary - Porter와 Minto의 사고법을 따르지만 FDA 감사 추적을 중시합니다. 사건 파일을 제시하는 포렌식 조사관처럼 말합니다."
|
||||||
|
```
|
||||||
|
|
||||||
|
파티 모드는 새 설명으로 Mary를 생성합니다. 분석가 활성화 자체는 Mary의 동작이 스킬별 `customize.toml`에 있으므로 정상 동작합니다. 이 오버라이드는 **외부 스킬이 Mary를 어떻게 인식하고 소개하는지**를 바꾸며, 내부 작업 방식은 바꾸지 않습니다.
|
||||||
|
|
||||||
|
### 5b. 가상 또는 커스텀 에이전트 추가
|
||||||
|
|
||||||
|
스킬 폴더 없이 전체 설명자만으로 명단 기반 기능에 충분합니다. 파티 모드나 브레인스토밍 세션에서 페르소나 다양성을 줄 때 유용합니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/config.user.toml (개인용 - git에서 무시)
|
||||||
|
|
||||||
|
[agents.spock]
|
||||||
|
team = "startrek"
|
||||||
|
name = "스팍 사령관"
|
||||||
|
title = "과학 장교"
|
||||||
|
icon = "🖖"
|
||||||
|
description = "논리를 우선하고 감정을 억제합니다. 관찰을 '흥미롭군요.'로 시작합니다. 절대 올림하지 않습니다. 직감에 의존하는 주장에 반대 관점을 제공합니다."
|
||||||
|
|
||||||
|
[agents.mccoy]
|
||||||
|
team = "startrek"
|
||||||
|
name = "레너드 맥코이 박사"
|
||||||
|
title = "수석 의무관"
|
||||||
|
icon = "⚕️"
|
||||||
|
description = "시골 의사의 따뜻함과 짧은 인내심을 지녔습니다. '제기랄 짐, 난 ___가 아니라 의사라고.' 윤리 중심으로 스팍의 균형을 잡습니다."
|
||||||
|
```
|
||||||
|
|
||||||
|
파티 모드에 "엔터프라이즈 승무원을 초대해 줘"라고 요청하면 `team = "startrek"`으로 필터링하고 스팍과 맥코이를 생성합니다. 요청하면 실제 BMad 에이전트(Mary, Amelia)도 같은 테이블에 앉을 수 있습니다.
|
||||||
|
|
||||||
|
### 5c. 팀 설치 설정 고정
|
||||||
|
|
||||||
|
설치 프로그램은 각 개발자에게 `planning_artifacts` 경로 같은 값을 묻습니다. 조직이 팀 전체에 하나의 답을 강제해야 한다면 중앙 설정에 고정하세요. 각 개발자의 로컬 프롬프트 답변은 해석 시점에 오버라이드됩니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/config.toml
|
||||||
|
|
||||||
|
[modules.bmm]
|
||||||
|
planning_artifacts = "{project-root}/shared/planning"
|
||||||
|
implementation_artifacts = "{project-root}/shared/implementation"
|
||||||
|
|
||||||
|
[core]
|
||||||
|
document_output_language = "English"
|
||||||
|
```
|
||||||
|
|
||||||
|
`user_name`, `communication_language`, `user_skill_level` 같은 개인 설정은 각 개발자의 `_bmad/config.user.toml` 아래에 둡니다. 팀 파일은 이를 건드리지 않는 것이 좋습니다.
|
||||||
|
|
||||||
|
**왜 중앙 설정인가요:** 에이전트별 파일은 *하나의* 에이전트가 활성화될 때 동작을 조정합니다. 중앙 설정은 명단을 사용하는 스킬이 명단을 조회할 때 *무엇을 보게 되는지*를 조정합니다. 어떤 에이전트가 존재하는지, 무엇이라고 불리는지, 어떤 팀에 속하는지, 저장소가 합의한 공유 설치 설정이 무엇인지입니다.
|
||||||
|
|
||||||
|
## IDE 세션 파일에 전역 규칙 보강
|
||||||
|
|
||||||
|
BMad 커스터마이징은 스킬이 활성화될 때 로드됩니다. 많은 IDE 도구는 스킬이 실행되기 전 **모든 세션 시작 시** 전역 지침 파일도 로드합니다(`CLAUDE.md`, `AGENTS.md`, `.cursor/rules/`, `.github/copilot-instructions.md` 등). BMad 스킬 밖에서도 지켜져야 하는 규칙은 거기에도 핵심만 반복하세요.
|
||||||
|
|
||||||
|
**중복해 둘 때:**
|
||||||
|
|
||||||
|
- 일반 채팅 대화(활성 스킬 없음)에서도 지켜야 할 만큼 중요한 규칙입니다
|
||||||
|
- 학습 데이터 기반 기본값이 모델을 다른 방향으로 끌 수 있어 이중 안전장치가 필요합니다
|
||||||
|
- 세션 파일을 부풀리지 않을 만큼 간결한 규칙입니다
|
||||||
|
|
||||||
|
**예시: 레시피 1의 dev 에이전트 규칙을 저장소의 `CLAUDE.md`에 한 줄로 보강.**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- 라이브러리 문서를 읽을 때는 학습 데이터 지식에 의존하기 전에
|
||||||
|
context7 MCP 도구(`mcp__context7__resolve_library_id` 이후
|
||||||
|
`mcp__context7__get_library_docs`)를 거칩니다. -->
|
||||||
|
```
|
||||||
|
|
||||||
|
한 문장이 매 세션에 로드됩니다. `bmad-agent-dev.toml` 커스터마이징과 짝을 이뤄 Amelia의 워크플로 안과 어시스턴트와의 임시 채팅 모두에 규칙을 적용합니다.
|
||||||
|
|
||||||
|
| 계층 | 범위 | 사용처 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| IDE 세션 파일(`CLAUDE.md` / `AGENTS.md`) | 모든 세션, 스킬 활성화 전 | BMad 밖에서도 살아야 하는 짧은 보편 규칙 |
|
||||||
|
| BMad 에이전트 커스터마이징 | 에이전트가 실행하는 모든 워크플로 | 에이전트 페르소나별 동작 |
|
||||||
|
| BMad 워크플로 커스터마이징 | 하나의 워크플로 실행 | 워크플로별 출력 형태, 게시 후크, 템플릿 |
|
||||||
|
| BMad 중앙 설정 | 에이전트 명단 + 공유 설치 설정 | 방에 누가 있고 팀이 어떤 공유 경로를 쓰는지 |
|
||||||
|
|
||||||
|
IDE 파일은 **간결하게** 유지하세요. 잘 고른 열두 줄이 긴 목록보다 효과적입니다. 모델은 이를 매 턴 읽고, 노이즈는 신호를 밀어냅니다.
|
||||||
|
|
||||||
|
## 레시피 6: 고급 통합 패턴
|
||||||
|
|
||||||
|
몇몇 BMad 워크플로는 레시피 1-5에서 다룬 기본을 넘어 더 풍부한 설정 영역을 노출합니다. 온디맨드 지식 소스, 자동 출력 게시, 완료 시점 문서 표준, 교체 가능한 템플릿 같은 패턴은 여러 워크플로에 걸쳐 나타납니다. 어떤 필드를 노출하는지는 워크플로의 `customize.toml`을 확인하세요. 아래 예시는 모든 필드를 노출하는 `bmad-prd`를 사용하지만, 같은 패턴은 해당 필드가 있는 어디서나 적용됩니다.
|
||||||
|
|
||||||
|
### 온디맨드 지식 소스(`external_sources`)
|
||||||
|
|
||||||
|
워크플로를 내부 지식 베이스, 경쟁사 데이터베이스, 컴플라이언스 참조에 연결합니다. 에이전트는 대화에서 일치하는 필요가 나타날 때만 온디맨드로 참조하고 선제적으로 호출하지 않습니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-prd.toml (external_sources를 노출하는 모든 워크플로에서 같은 패턴 사용)
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
external_sources = [
|
||||||
|
"사용자가 경쟁사나 시장 세그먼트를 언급하면 차별화 섹션 초안을 작성하기 전에 corp:competitive_db(category={project_name})를 조회하세요.",
|
||||||
|
"규제 도메인(헬스케어, 핀테크, 교육)에서는 도메인별 섹션 초안을 작성하기 전에 corp:compliance_reference를 참고하세요.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
각 항목은 MCP 도구 이름, 트리거 조건, 도구에 필요한 필드를 자연어로 지정합니다. 런타임에 도구가 없으면 워크플로는 표준 동작으로 돌아가고 공백을 알립니다.
|
||||||
|
|
||||||
|
### 자동 출력 게시(`external_handoffs`)
|
||||||
|
|
||||||
|
워크플로가 완료된 뒤 완성된 산출물을 외부 기록 시스템으로 보냅니다. 레시피 3의 `on_complete`와 달리 `external_handoffs`는 전용 추가 배열입니다. 팀 항목이 쌓이고 각 전달 작업은 도구가 없을 때 점진적 기능 저하와 함께 독립 실행됩니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-prd.toml (external_handoffs를 노출하는 모든 워크플로에서 같은 패턴 사용)
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
external_handoffs = [
|
||||||
|
"완료 후 corp:confluence_upload(space_key='PROD', parent_page='PRDs', label='prd', author={user_name})로 prd.md와 addendum.md를 Confluence에 업로드하세요. 반환된 페이지 URL을 기록하고 보여 주세요.",
|
||||||
|
"notion:create_page(database_id='abc123', title='PRD: ' + {project_name})로 Notion에도 복제하세요.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
지정된 도구가 없으면 전달 작업은 건너뛰고 표시됩니다. 로컬 파일은 항상 존재합니다.
|
||||||
|
|
||||||
|
### 완료 시점 문서 표준(`doc_standards`)
|
||||||
|
|
||||||
|
사람이 읽을 문서에 조직 작성 표준을 완료 시점에 적용합니다. 내용이 완료된 후, 사용자가 출력을 보기 전입니다. 각 항목은 `skill:`, `file:`, 일반 텍스트 지시문일 수 있으며 각 검토 단계는 병렬 서브에이전트로 실행됩니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-prd.toml (doc_standards를 노출하는 모든 워크플로에서 같은 패턴 사용)
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
doc_standards = [
|
||||||
|
"file:{project-root}/docs/enterprise/voice-and-tone.md",
|
||||||
|
"모든 날짜는 ISO 8601 형식(YYYY-MM-DD)을 사용해야 합니다.",
|
||||||
|
"'활용'을 사용한 곳은 모두 '사용'으로 바꾸세요.",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
`doc_standards`는 추가 배열입니다. 팀 항목은 워크플로가 제공하는 기본값 위에 쌓입니다. 넓은 구조 검토가 좁은 문장 검토보다 먼저 와야 합니다.
|
||||||
|
|
||||||
|
### 교체 가능한 템플릿과 체크리스트
|
||||||
|
|
||||||
|
구조화된 문서를 만드는 워크플로는 일반적으로 템플릿과 체크리스트 경로를 오버라이드 가능한 스칼라 값으로 노출합니다. `{project-root}` 아래 조직 소유 파일을 가리키면 소스를 수정하지 않고 다른 구조를 강제할 수 있습니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-prd.toml
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
# 규제 산업용 PRD 구조
|
||||||
|
prd_template = "{project-root}/docs/enterprise/prd-template-hipaa.md"
|
||||||
|
|
||||||
|
# 조직별 검증 기준
|
||||||
|
validation_checklist = "{project-root}/docs/enterprise/prd-checklist-regulated.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
에이전트는 템플릿이 정의한 구조에 적응합니다. 템플릿은 `{project-root}/docs/` 또는 `{project-root}/_bmad/custom/templates/` 아래에 두어 오버라이드 파일과 함께 버전 관리하세요. 다중 조직 저장소에서는 `.user.toml`로 개별 팀이 커밋된 팀 파일을 건드리지 않고 자체 템플릿을 가리키게 할 수 있습니다.
|
||||||
|
|
||||||
|
## 레시피 조합
|
||||||
|
|
||||||
|
여섯 레시피는 모두 조합됩니다. 현실적인 엔터프라이즈용 `bmad-product-brief` 오버라이드는 한 파일에서 `persistent_facts`(레시피 2), `on_complete`(레시피 3), `brief_template`(레시피 4)을 설정할 수 있습니다. 에이전트 수준 규칙(레시피 1)은 에이전트 이름의 별도 파일에 있고, 중앙 설정(레시피 5)은 공유 명단과 팀 설정을 고정하며, 고급 통합 패턴(레시피 6)은 외부 소스와 전달 작업을 설정합니다. 모든 계층은 나란히 적용됩니다.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-product-brief.toml (워크플로 수준)
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
persistent_facts = ["..."]
|
||||||
|
brief_template = "{project-root}/docs/enterprise/brief-template.md"
|
||||||
|
on_complete = """ ... """
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# _bmad/custom/bmad-agent-analyst.toml (에이전트 수준 - Mary가 product-brief를 실행)
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
persistent_facts = ["도메인이 헬스케어, 금융, 아동 데이터와 관련되면 항상 '규제 검토' 섹션을 포함하세요."]
|
||||||
|
```
|
||||||
|
|
||||||
|
결과: Mary는 페르소나 활성화에서 규제 리뷰 규칙을 로드합니다. 사용자가 제품 개요 메뉴 항목을 선택하면 워크플로는 자체 관례를 그 위에 로드하고 엔터프라이즈 템플릿에 작성한 뒤 완료 시 Confluence에 게시합니다. 모든 계층이 함께 작동하며 BMad 소스는 수정하지 않습니다.
|
||||||
|
|
||||||
|
## 문제 해결
|
||||||
|
|
||||||
|
**오버라이드가 적용되지 않나요?** 파일이 `_bmad/custom/` 아래 정확한 스킬 디렉터리 이름으로 있는지 확인하세요(예: `bmad-agent-dev.toml`, `bmad-dev.toml` 아님). [BMad 커스터마이징 방법](./customize-bmad.md)을 참고하세요.
|
||||||
|
|
||||||
|
**MCP 도구 이름을 모르겠나요?** 현재 세션에서 MCP 서버가 노출하는 정확한 이름을 사용하세요. 확실하지 않다면 Claude Code에 사용 가능한 MCP 도구 목록을 보여달라고 요청하세요. `persistent_facts`나 `on_complete`에 하드코딩한 이름은 MCP 서버가 연결되어 있지 않으면 동작하지 않습니다.
|
||||||
|
|
||||||
|
**패턴이 내 설정에 맞지 않나요?** 위 레시피는 예시입니다. 기반 메커니즘(3계층 병합, 구조 규칙, 에이전트가 여러 워크플로에 걸쳐 동작하는 방식)은 훨씬 많은 패턴을 지원합니다. 필요에 맞게 조합하세요.
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
---
|
||||||
|
title: 'BMad에 대한 답을 얻는 방법'
|
||||||
|
description: LLM을 사용해 BMad 관련 질문에 빠르게 답하기
|
||||||
|
sidebar:
|
||||||
|
order: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad의 내장 도움말, 소스 문서, 커뮤니티를 사용해 답을 얻으세요. 가장 빠른 방법부터 가장 꼼꼼한 방법까지 순서대로 소개합니다.
|
||||||
|
|
||||||
|
## 1. BMad 도움말에게 묻기
|
||||||
|
|
||||||
|
답을 얻는 가장 빠른 방법입니다. `bmad-help` 스킬은 AI 세션에서 바로 사용할 수 있으며 질문의 80% 이상을 처리합니다. 프로젝트를 검사하고 완료한 작업을 확인한 뒤 다음에 무엇을 해야 할지 알려줍니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
bmad-help SaaS 아이디어가 있고 기능도 모두 알고 있습니다. 어디서 시작하나요?
|
||||||
|
bmad-help UX 설계에는 어떤 선택지가 있나요?
|
||||||
|
bmad-help PRD 워크플로에서 막혔어요
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
플랫폼에 따라 `/bmad-help` 또는 `$bmad-help`도 사용할 수 있지만, 대부분은 `bmad-help`만으로 동작합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 2. 소스로 더 깊게 들어가기
|
||||||
|
|
||||||
|
BMad 도움말은 설치된 설정을 바탕으로 답합니다. BMad의 내부 구조, 역사, 아키텍처에 대한 질문이 있거나 설치 전에 BMad를 조사하고 있다면 AI가 소스를 직접 보게 하세요.
|
||||||
|
|
||||||
|
[BMAD-METHOD 저장소](https://github.com/bmad-code-org/BMAD-METHOD)를 복제하거나 열고 AI에게 질문하세요. 에이전트 기능이 있는 도구(Claude Code, Cursor, Windsurf 등)는 소스를 읽고 직접 답할 수 있습니다.
|
||||||
|
|
||||||
|
:::note[예시]
|
||||||
|
**Q:** "BMad로 무언가를 가장 빠르게 만드는 방법을 알려줘"
|
||||||
|
|
||||||
|
**A:** 빠른 흐름을 사용하세요. `bmad-quick-dev`를 실행하면 의도를 명확히 하고, 계획하고, 구현하고, 리뷰하고, 결과를 하나의 워크플로에서 제시합니다. 전체 계획 단계를 건너뜁니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
**더 좋은 답을 위한 팁:**
|
||||||
|
|
||||||
|
- **구체적으로 묻기** - "PRD 워크플로 3단계가 무엇을 하나요?"가 "PRD는 어떻게 작동하나요?"보다 좋습니다
|
||||||
|
- **놀라운 주장은 확인하기** - LLM은 가끔 틀립니다. 소스 파일을 확인하거나 Discord에서 물어보세요
|
||||||
|
|
||||||
|
### 에이전트를 쓰지 않는다면 문서 사이트 사용
|
||||||
|
|
||||||
|
AI가 로컬 파일을 읽을 수 없다면(ChatGPT, Claude.ai 등), 세션에 [llms-full.txt](https://bmad-code-org.github.io/BMAD-METHOD/llms-full.txt)를 가져오세요. BMad 문서의 단일 파일 스냅샷입니다.
|
||||||
|
|
||||||
|
## 3. 사람에게 묻기
|
||||||
|
|
||||||
|
BMad 도움말이나 소스로도 답을 얻지 못했다면, 이제 훨씬 더 좋은 질문을 갖게 된 것입니다.
|
||||||
|
|
||||||
|
| 채널 | 사용처 |
|
||||||
|
| --- | --- |
|
||||||
|
| `help-requests` 포럼 | 질문 |
|
||||||
|
| `#suggestions-feedback` | 아이디어와 기능 요청 |
|
||||||
|
|
||||||
|
**Discord:** [discord.gg/gk8jAdXWmj](https://discord.gg/gk8jAdXWmj)
|
||||||
|
|
||||||
|
**GitHub Issues:** [github.com/bmad-code-org/BMAD-METHOD/issues](https://github.com/bmad-code-org/BMAD-METHOD/issues)
|
||||||
|
|
||||||
|
_당신이_
|
||||||
|
_막힌 채_
|
||||||
|
_줄 서서_
|
||||||
|
_기다린다면_
|
||||||
|
_누구를 기다리나요?_
|
||||||
|
|
||||||
|
_소스는_
|
||||||
|
_이미 거기,_
|
||||||
|
_눈앞에 있습니다._
|
||||||
|
|
||||||
|
_AI에게_
|
||||||
|
_소스를 가리키고._
|
||||||
|
_풀어 주세요._
|
||||||
|
|
||||||
|
_읽고._
|
||||||
|
_말하고._
|
||||||
|
_물어보세요._
|
||||||
|
|
||||||
|
_내일까지_
|
||||||
|
_기다릴 이유가 있나요_
|
||||||
|
_오늘 이미_
|
||||||
|
_할 수 있는데?_
|
||||||
|
|
||||||
|
_—Claude_
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
---
|
||||||
|
title: 'BMad 설치 방법'
|
||||||
|
description: 로컬 개발, 팀, CI를 위해 BMad를 설치, 업데이트, 고정합니다
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
프로젝트에 BMad를 설정하려면 `npx bmad-method install`을 사용하세요. 하나의 명령으로 최초 설치, 업그레이드, 채널 전환, 스크립트 기반 CI 실행을 처리합니다. 이 페이지에서 그 전체를 다룹니다.
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
- BMad로 새 프로젝트를 시작합니다
|
||||||
|
- 기존 설치에 모듈을 추가하거나 제거합니다
|
||||||
|
- 모듈을 main 브랜치 최신 커밋으로 전환하거나 특정 릴리스에 고정합니다
|
||||||
|
- CI 파이프라인, Dockerfile, 엔터프라이즈 배포를 위해 설치를 스크립트화합니다
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
|
||||||
|
- **Node.js** 20.12+ (설치 프로그램에 필요)
|
||||||
|
- **Git** (외부 모듈 복제용)
|
||||||
|
- Claude Code 또는 Cursor 같은 **AI 도구**(지원 도구 목록은 `npx bmad-method install --list-tools`로 확인)
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 최초 설치(빠른 경로)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install
|
||||||
|
```
|
||||||
|
|
||||||
|
대화형 흐름은 다섯 가지를 묻습니다.
|
||||||
|
|
||||||
|
1. 설치 디렉터리(기본값은 현재 작업 디렉터리)
|
||||||
|
2. 설치할 모듈(core, bmm, bmb, cis, gds, tea 체크박스)
|
||||||
|
3. **"Ready to install (all stable)?"** - **Yes**를 선택하면 모든 외부 모듈의 최신 릴리스 태그를 사용합니다
|
||||||
|
4. 연동할 AI 도구/IDE(`claude-code`, `cursor` 등)
|
||||||
|
5. 모듈별 설정(이름, 언어, 출력 폴더)
|
||||||
|
|
||||||
|
기본값을 받아들이면 선택한 도구에 맞게 설정된 각 모듈의 최신 안정 릴리스가 설치됩니다.
|
||||||
|
|
||||||
|
:::tip[최신 사전 릴리스만 원하나요?]
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method@next install
|
||||||
|
```
|
||||||
|
|
||||||
|
core와 bmm의 더 새로운 스냅샷이 포함된 사전 릴리스 설치 프로그램을 실행합니다. 변화는 더 잦지만 개발과 릴리스 사이의 지연이 줄어듭니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 특정 버전 선택
|
||||||
|
|
||||||
|
디스크에 무엇이 설치되는지는 두 개의 독립 축으로 제어됩니다.
|
||||||
|
|
||||||
|
### 축 1: 외부 모듈 채널
|
||||||
|
|
||||||
|
bmb, cis, gds, tea, 커뮤니티 모듈 등 모든 외부 모듈은 세 채널 중 하나로 설치됩니다.
|
||||||
|
|
||||||
|
| 채널 | 설치되는 것 | 누가 선택하나 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `stable`(기본값) | 가장 높은 시맨틱 버전 릴리스 태그. `v2.0.0-alpha.1` 같은 사전 릴리스는 제외됩니다. | 대부분의 사용자 |
|
||||||
|
| `next` | 설치 시점의 main 브랜치 최신 커밋 | 기여자, 초기 채택자 |
|
||||||
|
| `pinned` | 지정한 특정 태그 | 엔터프라이즈 설치, CI 재현성 |
|
||||||
|
|
||||||
|
채널은 모듈마다 정할 수 있습니다. bmb는 `next`로 두고 cis는 `stable`로 둘 수 있습니다. 아래 플래그로 자유롭게 섞을 수 있습니다.
|
||||||
|
|
||||||
|
### 축 2: 설치 프로그램 바이너리 버전
|
||||||
|
|
||||||
|
`bmad-method` npm 패키지 자체에는 두 npm 배포 태그(dist-tag)가 있습니다.
|
||||||
|
|
||||||
|
| 명령 | 받는 것 |
|
||||||
|
| --- | --- |
|
||||||
|
| `npx bmad-method install`(`@latest`) | 최신 안정 설치 프로그램 릴리스 |
|
||||||
|
| `npx bmad-method@next install` | main에 푸시될 때마다 자동 배포되는 최신 사전 릴리스 설치 프로그램 |
|
||||||
|
|
||||||
|
**설치 프로그램 바이너리가 core와 bmm 버전을 결정합니다.** 이 두 모듈은 별도 저장소에서 복제되지 않고 설치 프로그램 패키지 안에 번들됩니다.
|
||||||
|
|
||||||
|
### core와 bmm에 자체 채널이 없는 이유
|
||||||
|
|
||||||
|
두 모듈은 실행한 설치 프로그램 바이너리에 묶여 있습니다.
|
||||||
|
|
||||||
|
- `npx bmad-method install` → 최신 안정 core 및 bmm
|
||||||
|
- `npx bmad-method@next install` → 사전 릴리스 core 및 bmm
|
||||||
|
- `node /path/to/local-checkout/tools/installer/bmad-cli.js install` → 로컬 체크아웃의 내용
|
||||||
|
|
||||||
|
`--pin bmm=v6.3.0`과 `--next=bmm`은 번들 모듈에는 효과가 없고, 시도하면 설치 프로그램이 경고합니다. 향후 릴리스에서 bmm가 설치 프로그램 패키지에서 분리되면 bmb처럼 적절한 채널 선택기를 갖게 됩니다.
|
||||||
|
|
||||||
|
## 기존 설치 업데이트
|
||||||
|
|
||||||
|
이미 `_bmad/`가 있는 디렉터리에서 `npx bmad-method install`을 실행하면 메뉴가 나타납니다.
|
||||||
|
|
||||||
|
| 실제 메뉴 선택 | 하는 일 |
|
||||||
|
| --- | --- |
|
||||||
|
| **Quick Update** | 기존 설정으로 설치를 다시 실행합니다. 파일을 새로 고치고, 안정 채널의 패치와 마이너 업그레이드를 적용하며, 메이저 업그레이드는 거부합니다. 빠르고 비대화형입니다. |
|
||||||
|
| **Modify Install** | 전체 대화형 흐름입니다. 모듈을 추가/제거하고, 설정을 다시 구성하고, 기존 모듈 채널을 검토하고 전환할 수 있습니다. |
|
||||||
|
|
||||||
|
### 업그레이드 프롬프트
|
||||||
|
|
||||||
|
`Modify`가 `stable`에 설치된 모듈의 새 안정 태그를 감지하면 변경 폭을 분류하고 그에 맞게 묻습니다.
|
||||||
|
|
||||||
|
| 업그레이드 유형 | 예시 | 기본값 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 패치 | v1.7.0 → v1.7.1 | `Y` |
|
||||||
|
| 마이너 | v1.7.0 → v1.8.0 | `Y` |
|
||||||
|
| 메이저 | v1.7.0 → v2.0.0 | **`N`** |
|
||||||
|
|
||||||
|
메이저 업그레이드는 호환성 깨짐이 예상치 못한 "불안정"으로 나타나는 경우가 많기 때문에 기본값이 `N`입니다. 프롬프트에는 변경 내용을 읽을 수 있는 GitHub 릴리스 노트 URL이 포함됩니다.
|
||||||
|
|
||||||
|
`--yes`에서는 패치와 마이너 업그레이드가 자동 적용됩니다. 메이저 업그레이드는 고정된 채로 유지됩니다. 비대화형으로 수락하려면 `--pin <code>=<new-tag>`를 전달하세요.
|
||||||
|
|
||||||
|
### 모듈 채널 전환
|
||||||
|
|
||||||
|
**대화형:** **Modify**를 선택하고 `"Review channel assignments?"`에 **Yes**로 답한 뒤, 각 외부 모듈에서 Keep, Switch to stable, Switch to next, Pin to a tag 중 하나를 선택합니다.
|
||||||
|
|
||||||
|
**플래그로:** 다음 섹션의 레시피가 일반적인 경우를 다룹니다.
|
||||||
|
|
||||||
|
## Headless CI
|
||||||
|
|
||||||
|
### 플래그 참조
|
||||||
|
|
||||||
|
| 플래그 | 목적 |
|
||||||
|
| --- | --- |
|
||||||
|
| `--yes`, `-y` | 모든 프롬프트를 건너뛰고 플래그 값과 기본값을 수락합니다 |
|
||||||
|
| `--directory <path>` | 이 디렉터리에 설치합니다(기본값: 현재 작업 디렉터리) |
|
||||||
|
| `--modules <a,b,c>` | 정확한 모듈 집합입니다. core는 자동 추가됩니다. 증분 목록이 아니므로 유지하려는 모든 것을 나열하세요 |
|
||||||
|
| `--tools <a,b>` | IDE/도구 선택입니다. 새 `--yes` 설치에는 필수입니다. 유효 ID는 `--list-tools`로 확인하세요 |
|
||||||
|
| `--list-tools` | 지원되는 모든 도구/IDE ID와 대상 디렉터리를 출력하고 종료합니다 |
|
||||||
|
| `--action <type>` | `install`, `update`, `quick-update`. 기본값은 기존 설치 상태에 따라 달라집니다 |
|
||||||
|
| `--custom-source <urls>` | Git URL 또는 로컬 경로에서 커스텀 모듈을 설치합니다 |
|
||||||
|
| `--channel <stable\|next>` | 모든 외부 모듈에 적용합니다(`--all-stable` / `--all-next` 별칭) |
|
||||||
|
| `--all-stable` | `--channel=stable` 별칭 |
|
||||||
|
| `--all-next` | `--channel=next` 별칭 |
|
||||||
|
| `--next=<code>` | 한 모듈을 next 채널에 둡니다. 반복 가능합니다 |
|
||||||
|
| `--pin <code>=<tag>` | 한 모듈을 특정 태그에 고정합니다. 반복 가능합니다 |
|
||||||
|
| `--set <module>.<key>=<value>` | 모듈 설정 옵션을 비대화형으로 설정합니다(권장, [모듈 설정 오버라이드](#모듈-설정-오버라이드) 참고). 반복 가능합니다 |
|
||||||
|
| `--list-options [module]` | 내장 및 로컬 캐시된 공식 모듈의 모든 `--set` 키를 출력하고 종료합니다. 모듈 코드를 전달하면 범위를 좁힙니다 |
|
||||||
|
| `--user-name`, `--communication-language`, `--document-output-language`, `--output-folder` | `--set core.<key>=<value>`와 동등한 레거시 단축 플래그입니다(계속 지원) |
|
||||||
|
|
||||||
|
플래그가 겹칠 때 우선순위는 `--pin` > `--next=` > `--channel` / `--all-*` > 레지스트리 기본값(`stable`)입니다.
|
||||||
|
|
||||||
|
:::note[해결 예시]
|
||||||
|
`--all-next --pin cis=v0.2.0`은 bmb, gds, tea를 next에 두고 cis를 v0.2.0에 고정합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 레시피
|
||||||
|
|
||||||
|
**기본 설치 - 모든 것을 최신 안정 버전으로:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --yes --modules bmm,bmb,cis --tools claude-code
|
||||||
|
```
|
||||||
|
|
||||||
|
**엔터프라이즈 고정 - 바이트 단위로 재현 가능:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --yes \
|
||||||
|
--modules bmm,bmb,cis \
|
||||||
|
--pin bmb=v1.7.0 --pin cis=v0.2.0 \
|
||||||
|
--tools claude-code
|
||||||
|
```
|
||||||
|
|
||||||
|
**최신 개발판 - 외부 모듈을 main 브랜치 최신 커밋으로:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --yes --modules bmm,bmb --all-next --tools claude-code
|
||||||
|
```
|
||||||
|
|
||||||
|
**기존 설치에 모듈 추가**(나머지는 유지):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --yes --action update \
|
||||||
|
--modules bmm,bmb,gds
|
||||||
|
```
|
||||||
|
|
||||||
|
`--tools`는 의도적으로 생략했습니다. `--action update`는 최초 설치 때 설정한 도구를 재사용합니다.
|
||||||
|
|
||||||
|
**채널 혼합 - bmb는 next, gds는 stable:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --yes --action update \
|
||||||
|
--modules bmm,bmb,cis,gds \
|
||||||
|
--next=bmb
|
||||||
|
```
|
||||||
|
|
||||||
|
### 모듈 설정 오버라이드
|
||||||
|
|
||||||
|
`--set <module>.<key>=<value>`는 모듈 설정 옵션을 비대화형으로 설정합니다. 반복 가능하고 앞으로 추가될 모듈에도 같은 방식으로 적용됩니다. 이 플래그는 설치 후 패치로 적용됩니다. 설치 프로그램이 정상 흐름을 먼저 실행한 뒤 `--set`이 각 값을 `_bmad/config.toml`(팀 범위) 또는 `_bmad/config.user.toml`(사용자 범위), 그리고 `_bmad/<module>/config.yaml`에 갱신 또는 삽입하여 선언된 값이 다음 설치로 이어지게 합니다.
|
||||||
|
|
||||||
|
**예시 - 명시적 프로젝트 지식과 스킬 수준으로 bmm 설치:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --yes \
|
||||||
|
--modules bmm \
|
||||||
|
--tools claude-code \
|
||||||
|
--set bmm.project_knowledge=research \
|
||||||
|
--set bmm.user_skill_level=expert
|
||||||
|
```
|
||||||
|
|
||||||
|
**모듈에서 사용할 수 있는 키 찾기:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --list-options bmm
|
||||||
|
```
|
||||||
|
|
||||||
|
`--list-options`(인자 없음)는 설치 프로그램이 로컬에서 찾을 수 있는 모든 키를 나열합니다. 내장 모듈(`core`, `bmm`)과 현재 캐시된 공식 모듈이 포함됩니다. 캐시는 머신별이고 지워질 수 있으므로, 이전에 설치한 공식 모듈도 새 체크아웃이나 임시 CI 작업자에서는 다시 설치되기 전까지 나타나지 않습니다. 커뮤니티 및 커스텀 모듈은 여기서 열거되지 않습니다. 모듈의 `module.yaml`을 직접 읽어 선언된 키를 확인하세요.
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
- **경로 선택.** 패치 단계는 먼저 `config.user.toml`에서 `[modules.<module>] <key>`(또는 `[core] <key>`)를 찾고, 있으면 그 파일을 업데이트합니다. 그렇지 않으면 팀 범위 `config.toml`에 씁니다. 그래서 `core.user_name`, `bmm.user_skill_level` 같은 사용자 범위 키는 `config.user.toml`에, 팀 범위 키는 `config.toml`에 들어갑니다.
|
||||||
|
- **그대로 쓰는 값.** 값은 제공한 그대로 기록됩니다. `result:` 템플릿 렌더링은 없습니다. 렌더링된 형태(예: `{project-root}/research`)를 원하면 명시적으로 전달하세요: `--set bmm.project_knowledge='{project-root}/research'`.
|
||||||
|
- **다음 설치로 이어지는 선언된 키.** `module.yaml`에 선언된 키 값은 `_bmad/<module>/config.yaml`에도 쓰이므로 다음 설치 때 프롬프트 기본값으로 살아남습니다.
|
||||||
|
- **다음 설치로 이어지지 않는 미선언 키.** 모듈 스키마가 선언하지 않은 키 값은 현재 설치의 `config.toml`에 들어가지만 다음 설치 때 다시 생성되지 않습니다(매니페스트 작성기의 엄격한 스키마 분리 단계가 알 수 없는 키를 떨어뜨립니다). 계속 유지해야 한다면 `--set`을 다시 전달하거나 `_bmad/config.toml`을 직접 수정하세요.
|
||||||
|
- **검증 없음.** `single-select` 값은 허용 선택지와 대조하지 않고, 알 수 없는 키도 거부하지 않습니다. 지정한 값이 그대로 쓰입니다.
|
||||||
|
- **`--modules`에 없는 모듈.** 포함하지 않은 모듈에 값을 설정하면 경고를 출력하고 값은 버려집니다(설치되지 않은 모듈용 파일은 생성되지 않습니다).
|
||||||
|
|
||||||
|
레거시 core 단축 플래그(`--user-name`, `--output-folder` 등)은 하위 호환성을 위해 계속 동작하고 문서화되어 있지만, `--set core.user_name=...`과 동등합니다.
|
||||||
|
|
||||||
|
:::note[quick-update와 함께 동작]
|
||||||
|
`--set`은 설치 후 패치이므로 작업 유형과 관계없이 동일하게 적용됩니다. `bmad install --action quick-update` 또는 기존 설치에서 `--yes`(기본이 quick-update)로 실행해도 일반 설치처럼 마지막에 중앙 설정 파일을 패치합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::caution[공유 IP의 요청 제한]
|
||||||
|
익명 GitHub API 호출은 IP당 시간당 60회로 제한됩니다. 한 번의 설치는 안정 태그를 확인하기 위해 외부 모듈마다 API를 한 번 호출합니다. NAT 뒤의 사무실, CI 러너 풀, VPN은 함께 이 한도를 소진할 수 있습니다.
|
||||||
|
|
||||||
|
환경 변수에 `GITHUB_TOKEN=<personal access token>`을 설정하면 계정당 시간당 5000회로 한도가 올라갑니다. 공개 저장소 읽기용 개인 액세스 토큰(PAT)이면 충분하며 범위는 필요 없습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 설치된 내용
|
||||||
|
|
||||||
|
설치 후 `_bmad/_config/manifest.yaml`은 디스크에 있는 내용을 정확히 기록합니다.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
modules:
|
||||||
|
- name: bmb
|
||||||
|
version: v1.7.0 # 태그 또는 next용 "main"
|
||||||
|
channel: stable # stable | next | pinned
|
||||||
|
sha: 86033fc9aeae2ca6d52c7cdb675c1f4bf17fc1c1
|
||||||
|
source: external
|
||||||
|
repoUrl: https://github.com/bmad-code-org/bmad-builder
|
||||||
|
```
|
||||||
|
|
||||||
|
`sha` 필드는 git 기반 모듈(외부, 커뮤니티, URL 기반 커스텀)에 기록됩니다. 번들 모듈(core, bmm)과 로컬 경로 커스텀 모듈에는 없습니다. 그 코드는 복제 가능한 참조가 아니라 설치 프로그램 바이너리 또는 파일시스템 상태에 따라 달라집니다.
|
||||||
|
|
||||||
|
머신 간 재현성을 위해 같은 `--modules` 명령을 다시 실행하는 것에 의존하지 마세요. 안정 채널 설치는 **설치 시점**의 가장 높은 릴리스 태그로 해석되므로 나중에 다시 실행하면 그 사이 릴리스된 버전으로 설치됩니다. `manifest.yaml`의 기록된 태그를 대상 머신에서 명시적 `--pin` 플래그로 바꾸세요. 예:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install --yes --modules bmb,cis \
|
||||||
|
--pin bmb=v1.7.0 --pin cis=v0.4.2 --tools claude-code
|
||||||
|
```
|
||||||
|
|
||||||
|
## 문제 해결
|
||||||
|
|
||||||
|
### "Could not resolve stable tag" 또는 "API rate limit exceeded"
|
||||||
|
|
||||||
|
GitHub의 익명 시간당 60회 한도에 도달했습니다. `GITHUB_TOKEN`을 설정하고 다시 시도하세요. 이미 토큰이 있다면 만료되었거나 해당 토큰 자체의 한도에 걸렸을 수 있습니다. 다른 토큰을 시도하거나 시간당 한도가 초기화될 때까지 기다리세요.
|
||||||
|
|
||||||
|
### "Tag 'vX.Y.Z' not found"
|
||||||
|
|
||||||
|
`--pin`에 전달한 태그가 모듈 저장소에 없습니다. GitHub의 저장소 릴리스 페이지에서 유효한 태그를 확인하세요.
|
||||||
|
|
||||||
|
### 고정 설치가 계속 업그레이드됨
|
||||||
|
|
||||||
|
고정 설치는 업그레이드되지 않습니다. `Quick Update`는 안정 채널의 패치와 마이너만 적용하며 `pinned`나 `next`는 건드리지 않습니다. 고정 설치가 바뀌었다면 `_bmad/_config/manifest.yaml`을 여세요. 명시적으로 플래그로 오버라이드하지 않는 한 `channel: pinned`와 고정된 `version`, `sha`가 실행 간 유지되어야 합니다.
|
||||||
|
|
||||||
|
### `--pin bmm=X`가 아무 것도 하지 않음
|
||||||
|
|
||||||
|
bmm은 번들 모듈입니다. `--pin`과 `--next=`가 적용되지 않습니다. 사전 릴리스 core/bmm을 원하면 `npx bmad-method@next install`을 사용하거나 bmad-bmm 저장소를 체크아웃하고 설치 프로그램을 로컬에서 실행해 아직 릴리스되지 않은 변경을 받으세요.
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
---
|
||||||
|
title: '커스텀 및 커뮤니티 모듈 설치'
|
||||||
|
description: 커뮤니티 레지스트리, Git 저장소, 로컬 경로에서 서드파티 모듈을 설치합니다
|
||||||
|
sidebar:
|
||||||
|
order: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad 설치 프로그램을 사용해 커뮤니티 레지스트리, 서드파티 Git 저장소, 로컬 파일 경로에서 모듈을 추가하세요.
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
- BMad 레지스트리에서 커뮤니티 기여 모듈을 설치합니다
|
||||||
|
- 서드파티 Git 저장소(GitHub, GitLab, Bitbucket, 자체 호스팅)에서 모듈을 설치합니다
|
||||||
|
- BMad 빌더로 로컬에서 개발 중인 모듈을 테스트합니다
|
||||||
|
- 비공개 또는 자체 호스팅 Git 서버에서 모듈을 설치합니다
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
[Node.js](https://nodejs.org) v20.12+와 `npx`(npm에 포함)가 필요합니다. 커스텀 및 커뮤니티 모듈은 새 설치 중 선택하거나 기존 설치에 추가할 수 있습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 커뮤니티 모듈
|
||||||
|
|
||||||
|
커뮤니티 모듈은 [BMad 플러그인 마켓플레이스](https://github.com/bmad-code-org/bmad-plugins-marketplace)에서 선별됩니다. 카테고리별로 구성되고 안전을 위해 승인된 커밋에 고정됩니다.
|
||||||
|
|
||||||
|
### 1. 설치 프로그램 실행
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 커뮤니티 카탈로그 둘러보기
|
||||||
|
|
||||||
|
공식 모듈을 선택한 뒤 설치 프로그램이 묻습니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
Would you like to browse community modules?
|
||||||
|
```
|
||||||
|
|
||||||
|
카탈로그 브라우저로 들어가려면 **Yes**를 선택하세요. 할 수 있는 일은 다음과 같습니다.
|
||||||
|
|
||||||
|
- 카테고리별 탐색
|
||||||
|
- 추천 모듈 보기
|
||||||
|
- 사용 가능한 모든 모듈 보기
|
||||||
|
- 키워드로 검색
|
||||||
|
|
||||||
|
### 3. 모듈 선택
|
||||||
|
|
||||||
|
어떤 카테고리에서든 모듈을 선택하세요. 설치 프로그램은 설명, 버전, 신뢰 등급을 보여줍니다. 이미 설치된 모듈은 업데이트 대상으로 미리 체크됩니다.
|
||||||
|
|
||||||
|
### 4. 설치 계속
|
||||||
|
|
||||||
|
커뮤니티 모듈을 선택하면 설치 프로그램은 커스텀 소스, 도구/IDE 설정, 나머지 설치 흐름으로 이어집니다.
|
||||||
|
|
||||||
|
## 커스텀 소스(Git URL과 로컬 경로)
|
||||||
|
|
||||||
|
커스텀 모듈은 어떤 Git 저장소나 로컬 디렉터리에서든 올 수 있습니다. 설치 프로그램은 소스를 해석하고 모듈 구조를 분석한 뒤 다른 모듈 옆에 설치합니다.
|
||||||
|
|
||||||
|
### 대화형 설치
|
||||||
|
|
||||||
|
설치 중 커뮤니티 모듈 단계 이후 설치 프로그램이 묻습니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
Would you like to install from a custom source (Git URL or local path)?
|
||||||
|
```
|
||||||
|
|
||||||
|
**Yes**를 선택한 뒤 소스를 제공합니다.
|
||||||
|
|
||||||
|
| 입력 유형 | 예시 |
|
||||||
|
| --- | --- |
|
||||||
|
| HTTPS URL(모든 호스트) | `https://github.com/org/repo` |
|
||||||
|
| HTTP URL(모든 호스트) | `http://host/org/repo` |
|
||||||
|
| 하위 디렉터리가 있는 HTTPS URL | `https://github.com/org/repo/tree/main/my-module` |
|
||||||
|
| SSH URL | `git@github.com:org/repo.git` |
|
||||||
|
| 로컬 경로 | `/Users/me/projects/my-module` |
|
||||||
|
| 틸드가 있는 로컬 경로 | `~/projects/my-module` |
|
||||||
|
|
||||||
|
설치 프로그램은 저장소를 복제(URL인 경우)하거나 디스크에서 직접 읽은 뒤(로컬 경로인 경우), 발견된 모듈을 선택할 수 있게 보여줍니다.
|
||||||
|
|
||||||
|
### 비대화형 설치
|
||||||
|
|
||||||
|
명령줄에서 커스텀 모듈을 설치하려면 `--custom-source` 플래그를 사용하세요.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install \
|
||||||
|
--directory . \
|
||||||
|
--custom-source /path/to/my-module \
|
||||||
|
--tools claude-code \
|
||||||
|
--yes
|
||||||
|
```
|
||||||
|
|
||||||
|
`--modules` 없이 `--custom-source`를 제공하면 core와 커스텀 모듈만 설치됩니다. 공식 모듈도 포함하려면 `--modules`를 추가하세요.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install \
|
||||||
|
--directory . \
|
||||||
|
--modules bmm \
|
||||||
|
--custom-source https://gitlab.com/myorg/my-module \
|
||||||
|
--tools claude-code \
|
||||||
|
--yes
|
||||||
|
```
|
||||||
|
|
||||||
|
여러 소스는 쉼표로 구분할 수 있습니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
--custom-source /path/one,https://github.com/org/repo,/path/two
|
||||||
|
```
|
||||||
|
|
||||||
|
## 모듈 발견 방식
|
||||||
|
|
||||||
|
설치 프로그램은 소스에서 설치 가능한 모듈을 찾기 위해 두 모드를 사용합니다.
|
||||||
|
|
||||||
|
| 모드 | 트리거 | 동작 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `Discovery` | 소스에 `.claude-plugin/marketplace.json`이 있습니다 | 매니페스트의 모든 플러그인을 나열하고 설치할 항목을 선택하게 합니다 |
|
||||||
|
| `Direct` | marketplace.json이 없습니다 | 디렉터리에서 스킬(`SKILL.md`가 있는 하위 디렉터리)을 스캔하고 단일 모듈로 해석합니다 |
|
||||||
|
|
||||||
|
`Discovery` 모드는 게시된 모듈에 일반적입니다. `Direct` 모드는 로컬 개발 중 스킬 디렉터리를 가리킬 때 편리합니다.
|
||||||
|
|
||||||
|
:::note[`.claude-plugin/`에 대해]
|
||||||
|
`.claude-plugin/marketplace.json` 경로는 여러 AI 도구 설치 프로그램에서 플러그인 발견을 위해 채택한 표준 관례입니다. Claude가 필요하지 않고 Claude API를 사용하지 않으며 어떤 AI 도구를 쓰는지에 영향을 주지 않습니다. 이 파일이 있는 모듈은 관례를 따르는 모든 설치 프로그램에서 발견될 수 있습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 로컬 개발 워크플로
|
||||||
|
|
||||||
|
[BMad 빌더](https://github.com/bmad-code-org/bmad-builder)로 모듈을 만들고 있다면 작업 디렉터리에서 직접 설치할 수 있습니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install \
|
||||||
|
--directory ~/my-project \
|
||||||
|
--custom-source ~/my-module-repo/skills \
|
||||||
|
--tools claude-code \
|
||||||
|
--yes
|
||||||
|
```
|
||||||
|
|
||||||
|
로컬 소스는 캐시에 복사되지 않고 경로로 참조됩니다. 모듈 소스를 업데이트하고 다시 설치하면 설치 프로그램이 최신 변경을 가져옵니다.
|
||||||
|
|
||||||
|
:::caution[소스 제거]
|
||||||
|
설치 후 로컬 소스 디렉터리를 삭제해도 `_bmad/`에 설치된 모듈 파일은 보존됩니다. 소스 경로가 복원될 때까지 업데이트 중 해당 모듈은 건너뜁니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 얻는 결과
|
||||||
|
|
||||||
|
설치 후 커스텀 모듈은 공식 모듈과 함께 `_bmad/`에 나타납니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
your-project/
|
||||||
|
├── _bmad/
|
||||||
|
│ ├── core/ # 내장 core 모듈
|
||||||
|
│ ├── bmm/ # 공식 모듈(선택한 경우)
|
||||||
|
│ ├── my-module/ # 커스텀 모듈
|
||||||
|
│ │ ├── my-skill/
|
||||||
|
│ │ │ └── SKILL.md
|
||||||
|
│ │ └── module-help.csv
|
||||||
|
│ └── _config/
|
||||||
|
│ └── manifest.yaml # 모든 모듈, 버전, 소스를 추적
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
매니페스트는 각 커스텀 모듈의 소스(Git 소스는 `repoUrl`, 로컬 소스는 `localPath`)를 기록하여 `Quick Update`가 소스를 다시 찾을 수 있게 합니다.
|
||||||
|
|
||||||
|
## 커스텀 모듈 업데이트
|
||||||
|
|
||||||
|
커스텀 모듈도 일반 업데이트 흐름에 참여합니다.
|
||||||
|
|
||||||
|
- **Quick Update**(`--action quick-update`): 모든 모듈을 원래 소스에서 새로 고칩니다. Git 기반 모듈은 다시 가져오고 로컬 모듈은 소스 경로에서 다시 읽힙니다.
|
||||||
|
- **전체 업데이트**: 모듈 선택을 다시 실행해 커스텀 모듈을 추가하거나 제거할 수 있습니다.
|
||||||
|
|
||||||
|
## 직접 모듈 만들기
|
||||||
|
|
||||||
|
다른 사람이 설치할 수 있는 모듈을 만들려면 [BMad 빌더](https://github.com/bmad-code-org/bmad-builder)를 사용하세요.
|
||||||
|
|
||||||
|
1. `bmad-module-builder`를 실행해 모듈 초기 구조를 생성합니다
|
||||||
|
2. 여러 BMad 빌더 도구로 스킬, 에이전트, 워크플로를 추가합니다
|
||||||
|
3. Git 저장소에 게시하거나 폴더 컬렉션을 공유합니다
|
||||||
|
4. 다른 사용자는 `--custom-source <your-repo-url>`로 설치합니다
|
||||||
|
|
||||||
|
모듈이 발견 모드를 지원하려면 저장소 루트에 `.claude-plugin/marketplace.json`을 포함하세요(Claude 전용이 아닌 도구 간 관례입니다). marketplace.json 형식은 [BMad 빌더 문서](https://github.com/bmad-code-org/bmad-builder)를 참고하세요.
|
||||||
|
|
||||||
|
:::tip[먼저 로컬에서 테스트]
|
||||||
|
개발 중에는 Git 저장소에 게시하기 전에 로컬 경로로 모듈을 설치해 빠르게 반복하세요.
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
title: 비대화형 설치
|
||||||
|
description: 비대화형 / CI 설치 문서가 이동되었습니다
|
||||||
|
sidebar:
|
||||||
|
order: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
:::note[이 페이지는 이동되었습니다]
|
||||||
|
비대화형 및 CI 설치 플래그, 채널 선택, 버전 고정은 통합된 [BMad 설치 방법](./install-bmad.md) 가이드로 이동했습니다. 플래그 참조와 바로 복사해 쓸 수 있는 예시는 [비대화형 CI](./install-bmad.md#headless-ci) 섹션에서 확인하세요.
|
||||||
|
:::
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
---
|
||||||
|
title: '프로젝트 컨텍스트 관리'
|
||||||
|
description: AI 에이전트를 안내하는 project-context.md를 만들고 유지합니다
|
||||||
|
sidebar:
|
||||||
|
order: 9
|
||||||
|
---
|
||||||
|
|
||||||
|
`project-context.md` 파일을 사용해 모든 워크플로에서 AI 에이전트가 프로젝트의 기술 선호도와 구현 규칙을 따르게 하세요. 이 파일을 항상 참고하게 하려면 도구 컨텍스트나 항상 적용되는 규칙 파일(예: `AGENTS.md`)에 `중요한 프로젝트 컨텍스트와 관례는 [프로젝트 컨텍스트 경로]/project-context.md에 있습니다`라는 줄을 추가할 수도 있습니다.
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
|
||||||
|
- BMad Method 설치
|
||||||
|
- 프로젝트의 기술 스택과 규칙에 대한 이해
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
- 아키텍처를 시작하기 전에 강한 기술 선호도가 있습니다
|
||||||
|
- 아키텍처를 완료했고 구현 결정을 포착하고 싶습니다
|
||||||
|
- 이미 확립된 패턴이 있는 기존 코드베이스에서 작업합니다
|
||||||
|
- 스토리마다 에이전트가 일관되지 않은 결정을 내리는 문제가 보입니다
|
||||||
|
|
||||||
|
## 1단계: 접근 방식 선택
|
||||||
|
|
||||||
|
**수동 작성** - 문서화할 규칙을 정확히 알고 있을 때 가장 좋습니다
|
||||||
|
|
||||||
|
**아키텍처 후 생성** - 솔루션 설계 중 내려진 결정을 포착할 때 가장 좋습니다
|
||||||
|
|
||||||
|
**기존 프로젝트용 생성** - 기존 코드베이스의 패턴을 발견할 때 가장 좋습니다
|
||||||
|
|
||||||
|
## 2단계: 파일 만들기
|
||||||
|
|
||||||
|
### 옵션 A: 수동 작성
|
||||||
|
|
||||||
|
`_bmad-output/project-context.md`에 파일을 만듭니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p _bmad-output
|
||||||
|
touch _bmad-output/project-context.md
|
||||||
|
```
|
||||||
|
|
||||||
|
기술 스택과 구현 규칙을 추가합니다.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
project_name: '내프로젝트'
|
||||||
|
user_name: '사용자이름'
|
||||||
|
date: '2026-02-15'
|
||||||
|
sections_completed: ['technology_stack', 'critical_rules']
|
||||||
|
---
|
||||||
|
|
||||||
|
# AI 에이전트용 프로젝트 컨텍스트
|
||||||
|
|
||||||
|
## 기술 스택과 버전
|
||||||
|
|
||||||
|
- Node.js 20.x, TypeScript 5.3, React 18.2
|
||||||
|
- 상태 관리: Zustand
|
||||||
|
- 테스트: Vitest, Playwright
|
||||||
|
- 스타일링: Tailwind CSS
|
||||||
|
|
||||||
|
## 중요한 구현 규칙
|
||||||
|
|
||||||
|
**TypeScript:**
|
||||||
|
|
||||||
|
- 엄격 모드 사용, `any` 타입 금지
|
||||||
|
- 공개 API에는 `interface`, 유니언에는 `type` 사용
|
||||||
|
|
||||||
|
**코드 구성:**
|
||||||
|
|
||||||
|
- 컴포넌트는 `/src/components/`에 두고 테스트를 함께 배치
|
||||||
|
- API 호출은 `apiClient` 싱글턴 사용 - 직접 fetch 금지
|
||||||
|
|
||||||
|
**테스트:**
|
||||||
|
|
||||||
|
- 단위 테스트는 비즈니스 로직에 집중
|
||||||
|
- 통합 테스트는 MSW로 API를 모킹
|
||||||
|
```
|
||||||
|
|
||||||
|
### 옵션 B: 아키텍처 후 생성
|
||||||
|
|
||||||
|
새 채팅에서 워크플로를 실행합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bmad-generate-project-context
|
||||||
|
```
|
||||||
|
|
||||||
|
워크플로는 아키텍처 문서와 프로젝트 파일을 스캔해 내려진 결정을 담은 컨텍스트 파일을 생성합니다.
|
||||||
|
|
||||||
|
### 옵션 C: 기존 프로젝트용 생성
|
||||||
|
|
||||||
|
기존 프로젝트에서는 다음을 실행합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bmad-generate-project-context
|
||||||
|
```
|
||||||
|
|
||||||
|
워크플로가 코드베이스를 분석해 규칙을 식별한 뒤 검토하고 다듬을 수 있는 컨텍스트 파일을 생성합니다.
|
||||||
|
|
||||||
|
## 3단계: 내용 확인
|
||||||
|
|
||||||
|
생성된 파일을 검토하고 다음이 담겨 있는지 확인하세요.
|
||||||
|
|
||||||
|
- 올바른 기술 버전
|
||||||
|
- 실제 관례(일반적인 모범 사례가 아님)
|
||||||
|
- 흔한 실수를 예방하는 규칙
|
||||||
|
- 프레임워크별 패턴
|
||||||
|
|
||||||
|
누락된 내용은 수동으로 추가하고 부정확한 내용은 제거하세요.
|
||||||
|
|
||||||
|
## 얻는 결과
|
||||||
|
|
||||||
|
`project-context.md` 파일은 다음을 제공합니다.
|
||||||
|
|
||||||
|
- 모든 에이전트가 같은 규칙을 따르게 합니다
|
||||||
|
- 스토리 간 일관되지 않은 결정을 방지합니다
|
||||||
|
- 구현을 위한 아키텍처 결정을 포착합니다
|
||||||
|
- 프로젝트 패턴과 규칙의 참조 자료가 됩니다
|
||||||
|
|
||||||
|
## 팁
|
||||||
|
|
||||||
|
:::tip[모범 사례]
|
||||||
|
|
||||||
|
- **겉으로 잘 드러나지 않는 것에 집중하세요** - "의미 있는 변수명을 사용하라" 같은 보편 규칙보다 "모든 공개 클래스에는 JSDoc을 사용하라"처럼 에이전트가 놓칠 수 있는 패턴을 문서화합니다.
|
||||||
|
- **간결하게 유지하세요** - 이 파일은 모든 구현 워크플로에서 로드됩니다. 긴 파일은 컨텍스트를 낭비합니다. 좁은 범위나 특정 스토리에만 적용되는 내용은 제외하세요.
|
||||||
|
- **필요할 때 업데이트하세요** - 패턴이 바뀌면 수동으로 수정하거나 큰 아키텍처 변경 후 다시 생성하세요.
|
||||||
|
- 빠른 흐름과 전체 BMad Method 프로젝트 모두에 사용할 수 있습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 다음 단계
|
||||||
|
|
||||||
|
- [**프로젝트 컨텍스트 설명**](../explanation/project-context.md) - 작동 방식을 더 알아보기
|
||||||
|
- [**워크플로 맵**](../reference/workflow-map.md) - 어떤 워크플로가 프로젝트 컨텍스트를 로드하는지 보기
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
---
|
||||||
|
title: '빠른 수정'
|
||||||
|
description: 빠른 수정과 임시 변경을 수행하는 방법
|
||||||
|
sidebar:
|
||||||
|
order: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
전체 BMad Method가 필요하지 않은 버그 수정, 리팩터링, 작은 목표 변경에는 **빠른 개발**을 사용하세요.
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
- 원인이 명확하고 알려진 버그 수정
|
||||||
|
- 몇 개 파일 안에 제한된 작은 리팩터링(이름 변경, 추출, 구조 변경)
|
||||||
|
- 작은 기능 조정이나 설정 변경
|
||||||
|
- 의존성 업데이트
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
|
||||||
|
- BMad Method 설치(`npx bmad-method install`)
|
||||||
|
- AI 기반 IDE(Claude Code, Cursor 또는 유사 도구)
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 단계
|
||||||
|
|
||||||
|
### 1. 새 채팅 시작
|
||||||
|
|
||||||
|
AI IDE에서 **새 채팅 세션**을 엽니다. 이전 워크플로 세션을 재사용하면 컨텍스트 충돌이 생길 수 있습니다.
|
||||||
|
|
||||||
|
### 2. 의도 전달
|
||||||
|
|
||||||
|
빠른 개발은 호출 전, 호출과 함께, 또는 호출 후에 자유 형식 의도를 받을 수 있습니다. 예를 들면 다음과 같습니다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
run quick-dev - 빈 비밀번호를 허용하는 로그인 검증 버그를 수정해 줘.
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
run quick-dev - https://github.com/org/repo/issues/42 를 수정해 줘
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
run quick-dev - _bmad-output/implementation-artifacts/my-intent.md의 의도를 구현해 줘
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
문제는 인증 미들웨어에 있는 것 같아요. 토큰 만료를 확인하지 않습니다.
|
||||||
|
확인해 보니 src/auth/middleware.ts 47번째 줄에서 exp 확인을 완전히 건너뜁니다.
|
||||||
|
run quick-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
run quick-dev
|
||||||
|
> 무엇을 하고 싶나요?
|
||||||
|
UserService가 콜백 대신 async/await를 사용하도록 리팩터링해 줘.
|
||||||
|
```
|
||||||
|
|
||||||
|
일반 텍스트, 파일 경로, GitHub 이슈 URL, 버그 트래커 링크 등 LLM이 구체적 의도로 해석할 수 있는 것이면 됩니다.
|
||||||
|
|
||||||
|
### 3. 질문에 답하고 승인
|
||||||
|
|
||||||
|
빠른 개발은 구현 전에 명확화 질문을 하거나 짧은 사양을 제시해 승인을 요청할 수 있습니다. 질문에 답하고 계획이 만족스러우면 승인하세요.
|
||||||
|
|
||||||
|
### 4. 리뷰하고 푸시
|
||||||
|
|
||||||
|
빠른 개발이 변경을 구현하고, 자체 리뷰하고, 문제를 패치하고, 로컬에 커밋합니다. 완료되면 영향을 받은 파일을 에디터에서 엽니다.
|
||||||
|
|
||||||
|
- diff를 훑어 변경이 의도와 맞는지 확인합니다
|
||||||
|
- 이상한 점이 있으면 에이전트에게 수정할 내용을 말하세요. 같은 세션에서 반복할 수 있습니다
|
||||||
|
|
||||||
|
만족하면 커밋을 푸시하세요. 빠른 개발이 푸시와 PR 생성을 제안합니다.
|
||||||
|
|
||||||
|
:::caution[문제가 생기면]
|
||||||
|
푸시한 변경이 예상치 못한 문제를 일으키면 `git revert HEAD`로 마지막 커밋을 깔끔하게 되돌리세요. 그런 다음 새 채팅을 시작하고 빠른 개발을 다시 실행해 다른 접근을 시도합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 얻는 결과
|
||||||
|
|
||||||
|
- 수정 또는 리팩터링이 적용된 소스 파일
|
||||||
|
- 테스트 스위트가 있다면 통과하는 테스트
|
||||||
|
- Conventional Commit 형식의 푸시 준비 완료 커밋
|
||||||
|
|
||||||
|
## 보류 작업
|
||||||
|
|
||||||
|
빠른 개발은 각 실행을 하나의 목표에 집중하게 합니다. 요청에 여러 독립 목표가 있거나 리뷰에서 변경과 무관한 기존 문제가 드러나면, 모든 것을 한 번에 처리하지 않고 구현 산출물 디렉터리의 `deferred-work.md` 파일에 따로 보류합니다.
|
||||||
|
|
||||||
|
실행 후 이 파일을 확인하세요. 나중에 다시 볼 작업 백로그입니다. 각 보류 항목은 이후 새 빠른 개발 실행에 넣을 수 있습니다.
|
||||||
|
|
||||||
|
## 정식 계획으로 업그레이드할 때
|
||||||
|
|
||||||
|
다음과 같다면 전체 BMad Method 사용을 고려하세요.
|
||||||
|
|
||||||
|
- 변경이 여러 시스템에 영향을 주거나 많은 파일의 조율된 업데이트가 필요합니다
|
||||||
|
- 범위를 확신하지 못해 먼저 요구사항 발견이 필요합니다
|
||||||
|
- 팀을 위해 문서나 아키텍처 결정을 기록해야 합니다
|
||||||
|
|
||||||
|
빠른 개발이 BMad Method와 어떻게 맞물리는지는 [빠른 개발](../explanation/quick-dev.md)을 참고하세요.
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
---
|
||||||
|
title: '문서 샤딩 가이드'
|
||||||
|
description: 큰 Markdown 파일을 더 작고 정리된 파일로 나눠 컨텍스트 관리를 개선합니다
|
||||||
|
sidebar:
|
||||||
|
order: 10
|
||||||
|
---
|
||||||
|
|
||||||
|
큰 Markdown 파일을 더 작고 정리된 파일로 나눠 컨텍스트 관리를 개선해야 한다면 `bmad-shard-doc` 도구를 사용하세요.
|
||||||
|
|
||||||
|
:::caution[지원 중단]
|
||||||
|
이 방식은 더 이상 권장되지 않습니다. 업데이트된 워크플로와 대부분의 주요 LLM 및 도구가 하위 프로세스를 지원하게 되면 곧 필요 없어질 것입니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
선택한 도구/모델 조합이 필요한 모든 문서를 입력으로 로드하고 읽지 못한다는 것을 확인한 경우에만 사용하세요.
|
||||||
|
|
||||||
|
## 문서 샤딩이란?
|
||||||
|
|
||||||
|
문서 샤딩은 큰 Markdown 파일을 2단계 제목(`## 제목`)을 기준으로 더 작고 정리된 파일로 나눕니다.
|
||||||
|
|
||||||
|
### 아키텍처
|
||||||
|
|
||||||
|
```text
|
||||||
|
샤딩 전:
|
||||||
|
_bmad-output/planning-artifacts/
|
||||||
|
└── PRD.md (큰 50k 토큰 파일)
|
||||||
|
|
||||||
|
샤딩 후:
|
||||||
|
_bmad-output/planning-artifacts/
|
||||||
|
└── prd/
|
||||||
|
├── index.md # 설명이 있는 목차
|
||||||
|
├── overview.md # 섹션 1
|
||||||
|
├── user-requirements.md # 섹션 2
|
||||||
|
├── technical-requirements.md # 섹션 3
|
||||||
|
└── ... # 추가 섹션
|
||||||
|
```
|
||||||
|
|
||||||
|
## 단계
|
||||||
|
|
||||||
|
### 1. 문서 샤딩 도구 실행
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/bmad-shard-doc
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 대화형 과정 따르기
|
||||||
|
|
||||||
|
```text
|
||||||
|
에이전트: 어떤 문서를 샤딩할까요?
|
||||||
|
사용자: docs/PRD.md
|
||||||
|
|
||||||
|
에이전트: 기본 대상: docs/prd/
|
||||||
|
기본값을 사용할까요? [y/n]
|
||||||
|
사용자: y
|
||||||
|
|
||||||
|
에이전트: PRD.md를 샤딩하는 중...
|
||||||
|
✓ 섹션 파일 12개 생성
|
||||||
|
✓ index.md 생성
|
||||||
|
✓ 완료!
|
||||||
|
```
|
||||||
|
|
||||||
|
## 워크플로 발견 방식
|
||||||
|
|
||||||
|
BMad 워크플로는 **이중 발견 시스템**을 사용합니다.
|
||||||
|
|
||||||
|
1. **먼저 전체 문서 시도** - `document-name.md`를 찾습니다
|
||||||
|
2. **샤딩된 버전 확인** - `document-name/index.md`를 찾습니다
|
||||||
|
3. **우선순위 규칙** - 둘 다 있으면 전체 문서가 우선합니다. 샤딩된 버전을 사용하려면 전체 문서를 제거하세요
|
||||||
|
|
||||||
|
## 워크플로 지원
|
||||||
|
|
||||||
|
모든 BMM 워크플로는 두 형식을 모두 지원합니다.
|
||||||
|
|
||||||
|
- 전체 문서
|
||||||
|
- 샤딩된 문서
|
||||||
|
- 자동 감지
|
||||||
|
- 사용자에게 투명하게 동작
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
---
|
||||||
|
title: 'v6로 업그레이드하는 방법'
|
||||||
|
description: BMad v4에서 v6로 마이그레이션합니다
|
||||||
|
sidebar:
|
||||||
|
order: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad 설치 프로그램을 사용해 v4에서 v6로 업그레이드하세요. 레거시 설치 자동 감지와 마이그레이션 지원이 포함되어 있습니다.
|
||||||
|
|
||||||
|
## 사용 시점
|
||||||
|
|
||||||
|
- BMad v4가 설치되어 있습니다(`.bmad-method` 폴더)
|
||||||
|
- 새 v6 아키텍처로 마이그레이션하고 싶습니다
|
||||||
|
- 보존해야 할 기존 계획 산출물이 있습니다
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
|
||||||
|
- Node.js 20.12+
|
||||||
|
- 기존 BMad v4 설치
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 단계
|
||||||
|
|
||||||
|
### 1. 설치 프로그램 실행
|
||||||
|
|
||||||
|
[설치 프로그램 안내](./install-bmad.md)를 따르세요.
|
||||||
|
|
||||||
|
### 2. 레거시 설치 처리
|
||||||
|
|
||||||
|
v4가 감지되면 다음 중 선택할 수 있습니다.
|
||||||
|
|
||||||
|
- 설치 프로그램이 `.bmad-method`를 백업하고 제거하게 합니다
|
||||||
|
- 종료한 뒤 수동으로 정리합니다
|
||||||
|
|
||||||
|
BMad Method 폴더 이름을 다르게 지정했다면 직접 폴더를 제거해야 합니다.
|
||||||
|
|
||||||
|
### 3. IDE 스킬 정리
|
||||||
|
|
||||||
|
레거시 v4 IDE 명령/스킬을 수동으로 제거하세요. 예를 들어 Claude Code를 사용한다면 bmad로 시작하는 중첩 폴더를 찾아 제거합니다.
|
||||||
|
|
||||||
|
- `.claude/commands/`
|
||||||
|
|
||||||
|
새 v6 스킬은 다음 위치에 설치됩니다.
|
||||||
|
|
||||||
|
- `.claude/skills/`
|
||||||
|
|
||||||
|
### 4. 계획 산출물 마이그레이션
|
||||||
|
|
||||||
|
**계획 문서(제품 개요/PRD/UX/아키텍처)가 있다면:**
|
||||||
|
|
||||||
|
설명적인 이름으로 `_bmad-output/planning-artifacts/`에 옮기세요.
|
||||||
|
|
||||||
|
- PRD 문서는 파일명에 `PRD`를 포함합니다
|
||||||
|
- 파일 유형에 맞게 `brief`, `architecture`, `ux-design`을 포함합니다
|
||||||
|
- 샤딩된 문서는 이름 있는 하위 폴더에 둘 수 있습니다
|
||||||
|
|
||||||
|
**계획 도중이라면:** v6 워크플로로 다시 시작하는 것을 고려하세요. 기존 문서를 입력으로 사용할 수 있습니다. 웹 검색과 IDE 계획 모드를 활용하는 새 점진적 발견 워크플로가 더 좋은 결과를 만듭니다.
|
||||||
|
|
||||||
|
### 5. 진행 중인 개발 마이그레이션
|
||||||
|
|
||||||
|
이미 생성 또는 구현된 스토리가 있다면:
|
||||||
|
|
||||||
|
1. v6 설치를 완료합니다
|
||||||
|
2. `epics.md` 또는 `epics/epic*.md`를 `_bmad-output/planning-artifacts/`에 둡니다
|
||||||
|
3. 개발자의 `bmad-sprint-planning` 워크플로를 실행합니다
|
||||||
|
4. 이미 완료된 에픽/스토리를 에이전트에게 알려줍니다
|
||||||
|
|
||||||
|
## 얻는 결과
|
||||||
|
|
||||||
|
**v6 통합 구조:**
|
||||||
|
|
||||||
|
```text
|
||||||
|
your-project/
|
||||||
|
├── _bmad/ # 단일 설치 폴더
|
||||||
|
│ ├── _config/ # 커스터마이징
|
||||||
|
│ │ └── agents/ # 에이전트 커스터마이징 파일
|
||||||
|
│ ├── core/ # 범용 core 프레임워크
|
||||||
|
│ ├── bmm/ # BMad Method 모듈
|
||||||
|
│ ├── bmb/ # BMad 빌더
|
||||||
|
│ └── cis/ # 창의적 지능 제품군
|
||||||
|
└── _bmad-output/ # 출력 폴더(v4의 문서 폴더)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 모듈 마이그레이션
|
||||||
|
|
||||||
|
| v4 모듈 | v6 상태 |
|
||||||
|
| --- | --- |
|
||||||
|
| `.bmad-2d-phaser-game-dev` | BMGD 모듈에 통합 |
|
||||||
|
| `.bmad-2d-unity-game-dev` | BMGD 모듈에 통합 |
|
||||||
|
| `.bmad-godot-game-dev` | BMGD 모듈에 통합 |
|
||||||
|
| `.bmad-infrastructure-devops` | 지원 중단 - 새 DevOps 에이전트 예정 |
|
||||||
|
| `.bmad-creative-writing` | 아직 적용되지 않음 - 새 v6 모듈 예정 |
|
||||||
|
|
||||||
|
## 주요 변경 사항
|
||||||
|
|
||||||
|
| 개념 | v4 | v6 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| **코어** | `_bmad-core`는 실제로 BMad Method였습니다 | `_bmad/core/`는 범용 프레임워크입니다 |
|
||||||
|
| **메서드** | `_bmad-method` | `_bmad/bmm/` |
|
||||||
|
| **설정** | 파일을 직접 수정 | 모듈별 `config.yaml` |
|
||||||
|
| **문서** | 샤딩 또는 비샤딩 필수 설정 | 완전히 유연하며 자동 스캔 |
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
---
|
||||||
|
title: 'Web Bundles 사용하기'
|
||||||
|
description: BMad web bundle을 Google Gemini Gem 또는 ChatGPT Custom GPT로 설치하기
|
||||||
|
---
|
||||||
|
|
||||||
|
Web bundle은 **[bmadcode.com/web-bundles](https://bmadcode.com/web-bundles/)**에서 설치합니다.
|
||||||
|
|
||||||
|
## 단일 진입점이 필요한 이유
|
||||||
|
|
||||||
|
이 사이트는 번들 카탈로그의 유일한 지원 설치 경로입니다. Gemini와 ChatGPT가 바뀌어도 단계가 최신 상태로 유지되고, 항상 가장 최신 태그 릴리스를 가리키며, 한 번 가입하면 새 번들이 나올 때 알림 목록에 들어갈 수 있습니다.
|
||||||
|
|
||||||
|
## 사이트에서 할 일
|
||||||
|
|
||||||
|
1. 카드 그리드에서 번들을 고릅니다.
|
||||||
|
2. 설치 모달을 엽니다. **Gemini Gem** 탭과 **ChatGPT GPT** 탭을 전환해 플랫폼별 단계를 확인합니다.
|
||||||
|
3. 번들 ZIP을 다운로드합니다. 이메일 전용 무료 멤버 가입은 한 번만 필요합니다.
|
||||||
|
4. 페이지 안의 단계를 따릅니다. Gem 또는 Custom GPT를 만들고, 지식 파일을 업로드하고, 지침 블록을 붙여 넣은 뒤 저장합니다.
|
||||||
|
|
||||||
|
## 사전 조건
|
||||||
|
|
||||||
|
- **Gemini Gems**: Gemini Advanced 구독.
|
||||||
|
- **ChatGPT Custom GPTs**: Plus, Pro, Business 또는 Enterprise 플랜.
|
||||||
|
- **Deep Research**를 사용하는 번들(현재 Market & Industry Research)은 프롬프트 바에서 활성화합니다(Tools → Deep Research). Deep Research에는 별도의 플랜 제한이 있습니다.
|
||||||
|
|
||||||
|
## 페르소나 커스터마이징
|
||||||
|
|
||||||
|
각 번들의 `INSTRUCTIONS.md`(ZIP 안에 있음)에는 붙여 넣기 경계 위에 **Persona Swap Example**이 포함됩니다. 설치한 지침의 `[persona]` 블록을 교체 예시로 바꾸면 프로토콜을 바꾸지 않고도 목소리를 바꿀 수 있습니다. 직접 새 페르소나를 작성해도 됩니다. 프로토콜은 그대로 유지됩니다.
|
||||||
|
|
||||||
|
## 얻는 것
|
||||||
|
|
||||||
|
- 하나의 BMad 계획 역량에 맞춰진 재사용 가능한 Gem 또는 Custom GPT.
|
||||||
|
- 구현을 위해 IDE에 바로 넣을 수 있는 다듬어진 산출물(brief, PRD, research report, UX spec).
|
||||||
|
- 계획 대화가 토큰 사용량 과금 IDE가 아니라 기존 웹 LLM 구독에서 실행됩니다.
|
||||||
|
|
||||||
|
:::caution[페르소나 이탈]
|
||||||
|
웹 LLM은 긴 세션 도중 가끔 페르소나를 놓칠 수 있습니다. 모델이 캐릭터 밖으로 말하기 시작하면 페르소나를 다시 상기시키거나 새 세션을 시작하세요.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 직접 만들기
|
||||||
|
|
||||||
|
기존 BMad 스킬을 web bundle로 바꾸려면 [bmad-utility-skills](https://github.com/bmad-code-org/bmad-utility-skills)의 `bmad-os-skill-to-bundle` 유틸리티 스킬을 사용하세요. 이 스킬은 소유 에이전트에서 페르소나를 상속하고 대비용 교체 목소리 예시를 포함한 번들 파일을 만듭니다. 번들을 카탈로그에 제출하려면 `web-bundles/bundles.json` 항목과 번들 디렉터리를 추가하는 PR을 [BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD)에 여세요.
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
---
|
||||||
|
title: BMad Method에 오신 것을 환영합니다
|
||||||
|
description: 전문 에이전트, 안내형 워크플로, 지능형 계획을 제공하는 AI 기반 개발 프레임워크
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad Method(**B**uild **M**ore **A**rchitect **D**reams)는 BMad Method 생태계에 속한 AI 기반 개발 프레임워크입니다. 아이디어 구상과 계획부터 에이전트 기반 구현까지 소프트웨어 개발 전 과정을 돕습니다. 버그 수정부터 엔터프라이즈 플랫폼 구축까지, 프로젝트 복잡도에 맞춰 전문 AI 에이전트, 안내형 워크플로, 지능형 계획을 제공합니다.
|
||||||
|
|
||||||
|
Claude, Cursor, GitHub Copilot 같은 AI 코딩 어시스턴트로 작업하는 데 익숙하다면 바로 시작할 준비가 된 것입니다.
|
||||||
|
|
||||||
|
:::note[V6가 출시되었습니다. 이제 시작입니다.]
|
||||||
|
스킬 아키텍처, BMad Builder v1, Dev Loop Automation 등 훨씬 많은 기능이 준비 중입니다. [**로드맵 보기**](/ko-kr/roadmap/)
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 처음이라면 튜토리얼부터 시작하세요
|
||||||
|
|
||||||
|
BMad를 가장 빠르게 이해하는 방법은 직접 써보는 것입니다.
|
||||||
|
|
||||||
|
- **[BMad 시작하기](./tutorials/getting-started.md)** - BMad를 설치하고 작동 방식을 이해합니다
|
||||||
|
- **[워크플로 맵](./reference/workflow-map.md)** - BMM 단계, 워크플로, 컨텍스트 관리를 한눈에 보여줍니다
|
||||||
|
|
||||||
|
:::tip[바로 시작하고 싶나요?]
|
||||||
|
BMad를 설치하고 `bmad-help` 스킬을 사용하세요. 프로젝트와 설치된 모듈에 맞춰 모든 과정을 안내합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 이 문서를 사용하는 방법
|
||||||
|
|
||||||
|
이 문서는 하려는 일에 따라 네 가지 섹션으로 구성되어 있습니다.
|
||||||
|
|
||||||
|
| 섹션 | 목적 |
|
||||||
|
| --- | --- |
|
||||||
|
| **튜토리얼** | 학습 중심입니다. 무언가를 만들어 보며 따라가는 단계별 가이드입니다. 처음이라면 여기서 시작하세요. |
|
||||||
|
| **사용 가이드** | 작업 중심입니다. 특정 문제를 해결하기 위한 실용 가이드입니다. "에이전트를 어떻게 커스터마이즈하지?" 같은 질문을 여기서 다룹니다. |
|
||||||
|
| **개념 설명** | 이해 중심입니다. 개념과 아키텍처를 깊게 설명합니다. *왜* 그런지 알고 싶을 때 읽으세요. |
|
||||||
|
| **참조** | 정보 중심입니다. 에이전트, 워크플로, 설정에 대한 기술 사양입니다. |
|
||||||
|
|
||||||
|
## 확장과 커스터마이징
|
||||||
|
|
||||||
|
직접 만든 에이전트, 워크플로, 모듈로 BMad를 확장하고 싶나요? [**BMad Builder**](https://bmad-builder-docs.bmad-method.org/)는 BMad에 새 기능을 더하거나 완전히 새로운 모듈을 만들 수 있는 프레임워크와 도구를 제공합니다.
|
||||||
|
|
||||||
|
## 필요한 것
|
||||||
|
|
||||||
|
BMad는 커스텀 시스템 프롬프트나 프로젝트 컨텍스트를 지원하는 AI 코딩 어시스턴트라면 무엇이든 함께 사용할 수 있습니다. 널리 쓰이는 선택지는 다음과 같습니다.
|
||||||
|
|
||||||
|
- **[Claude Code](https://code.claude.com)** - Anthropic의 CLI 도구(권장)
|
||||||
|
- **[Cursor](https://cursor.sh)** - AI 우선 코드 에디터
|
||||||
|
- **[Codex CLI](https://github.com/openai/codex)** - OpenAI의 터미널 코딩 에이전트
|
||||||
|
|
||||||
|
버전 관리, 프로젝트 구조, 애자일 워크플로 같은 기본 소프트웨어 개발 개념에 익숙하면 좋습니다. BMad 스타일의 에이전트 시스템 경험은 없어도 됩니다. 이 문서가 그 시작점이 되어 줍니다.
|
||||||
|
|
||||||
|
## 커뮤니티 참여
|
||||||
|
|
||||||
|
도움을 받고, 만들고 있는 것을 공유하고, BMad에 기여하세요.
|
||||||
|
|
||||||
|
- **[Discord](https://discord.gg/gk8jAdXWmj)** - 다른 BMad 사용자와 대화하고 질문하고 아이디어를 공유합니다
|
||||||
|
- **[GitHub](https://github.com/bmad-code-org/BMAD-METHOD)** - 소스 코드, 이슈, 기여
|
||||||
|
- **[YouTube](https://www.youtube.com/@BMadCode)** - 영상 튜토리얼과 워크스루
|
||||||
|
|
||||||
|
## 다음 단계
|
||||||
|
|
||||||
|
시작할 준비가 되었나요? [**BMad 시작하기**](./tutorials/getting-started.md)를 열고 첫 프로젝트를 만들어 보세요.
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
title: 에이전트
|
||||||
|
description: 기본 BMM 에이전트와 스킬 ID, 메뉴 트리거, 주요 워크플로
|
||||||
|
sidebar:
|
||||||
|
order: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
## 기본 에이전트
|
||||||
|
|
||||||
|
이 페이지는 BMad Method와 함께 설치되는 기본 BMM(애자일 제품군) 에이전트를 스킬 ID, 메뉴 트리거, 주요 워크플로와 함께 나열합니다. 각 에이전트는 스킬로 호출됩니다.
|
||||||
|
|
||||||
|
## 참고
|
||||||
|
|
||||||
|
- 각 에이전트는 설치 프로그램이 생성하는 스킬로 제공됩니다. 스킬 ID(예: `bmad-agent-dev`)를 사용해 에이전트를 호출합니다.
|
||||||
|
- 트리거는 각 에이전트 메뉴에 표시되는 짧은 메뉴 코드(예: `PRD`)와 유사 매칭 항목입니다.
|
||||||
|
- QA 테스트 생성은 개발자 에이전트를 통해 사용할 수 있는 `bmad-qa-generate-e2e-tests` 워크플로 스킬이 처리합니다. 전체 테스트 설계자(TEA)는 별도 모듈에 있습니다.
|
||||||
|
|
||||||
|
| 에이전트 | 스킬 ID | 트리거 | 주요 워크플로 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 분석가(Mary) | `bmad-agent-analyst` | `BP`, `MR`, `DR`, `TR`, `CB`, `WB`, `DP` | 브레인스토밍, 시장 리서치, 도메인 리서치, 기술 리서치, 개요 작성, PRFAQ 챌린지, 프로젝트 문서화 |
|
||||||
|
| 제품 관리자(John) | `bmad-agent-pm` | `PRD`, `CE`, `IR`, `CC` | PRD 생성/업데이트/검증, 에픽과 스토리 생성, 구현 준비 상태, 방향 수정 |
|
||||||
|
| 아키텍트(Winston) | `bmad-agent-architect` | `CA`, `IR` | 아키텍처 생성, 구현 준비 상태 |
|
||||||
|
| 개발자(Amelia) | `bmad-agent-dev` | `DS`, `QD`, `QA`, `CR`, `SP`, `CS`, `ER`, `IN` | 스토리 구현, 빠른 개발, QA 테스트 생성, 코드 리뷰, 스프린트 계획, 스토리 생성, 에픽 회고, [포렌식 조사](../explanation/forensic-investigation.md) |
|
||||||
|
| UX 디자이너(Sally) | `bmad-agent-ux-designer` | `CU` | UX 설계 생성 |
|
||||||
|
| 기술 작성자(Paige) | `bmad-agent-tech-writer` | `DP`, `WD`, `MG`, `VD`, `EC` | 프로젝트 문서화, 문서 작성, Mermaid 생성, 문서 검증, 개념 설명 |
|
||||||
|
|
||||||
|
## 트리거 유형
|
||||||
|
|
||||||
|
에이전트 메뉴 트리거는 두 가지 호출 방식을 사용합니다. 어떤 유형인지 알면 올바른 입력을 제공하기 쉽습니다.
|
||||||
|
|
||||||
|
### 워크플로 트리거(인수 불필요)
|
||||||
|
|
||||||
|
대부분의 트리거는 구조화된 워크플로 파일을 로드합니다. 트리거 코드를 입력하면 에이전트가 워크플로를 시작하고 각 단계에서 입력을 요청합니다.
|
||||||
|
|
||||||
|
예: `PRD`(PRD 생성, 업데이트 또는 검증), `DS`(스토리 구현), `CA`(아키텍처 생성), `QD`(빠른 개발)
|
||||||
|
|
||||||
|
### 대화형 트리거(인수 필요)
|
||||||
|
|
||||||
|
일부 트리거는 구조화된 워크플로 대신 자유 형식 대화를 시작합니다. 트리거 코드와 함께 필요한 내용을 설명해야 합니다.
|
||||||
|
|
||||||
|
| 에이전트 | 트리거 | 제공할 내용 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 기술 작성자(Paige) | `WD` | 작성할 문서 설명 |
|
||||||
|
| 기술 작성자(Paige) | `MG` | 다이어그램 설명과 유형(시퀀스, 플로차트 등) |
|
||||||
|
| 기술 작성자(Paige) | `VD` | 검증할 문서와 집중 영역 |
|
||||||
|
| 기술 작성자(Paige) | `EC` | 설명할 개념 이름 |
|
||||||
|
|
||||||
|
**예시:**
|
||||||
|
|
||||||
|
```text
|
||||||
|
WD 우리 Docker 설정에 대한 배포 가이드를 작성해 줘
|
||||||
|
MG 인증 흐름을 보여 주는 시퀀스 다이어그램을 만들어 줘
|
||||||
|
EC 모듈 시스템이 어떻게 작동하는지 설명해 줘
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
---
|
||||||
|
title: 스킬
|
||||||
|
description: BMad 스킬의 정의, 작동 방식, 위치에 대한 참조
|
||||||
|
sidebar:
|
||||||
|
order: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
스킬은 IDE 안에서 에이전트를 로드하거나 워크플로를 실행하거나 작업을 처리하는 미리 작성된 프롬프트입니다. BMad 설치 프로그램은 설치 시 선택한 모듈에서 스킬을 생성합니다. 나중에 모듈을 추가, 제거, 변경했다면 설치 프로그램을 다시 실행해 스킬을 동기화하세요([문제 해결](#문제-해결) 참고).
|
||||||
|
|
||||||
|
## 스킬 vs 에이전트 메뉴 트리거
|
||||||
|
|
||||||
|
BMad는 작업을 시작하는 두 가지 방법을 제공하며 목적이 다릅니다.
|
||||||
|
|
||||||
|
| 방식 | 호출 방법 | 일어나는 일 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| **스킬** | IDE에서 스킬 이름(예: `bmad-help`)을 입력 | 에이전트를 직접 로드하거나 워크플로를 실행하거나 작업을 처리 |
|
||||||
|
| **에이전트 메뉴 트리거** | 에이전트를 먼저 로드한 뒤 짧은 코드(예: `DS`) 입력 | 에이전트가 페르소나를 유지한 채 코드를 해석하고 일치하는 워크플로를 시작 |
|
||||||
|
|
||||||
|
에이전트 메뉴 트리거는 활성 에이전트 세션이 필요합니다. 어떤 워크플로를 원하는지 알고 있다면 스킬을 사용하세요. 이미 에이전트와 작업 중이고 대화를 떠나지 않고 작업을 바꾸고 싶다면 트리거를 사용하세요.
|
||||||
|
|
||||||
|
## 스킬 생성 방식
|
||||||
|
|
||||||
|
`npx bmad-method install`을 실행하면 설치 프로그램은 선택된 모든 모듈의 매니페스트를 읽고 에이전트, 워크플로, 작업, 도구마다 하나의 스킬을 작성합니다. 각 스킬은 AI에게 해당 소스 파일을 로드하고 지시를 따르라고 안내하는 `SKILL.md` 파일이 있는 폴더입니다.
|
||||||
|
|
||||||
|
설치 프로그램은 스킬 유형별 템플릿을 사용합니다.
|
||||||
|
|
||||||
|
| 스킬 유형 | 생성 파일의 역할 |
|
||||||
|
| --- | --- |
|
||||||
|
| **에이전트 실행기** | 에이전트 페르소나 파일을 로드하고 메뉴를 활성화하며 페르소나를 유지 |
|
||||||
|
| **워크플로 스킬** | 워크플로 설정을 로드하고 단계를 따름 |
|
||||||
|
| **작업 스킬** | 단독 실행 작업 파일을 로드하고 지시를 따름 |
|
||||||
|
| **도구 스킬** | 단독 실행 도구 파일을 로드하고 지시를 따름 |
|
||||||
|
|
||||||
|
:::note[설치 프로그램 다시 실행]
|
||||||
|
모듈을 추가하거나 제거했다면 설치 프로그램을 다시 실행하세요. 현재 모듈 선택에 맞춰 모든 스킬 파일을 다시 생성합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 스킬 파일 위치
|
||||||
|
|
||||||
|
설치 프로그램은 프로젝트 안의 IDE별 디렉터리에 스킬 파일을 씁니다. 정확한 경로는 설치 중 선택한 IDE에 따라 달라집니다.
|
||||||
|
|
||||||
|
| IDE / CLI | Skills 디렉터리 |
|
||||||
|
| --- | --- |
|
||||||
|
| Claude Code | `.claude/skills/` |
|
||||||
|
| Cursor | `.agents/skills/` |
|
||||||
|
| Windsurf | `.agents/skills/` |
|
||||||
|
| 기타 IDE | 대상 경로는 설치 프로그램 출력 참고 |
|
||||||
|
|
||||||
|
각 스킬은 `SKILL.md` 파일을 포함하는 폴더입니다. Claude Code 설치 예시는 다음과 같습니다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
.claude/skills/
|
||||||
|
├── bmad-help/
|
||||||
|
│ └── SKILL.md
|
||||||
|
├── bmad-prd/
|
||||||
|
│ └── SKILL.md
|
||||||
|
├── bmad-agent-dev/
|
||||||
|
│ └── SKILL.md
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
디렉터리 이름이 IDE에서의 스킬 이름을 결정합니다. 예를 들어 `bmad-agent-dev/` 디렉터리는 `bmad-agent-dev` 스킬을 등록합니다.
|
||||||
|
|
||||||
|
## 스킬 찾기
|
||||||
|
|
||||||
|
IDE에서 스킬 이름을 입력해 호출합니다. 일부 플랫폼은 스킬이 나타나기 전에 설정에서 활성화해야 합니다.
|
||||||
|
|
||||||
|
다음 단계를 상황에 맞게 안내받으려면 `bmad-help`를 실행하세요.
|
||||||
|
|
||||||
|
:::tip[빠른 탐색]
|
||||||
|
프로젝트에 생성된 스킬 디렉터리가 기준 목록입니다. 파일 탐색기에서 열면 설명이 있는 모든 스킬을 볼 수 있습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 스킬 범주
|
||||||
|
|
||||||
|
### 에이전트 스킬
|
||||||
|
|
||||||
|
에이전트 스킬은 정의된 역할, 커뮤니케이션 스타일, 워크플로 메뉴를 가진 전문 AI 페르소나를 로드합니다. 로드되면 에이전트는 페르소나를 유지하고 메뉴 트리거에 응답합니다.
|
||||||
|
|
||||||
|
| 예시 스킬 | 에이전트 | 역할 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `bmad-agent-dev` | Amelia(개발자) | 사양을 엄격히 준수해 스토리 구현 |
|
||||||
|
| `bmad-agent-pm` | John(제품 관리자) | PRD 생성 및 검증 |
|
||||||
|
| `bmad-agent-architect` | Winston(아키텍트) | 시스템 아키텍처 설계 |
|
||||||
|
|
||||||
|
기본 에이전트와 트리거 전체 목록은 [에이전트](./agents.md)를 참고하세요.
|
||||||
|
|
||||||
|
### 워크플로 스킬
|
||||||
|
|
||||||
|
워크플로 스킬은 에이전트 페르소나를 먼저 로드하지 않고 구조화된 다단계 프로세스를 실행합니다. 워크플로 설정을 로드하고 단계를 따릅니다.
|
||||||
|
|
||||||
|
| 예시 스킬 | 목적 |
|
||||||
|
| --- | --- |
|
||||||
|
| `bmad-product-brief` | 제품 개요 생성 또는 업데이트 - 개념이 명확할 때 안내형 발견 |
|
||||||
|
| `bmad-prfaq` | 제품 개념을 스트레스 테스트하는 [워킹 백워드 PRFAQ](../explanation/analysis-phase.md#prfaq-working-backwards) 챌린지 |
|
||||||
|
| `bmad-prd` | 제품 요구사항 문서(PRD) 생성, 업데이트, 검증 |
|
||||||
|
| `bmad-ux` | 사용자 경험 설계 |
|
||||||
|
| `bmad-create-architecture` | 시스템 아키텍처 설계 |
|
||||||
|
| `bmad-create-epics-and-stories` | 에픽과 스토리 생성 |
|
||||||
|
| `bmad-dev-story` | 스토리 구현 |
|
||||||
|
| `bmad-code-review` | 코드 리뷰 실행 |
|
||||||
|
| `bmad-quick-dev` | 통합 빠른 흐름 - 의도 정리, 계획, 구현, 리뷰, 발표 |
|
||||||
|
|
||||||
|
단계별 전체 워크플로 참조는 [워크플로 맵](./workflow-map.md)을 참고하세요.
|
||||||
|
|
||||||
|
### 작업과 도구 스킬
|
||||||
|
|
||||||
|
작업과 도구는 에이전트나 워크플로 컨텍스트 없이 실행되는 단독 작업입니다.
|
||||||
|
|
||||||
|
**BMad 도움말: 지능형 안내자**
|
||||||
|
|
||||||
|
`bmad-help`는 다음에 무엇을 해야 할지 찾는 기본 인터페이스입니다. 프로젝트를 검사하고, 자연어 쿼리를 이해하며, 설치된 모듈을 기준으로 다음 필수 또는 선택 단계를 추천합니다.
|
||||||
|
|
||||||
|
:::note[예시]
|
||||||
|
```
|
||||||
|
bmad-help
|
||||||
|
bmad-help SaaS 아이디어가 있고 기능도 모두 알고 있습니다. 어디서 시작하나요?
|
||||||
|
bmad-help UX 설계에는 어떤 선택지가 있나요?
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
**기타 핵심 작업과 도구**
|
||||||
|
|
||||||
|
핵심 모듈에는 스펙, 리뷰, 브레인스토밍, 커스터마이징, 문서 관리 등 12개의 내장 도구가 포함됩니다. 전체 참조는 [핵심 도구](./core-tools.md)를 참고하세요.
|
||||||
|
|
||||||
|
## 이름 규칙
|
||||||
|
|
||||||
|
모든 스킬은 `bmad-` 접두사 뒤에 설명적인 이름을 붙입니다(예: `bmad-agent-dev`, `bmad-prd`, `bmad-help`). 사용 가능한 모듈은 [모듈](./modules.md)을 참고하세요.
|
||||||
|
|
||||||
|
## 문제 해결
|
||||||
|
|
||||||
|
**설치 후 스킬이 보이지 않음.** 일부 플랫폼은 설정에서 스킬을 명시적으로 활성화해야 합니다. IDE 문서를 확인하거나 AI 어시스턴트에게 스킬 활성화 방법을 물어보세요. IDE 재시작 또는 창 새로고침이 필요할 수도 있습니다.
|
||||||
|
|
||||||
|
**예상한 스킬이 없음.** 설치 프로그램은 선택한 모듈의 스킬만 생성합니다. `npx bmad-method install`을 다시 실행하고 모듈 선택을 확인하세요. 예상 디렉터리에 스킬 파일이 있는지 확인하세요.
|
||||||
|
|
||||||
|
**제거한 모듈의 스킬이 계속 보임.** 설치 프로그램은 오래된 스킬 파일을 자동으로 삭제하지 않습니다. IDE 스킬 디렉터리에서 오래된 디렉터리를 제거하거나 전체 스킬 디렉터리를 삭제한 뒤 설치 프로그램을 다시 실행해 깨끗한 스킬 세트를 만드세요.
|
||||||
|
|
@ -0,0 +1,321 @@
|
||||||
|
---
|
||||||
|
title: 핵심 도구
|
||||||
|
description: 추가 모듈 없이 모든 BMad 설치에서 사용할 수 있는 내장 작업과 워크플로 참조
|
||||||
|
sidebar:
|
||||||
|
order: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
모든 BMad 설치에는 어떤 작업을 하든 함께 사용할 수 있는 핵심 스킬 모음이 포함됩니다. 모든 프로젝트, 모든 모듈, 모든 단계에서 단독으로 실행할 수 있는 작업과 워크플로입니다. 어떤 선택 모듈을 설치했든 항상 사용할 수 있습니다.
|
||||||
|
|
||||||
|
:::tip[빠른 경로]
|
||||||
|
IDE에서 스킬 이름(예: `bmad-help`)을 입력해 어떤 핵심 도구든 실행하세요. 에이전트 세션은 필요 없습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
| 도구 | 유형 | 목적 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| [`bmad-help`](#bmad-help) | 작업 | 다음에 무엇을 해야 할지 상황에 맞게 안내 |
|
||||||
|
| [`bmad-brainstorming`](#bmad-brainstorming) | 워크플로 | 대화형 브레인스토밍 세션 진행 |
|
||||||
|
| [`bmad-party-mode`](#bmad-party-mode) | 워크플로 | 다중 에이전트 그룹 토론 조율 |
|
||||||
|
| [`bmad-spec`](#bmad-spec) | 워크플로 | 모든 의도 입력을 후속 작업의 표준 계약인 SPEC 커널과 동반 파일로 정제 |
|
||||||
|
| [`bmad-advanced-elicitation`](#bmad-advanced-elicitation) | 작업 | LLM 출력을 반복 개선 방식으로 끌어올림 |
|
||||||
|
| [`bmad-review-adversarial-general`](#bmad-review-adversarial-general) | 작업 | 빠진 것과 틀린 것을 찾는 비판적 리뷰 |
|
||||||
|
| [`bmad-review-edge-case-hunter`](#bmad-review-edge-case-hunter) | 작업 | 처리되지 않은 엣지 케이스를 찾기 위한 철저한 분기 경로 분석 |
|
||||||
|
| [`bmad-editorial-review-prose`](#bmad-editorial-review-prose) | 작업 | 전달 명확성을 위한 엄격한 문장 교정 |
|
||||||
|
| [`bmad-editorial-review-structure`](#bmad-editorial-review-structure) | 작업 | 구조 편집 - 삭제, 병합, 재구성 |
|
||||||
|
| [`bmad-shard-doc`](#bmad-shard-doc) | 작업 | 큰 Markdown 파일을 정리된 섹션으로 분할 |
|
||||||
|
| [`bmad-index-docs`](#bmad-index-docs) | 작업 | 폴더 내 모든 문서 색인 생성 또는 업데이트 |
|
||||||
|
| [`bmad-customize`](#bmad-customize) | 작업 | BMad 커스터마이징 오버라이드 생성 및 검증 |
|
||||||
|
|
||||||
|
## bmad-help
|
||||||
|
|
||||||
|
**다음에 무엇을 해야 할지 알려주는 지능형 안내자입니다.** 프로젝트 상태를 검사하고, 완료된 것을 감지하며, 다음 필수 또는 선택 단계를 추천합니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 워크플로를 끝냈고 다음 단계를 알고 싶습니다
|
||||||
|
- BMad가 처음이라 방향 안내가 필요합니다
|
||||||
|
- 막혀서 상황에 맞는 조언이 필요합니다
|
||||||
|
- 새 모듈을 설치했고 사용할 수 있는 것을 보고 싶습니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 프로젝트에서 기존 산출물(PRD, 아키텍처, 스토리 등)를 스캔합니다
|
||||||
|
2. 설치된 모듈과 사용 가능한 워크플로를 감지합니다
|
||||||
|
3. 우선순위 순서로 다음 단계를 추천합니다. 필수 단계를 먼저, 선택 단계를 나중에 제시합니다
|
||||||
|
4. 각 추천을 스킬 명령과 짧은 설명으로 보여줍니다
|
||||||
|
|
||||||
|
**입력:** 자연어 선택 쿼리(예: `bmad-help SaaS 아이디어가 있는데 어디서 시작하나요?`)
|
||||||
|
|
||||||
|
**출력:** 스킬 명령이 포함된 권장 다음 단계의 우선순위 목록
|
||||||
|
|
||||||
|
## bmad-brainstorming
|
||||||
|
|
||||||
|
**대화형 창의 기법으로 다양한 아이디어를 생성합니다.** 기법 라이브러리에서 검증된 아이디어 발상법을 로드하고 100개 이상의 아이디어를 향해 안내한 뒤 정리하는 브레인스토밍 세션입니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 새 프로젝트를 시작하고 문제 영역을 탐색해야 합니다
|
||||||
|
- 아이디어 생성이 막혀 구조화된 창의 기법이 필요합니다
|
||||||
|
- SCAMPER, 역브레인스토밍 같은 검증된 아이디어 발상 프레임워크를 사용하고 싶습니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 주제로 브레인스토밍 세션을 설정합니다
|
||||||
|
2. 기법 라이브러리에서 창의 기법을 로드합니다
|
||||||
|
3. 기법을 하나씩 진행하며 아이디어를 생성합니다
|
||||||
|
4. 편향 방지 프로토콜을 적용합니다. 10개 아이디어마다 창의 영역을 바꿔 군집화를 방지합니다
|
||||||
|
5. 모든 아이디어를 기법별로 정리한 추가 전용 세션 문서를 만듭니다
|
||||||
|
|
||||||
|
**입력:** 브레인스토밍 주제 또는 문제 설명, 선택 사항 컨텍스트 파일
|
||||||
|
|
||||||
|
**출력:** 생성된 모든 아이디어가 담긴 `brainstorming-session-{date}.md`
|
||||||
|
|
||||||
|
:::note[수량 목표]
|
||||||
|
핵심은 아이디어 50-100개 지점에서 나옵니다. 이 워크플로는 정리 전에 100개 이상의 아이디어 생성을 권장합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## bmad-party-mode
|
||||||
|
|
||||||
|
**다중 에이전트 그룹 토론을 조율합니다.** 설치된 모든 BMad 에이전트를 로드하고 각 에이전트가 고유한 전문성과 페르소나로 기여하는 자연스러운 대화를 진행합니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 결정에 여러 전문가 관점이 필요합니다
|
||||||
|
- 에이전트들이 서로의 가정에 도전하길 원합니다
|
||||||
|
- 여러 도메인에 걸친 복잡한 주제를 탐색합니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 설치된 모든 에이전트 페르소나가 있는 에이전트 매니페스트를 로드합니다
|
||||||
|
2. 주제를 분석해 가장 관련 있는 에이전트 2-3개를 선택합니다
|
||||||
|
3. 에이전트들이 턴을 나눠 기여하고 자연스러운 상호 대화와 의견 차이를 만듭니다
|
||||||
|
4. 시간이 지나며 참여 에이전트를 순환해 다양한 관점을 보장합니다
|
||||||
|
5. `goodbye`, `end party`, `quit`로 종료합니다
|
||||||
|
|
||||||
|
**입력:** 토론 주제 또는 질문, 참여시키고 싶은 페르소나 지정(선택 사항)
|
||||||
|
|
||||||
|
**출력:** 에이전트 페르소나가 유지되는 실시간 다중 에이전트 대화
|
||||||
|
|
||||||
|
## bmad-spec
|
||||||
|
|
||||||
|
**모든 의도 입력을 후속 작업의 표준 SPEC 계약으로 정제합니다.** 간단한 아이디어, PRD, GDD, RFC, 브레인 덤프, 회의록, UX 폴더, 여러 소스가 섞인 입력을 받아 다섯 필드 커널(Why, Capabilities, Constraints, Non-goals, Success signal)을 담은 `SPEC.md`와 커널에 들어가지 않는 핵심 내용을 위한 동반 파일을 만듭니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 소프트웨어, 게임 디자인, 리서치, 편집, 정책, 비즈니스 등 어떤 작업이든 HOW 전에 WHAT을 고정해야 합니다.
|
||||||
|
- 후속 스킬이 모든 상위 산출물을 다시 읽지 않고도 소비할 수 있는 간결하고 군더더기 없는 LLM 최적화 계약이 필요합니다.
|
||||||
|
- 기존 spec을 검증하거나 업데이트하고 싶습니다.
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 입력과 연결된 보조 자료를 읽습니다.
|
||||||
|
2. 설정 가능한 템플릿으로 다섯 필드 커널을 정제하고, 넘치는 내용은 적절한 이름의 동반 파일로 보냅니다.
|
||||||
|
3. 두 단계 자체 검증을 실행합니다. 먼저 일관성 규칙을 확인하고, 다음으로 모든 핵심 소스 주장이 보존됐는지 확인합니다.
|
||||||
|
4. `{output_folder}/specs/spec-{slug}/` 아래에 `SPEC.md`, 동반 파일, `.decision-log.md`를 씁니다.
|
||||||
|
|
||||||
|
Spec Law는 여덟 가지 규칙을 강제합니다. capabilities는 의도와 성공 기준을 모두 담고, intents는 HOW가 아니라 WHAT이며, constraints는 실제 의사결정에 영향을 주고, non-goals는 명시적이며, success signals는 구체적이고, capability ID는 안정적이며, 모든 핵심 소스 주장은 보존되고, 문장은 간결해야 합니다.
|
||||||
|
|
||||||
|
**입력:**
|
||||||
|
|
||||||
|
- `input`(필수) - 경로 또는 인라인 텍스트. 모호한 아이디어, 브레인 덤프, PRD, GDD, RFC, brief, transcript, mockup 폴더, 여러 소스 조합.
|
||||||
|
- `slug`(선택 사항) - 입력이 빈약하고 소스 파일명에서 slug를 만들 수 없을 때만 필요합니다.
|
||||||
|
- `target_spec_path`(선택 사항) - 새 spec을 만드는 대신 기존 spec을 업데이트할 때 설정합니다.
|
||||||
|
|
||||||
|
**출력:** `SPEC.md`, 동반 파일, `.decision-log.md`가 들어 있는 spec 폴더. Headless 호출자는 결과 상태와 작성 또는 수정된 파일 목록을 담은 JSON 응답을 받습니다.
|
||||||
|
|
||||||
|
:::note[변경 계약]
|
||||||
|
`bmad-spec`은 `SPEC.md`와 spec이 작성한 동반 파일을 쓸 수 있는 유일한 도구입니다. 다른 스킬은 자체 네이티브 산출물을 만들고, 의도를 표준 계약으로 표현하거나 업데이트를 제안해야 할 때 headless 모드로 `bmad-spec`을 호출합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## bmad-advanced-elicitation
|
||||||
|
|
||||||
|
**LLM 출력을 반복 개선 방식으로 개선합니다.** 도출 기법 라이브러리에서 선택해 여러 차례에 걸쳐 내용을 체계적으로 개선합니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- LLM 출력이 얕거나 일반적으로 느껴집니다
|
||||||
|
- 여러 분석 관점에서 주제를 탐색하고 싶습니다
|
||||||
|
- 중요한 문서를 다듬고 더 깊은 사고가 필요합니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 5개 이상의 도출 기법이 있는 기법 레지스트리를 로드합니다
|
||||||
|
2. 내용 유형과 복잡도에 가장 잘 맞는 기법 5개를 선택합니다
|
||||||
|
3. 대화형 메뉴를 제시합니다. 기법 선택, 다시 섞기, 전체 목록 보기가 가능합니다
|
||||||
|
4. 선택한 기법을 적용해 내용을 강화합니다
|
||||||
|
5. "진행"을 선택할 때까지 반복 개선 옵션을 다시 제시합니다
|
||||||
|
|
||||||
|
**입력:** 강화할 내용 섹션
|
||||||
|
|
||||||
|
**출력:** 개선이 적용된 버전
|
||||||
|
|
||||||
|
## bmad-review-adversarial-general
|
||||||
|
|
||||||
|
**문제가 있다고 가정하고 찾는 비판적 리뷰입니다.** 허술한 작업을 용납하지 않는 회의적인 리뷰어의 관점을 취합니다. 틀린 것뿐 아니라 빠진 것을 찾습니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 산출물 확정 전 품질 보증이 필요합니다
|
||||||
|
- 사양, 스토리, 문서를 스트레스 테스트하고 싶습니다
|
||||||
|
- 낙관적인 리뷰가 놓치는 검토 공백을 찾고 싶습니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 냉정하고 비판적인 관점으로 내용을 읽습니다
|
||||||
|
2. 완전성, 정확성, 품질 전반의 이슈를 식별합니다
|
||||||
|
3. 존재하지만 잘못된 것만이 아니라 빠진 것을 특히 찾습니다
|
||||||
|
4. 최소 10개 이슈를 찾아야 하며, 부족하면 더 깊게 재분석합니다
|
||||||
|
|
||||||
|
**입력:**
|
||||||
|
|
||||||
|
- `content`(필수) - diff, 사양, 스토리, 문서 또는 모든 산출물
|
||||||
|
- `also_consider`(선택 사항) - 추가로 염두에 둘 영역
|
||||||
|
|
||||||
|
**출력:** 설명이 있는 10개 이상의 발견 사항 Markdown 목록
|
||||||
|
|
||||||
|
## bmad-review-edge-case-hunter
|
||||||
|
|
||||||
|
**모든 분기 경로와 경계 조건을 따라가며 처리되지 않은 사례만 보고합니다.** 엣지 케이스 유형을 기계적으로 도출하는 순수 경로 추적 기법입니다. 적대적 리뷰와 상호 보완적이며, 태도 기반이 아니라 기법 기반입니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 코드나 로직에 대한 철저한 엣지 케이스 검토가 필요합니다
|
||||||
|
- 적대적 리뷰를 보완하고 싶습니다(다른 기법, 다른 발견 사항)
|
||||||
|
- 경계 조건을 확인하기 위해 diff나 함수를 리뷰합니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 내용의 모든 분기 경로를 열거합니다
|
||||||
|
2. 누락된 else/기본값, 보호되지 않은 입력, off-by-one, 산술 오버플로, 암시적 타입 강제 변환, 경쟁 상태, 타임아웃 공백 같은 엣지 케이스 유형을 기계적으로 도출합니다
|
||||||
|
3. 각 경로를 기존 방어 로직과 대조합니다
|
||||||
|
4. 처리되지 않은 경로만 보고합니다. 이미 처리된 경로는 조용히 버립니다
|
||||||
|
|
||||||
|
**입력:**
|
||||||
|
|
||||||
|
- `content`(필수) - diff, 전체 파일, 함수
|
||||||
|
- `also_consider`(선택 사항) - 추가로 염두에 둘 영역
|
||||||
|
|
||||||
|
**출력:** 각 발견 사항이 `location`, `trigger_condition`, `guard_snippet`, `potential_consequence`를 포함하는 JSON 배열
|
||||||
|
|
||||||
|
:::note[상호 보완 리뷰]
|
||||||
|
상호 보완적 검토를 위해 `bmad-review-adversarial-general`과 `bmad-review-edge-case-hunter`를 함께 실행하세요. 적대적 리뷰는 품질과 완전성 이슈를 잡고, 엣지 케이스 헌터는 처리되지 않은 경로를 잡습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## bmad-editorial-review-prose
|
||||||
|
|
||||||
|
**전달 명확성에 집중한 엄격한 문장 교정입니다.** 이해를 방해하는 문장 문제를 리뷰합니다. Microsoft Writing Style Guide 기준을 적용하고 작성자 목소리를 보존합니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 문서를 초안으로 작성했고 문장을 다듬고 싶습니다
|
||||||
|
- 특정 독자를 위한 명확성을 보장해야 합니다
|
||||||
|
- 취향 기반 수정 없이 전달만 개선하고 싶습니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 코드 블록과 프런트매터를 건너뛰고 내용을 읽습니다
|
||||||
|
2. 스타일 선호가 아닌 전달 이슈를 식별합니다
|
||||||
|
3. 여러 위치의 같은 이슈를 중복 제거합니다
|
||||||
|
4. 세 열 수정 테이블을 생성합니다
|
||||||
|
|
||||||
|
**입력:**
|
||||||
|
|
||||||
|
- `content`(필수) - Markdown, 일반 텍스트, XML
|
||||||
|
- `style_guide`(선택 사항) - 프로젝트별 스타일 가이드
|
||||||
|
- `reader_type`(선택 사항) - 명확성/흐름용 `humans`(기본값) 또는 정밀도/일관성용 `llm`
|
||||||
|
|
||||||
|
**출력:** 세 열 Markdown 테이블: `Original Text | Revised Text | Changes`
|
||||||
|
|
||||||
|
## bmad-editorial-review-structure
|
||||||
|
|
||||||
|
**구조 편집입니다. 삭제, 병합, 이동, 압축을 제안합니다.** 문장 교정 전에 문서 구성을 리뷰하고 명확성과 흐름을 개선하는 실질적 변경을 제안합니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 여러 하위 프로세스에서 생성된 문서에 구조적 일관성이 필요합니다
|
||||||
|
- 이해도를 유지하면서 문서 길이를 줄이고 싶습니다
|
||||||
|
- 범위 위반이나 묻힌 핵심 정보를 식별해야 합니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 5개 구조 모델(튜토리얼, 참조, 설명, 프롬프트, 전략)에 대해 문서를 분석합니다
|
||||||
|
2. 중복, 범위 위반, 묻힌 정보를 식별합니다
|
||||||
|
3. 우선순위 권장 사항을 생성합니다: `CUT`, `MERGE`, `MOVE`, `CONDENSE`, `QUESTION`, `PRESERVE`
|
||||||
|
4. 총 단어 감소량과 감소율을 추정합니다
|
||||||
|
|
||||||
|
**입력:**
|
||||||
|
|
||||||
|
- `content`(필수) - 리뷰할 문서
|
||||||
|
- `purpose`(선택 사항) - 의도한 목적(예: "빠른 시작 튜토리얼")
|
||||||
|
- `target_audience`(선택 사항) - 독자
|
||||||
|
- `reader_type`(선택 사항) - `humans` 또는 `llm`
|
||||||
|
- `length_target`(선택 사항) - 목표 감소량(예: "30% 줄이기")
|
||||||
|
|
||||||
|
**출력:** 문서 요약, 우선순위 권장 사항 목록, 예상 감소량
|
||||||
|
|
||||||
|
## bmad-shard-doc
|
||||||
|
|
||||||
|
**큰 Markdown 파일을 정리된 섹션 파일로 나눕니다.** 2단계 헤더를 분할 지점으로 사용해 독립적인 섹션 파일과 색인이 있는 폴더를 만듭니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- Markdown 문서가 너무 커져 효과적으로 관리하기 어렵습니다(500줄 이상)
|
||||||
|
- 단일 문서를 탐색 가능한 섹션으로 나누고 싶습니다
|
||||||
|
- 병렬 편집 또는 LLM 컨텍스트 관리를 위해 별도 파일이 필요합니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 소스 파일이 존재하고 Markdown인지 검증합니다
|
||||||
|
2. 2단계(`##`) 헤더 기준으로 번호가 붙은 섹션 파일로 나눕니다
|
||||||
|
3. 섹션 매니페스트와 링크가 있는 `index.md`를 만듭니다
|
||||||
|
4. 원본을 삭제, 보관, 유지할지 묻습니다
|
||||||
|
|
||||||
|
**입력:** 소스 Markdown 파일 경로, 선택 사항 대상 폴더
|
||||||
|
|
||||||
|
**출력:** `index.md`와 `01-{section}.md`, `02-{section}.md` 등이 있는 폴더
|
||||||
|
|
||||||
|
## bmad-index-docs
|
||||||
|
|
||||||
|
**폴더의 모든 문서 색인을 생성하거나 업데이트합니다.** 디렉터리를 스캔하고 각 파일을 읽어 목적을 이해한 뒤 링크와 설명이 있는 정리된 `index.md`를 만듭니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 사용 가능한 문서를 LLM이 빠르게 스캔할 수 있는 가벼운 색인이 필요합니다
|
||||||
|
- 문서 폴더가 커져 정리된 목차가 필요합니다
|
||||||
|
- 최신 상태를 유지하는 자동 생성 개요를 원합니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 대상 디렉터리에서 숨김이 아닌 파일을 모두 스캔합니다
|
||||||
|
2. 각 파일을 읽어 실제 목적을 이해합니다
|
||||||
|
3. 유형, 목적, 하위 디렉터리 기준으로 파일을 그룹화합니다
|
||||||
|
4. 간결한 설명(각 3-10단어)을 생성합니다
|
||||||
|
|
||||||
|
**입력:** 대상 폴더 경로
|
||||||
|
|
||||||
|
**출력:** 정리된 파일 목록, 상대 링크, 짧은 설명이 있는 `index.md`
|
||||||
|
|
||||||
|
## bmad-customize
|
||||||
|
|
||||||
|
**커스터마이징 오버라이드를 만들고 검증합니다.** TOML을 직접 작성하지 않고도 설치된 BMad 에이전트나 워크플로의 동작을 바꿀 수 있게 도와줍니다.
|
||||||
|
|
||||||
|
**사용 시점:**
|
||||||
|
|
||||||
|
- 에이전트나 워크플로 동작을 바꾸고 싶습니다
|
||||||
|
- 지속 사실, 활성화 훅, 커스텀 메뉴 항목을 추가해야 합니다
|
||||||
|
- 올바른 오버라이드 범위를 자동으로 선택하고 검증하고 싶습니다
|
||||||
|
|
||||||
|
**작동 방식:**
|
||||||
|
|
||||||
|
1. 설치된 BMad 스킬에서 커스터마이징 가능한 영역을 스캔합니다
|
||||||
|
2. 요청한 변경에 맞는 범위를 선택합니다
|
||||||
|
3. `_bmad/custom/` 아래에 오버라이드 파일을 작성합니다
|
||||||
|
4. 병합된 설정을 검증합니다
|
||||||
|
|
||||||
|
**입력:** 원하는 커스터마이징을 설명하는 자연어
|
||||||
|
|
||||||
|
**출력:** `_bmad/custom/` 아래의 TOML 오버라이드 파일
|
||||||
|
|
||||||
|
BMad 커스터마이징에 대한 자세한 가이드는 [BMad 커스터마이징 방법](../how-to/customize-bmad.md)을 참고하세요.
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
---
|
||||||
|
title: 공식 모듈
|
||||||
|
description: 커스텀 에이전트, 창의적 지능, 게임 개발, 테스트를 위한 추가 모듈
|
||||||
|
sidebar:
|
||||||
|
order: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad는 설치 중 선택하는 공식 모듈로 확장됩니다. 이러한 추가 모듈은 내장 핵심 기능과 BMM(애자일 제품군)을 넘어 특정 도메인을 위한 전문 에이전트, 워크플로, 작업을 제공합니다.
|
||||||
|
|
||||||
|
:::tip[모듈 설치]
|
||||||
|
`npx bmad-method install`을 실행하고 원하는 모듈을 선택하세요. 설치 프로그램이 다운로드, 설정, IDE 통합을 자동으로 처리합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## BMad 빌더(BMB)
|
||||||
|
|
||||||
|
안내형 도구를 사용해 커스텀 에이전트, 워크플로, 도메인 특화 모듈을 만듭니다. BMad 빌더는 프레임워크 자체를 확장하는 메타 모듈입니다.
|
||||||
|
|
||||||
|
- **코드:** `bmb`
|
||||||
|
- **npm:** [`bmad-builder`](https://www.npmjs.com/package/bmad-builder)
|
||||||
|
- **GitHub:** [bmad-code-org/bmad-builder](https://github.com/bmad-code-org/bmad-builder)
|
||||||
|
|
||||||
|
**제공:**
|
||||||
|
|
||||||
|
- 에이전트 빌더 - 커스텀 전문성과 도구 접근 권한이 있는 전문 AI 에이전트 생성
|
||||||
|
- 워크플로 빌더 - 단계와 결정 지점이 있는 구조화된 프로세스 설계
|
||||||
|
- 모듈 빌더 - 에이전트와 워크플로를 공유 및 게시 가능한 모듈로 패키징
|
||||||
|
- YAML 설정과 npm 게시 지원이 있는 대화형 설정
|
||||||
|
|
||||||
|
## 창의적 지능 제품군(CIS)
|
||||||
|
|
||||||
|
초기 개발 단계의 구조화된 창의성, 아이디어 발상, 혁신을 위한 AI 기반 도구입니다. 이 제품군은 검증된 프레임워크를 사용해 브레인스토밍, 디자인 사고, 문제 해결을 진행하는 여러 에이전트를 제공합니다.
|
||||||
|
|
||||||
|
- **코드:** `cis`
|
||||||
|
- **npm:** [`bmad-creative-intelligence-suite`](https://www.npmjs.com/package/bmad-creative-intelligence-suite)
|
||||||
|
- **GitHub:** [bmad-code-org/bmad-module-creative-intelligence-suite](https://github.com/bmad-code-org/bmad-module-creative-intelligence-suite)
|
||||||
|
|
||||||
|
**제공:**
|
||||||
|
|
||||||
|
- 혁신 전략가, 디자인 사고 코치, 브레인스토밍 코치 에이전트
|
||||||
|
- 체계적 사고와 수평적 사고를 위한 문제 해결자와 창의적 문제 해결자
|
||||||
|
- 내러티브와 피치를 위한 스토리텔러와 발표 마스터
|
||||||
|
- SCAMPER, 역브레인스토밍, 문제 재구성을 포함한 아이디어 발상 프레임워크
|
||||||
|
|
||||||
|
## 게임 개발 스튜디오(BMGD)
|
||||||
|
|
||||||
|
Unity, Unreal, Godot, 커스텀 엔진에 맞춘 구조화된 게임 개발 워크플로입니다. 빠른 흐름을 통한 신속한 프로토타이핑과 에픽 중심 스프린트를 통한 전체 규모 제작을 지원합니다.
|
||||||
|
|
||||||
|
- **코드:** `gds`
|
||||||
|
- **npm:** [`bmad-game-dev-studio`](https://www.npmjs.com/package/bmad-game-dev-studio)
|
||||||
|
- **GitHub:** [bmad-code-org/bmad-module-game-dev-studio](https://github.com/bmad-code-org/bmad-module-game-dev-studio)
|
||||||
|
|
||||||
|
**제공:**
|
||||||
|
|
||||||
|
- 게임 디자인 문서 생성 워크플로
|
||||||
|
- 신속한 프로토타이핑을 위한 빠른 개발 모드
|
||||||
|
- 캐릭터, 대화, 세계관 구축을 위한 내러티브 디자인 지원
|
||||||
|
- 21개 이상 게임 유형과 엔진별 아키텍처 가이드 지원
|
||||||
|
|
||||||
|
## 테스트 설계자(TEA)
|
||||||
|
|
||||||
|
전문가 에이전트와 9개의 구조화된 워크플로를 통해 엔터프라이즈급 테스트 전략, 자동화 가이드, 릴리스 게이트 결정을 지원합니다. TEA는 위험 기반 우선순위와 요구사항 추적성으로 내장 QA 에이전트를 크게 넘어섭니다.
|
||||||
|
|
||||||
|
- **코드:** `tea`
|
||||||
|
- **npm:** [`bmad-method-test-architecture-enterprise`](https://www.npmjs.com/package/bmad-method-test-architecture-enterprise)
|
||||||
|
- **GitHub:** [bmad-code-org/bmad-method-test-architecture-enterprise](https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise)
|
||||||
|
|
||||||
|
**제공:**
|
||||||
|
|
||||||
|
- Murat 에이전트(마스터 테스트 아키텍트 겸 품질 조언자)
|
||||||
|
- 테스트 설계, ATDD, 자동화, 테스트 리뷰, 추적성 워크플로
|
||||||
|
- NFR 평가, CI 설정, 프레임워크 초기 구조 생성
|
||||||
|
- 선택적 Playwright 유틸리티 및 MCP 통합을 포함한 P0-P3 우선순위
|
||||||
|
|
||||||
|
## 커뮤니티 모듈
|
||||||
|
|
||||||
|
커뮤니티 모듈과 모듈 마켓플레이스가 준비 중입니다. 업데이트는 [BMad GitHub 조직](https://github.com/bmad-code-org)을 확인하세요.
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
---
|
||||||
|
title: 테스트 옵션
|
||||||
|
description: 내장 QA 워크플로와 테스트 설계자(TEA) 모듈의 테스트 자동화 비교
|
||||||
|
sidebar:
|
||||||
|
order: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad는 두 가지 테스트 경로를 제공합니다. 빠른 테스트 생성을 위한 내장 QA 워크플로와 엔터프라이즈급 테스트 전략을 위한 설치 가능한 테스트 설계자 모듈입니다.
|
||||||
|
|
||||||
|
## 무엇을 사용해야 하나요?
|
||||||
|
|
||||||
|
| 기준 | 내장 QA | TEA 모듈 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| **적합한 경우** | 중소형 프로젝트, 빠른 커버리지 | 대형 프로젝트, 규제 대상 또는 복잡한 도메인 |
|
||||||
|
| **설정** | 설치할 것 없음 - BMM에 포함 | `npx bmad-method install`로 별도 설치 |
|
||||||
|
| **접근 방식** | 테스트를 빠르게 생성하고 나중에 반복 개선 | 먼저 계획하고 추적 가능하게 생성 |
|
||||||
|
| **테스트 유형** | API 및 E2E 테스트 | API, E2E, ATDD, NFR 등 |
|
||||||
|
| **전략** | 정상 경로 + 중요한 엣지 케이스 | 위험 기반 우선순위(P0-P3) |
|
||||||
|
| **워크플로 수** | 1(자동화) | 9개(설계, ATDD, 자동화, 리뷰, 추적 등) |
|
||||||
|
|
||||||
|
:::tip[내장 QA로 시작]
|
||||||
|
대부분의 프로젝트는 내장 QA 워크플로로 시작하면 됩니다. 나중에 테스트 전략, 품질 게이트, 요구사항 추적성이 필요해지면 TEA를 함께 설치하세요.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 내장 QA 워크플로
|
||||||
|
|
||||||
|
내장 QA 워크플로(`bmad-qa-generate-e2e-tests`)는 BMM(애자일 제품군) 모듈의 일부이며 개발자 에이전트를 통해 사용할 수 있습니다. 설정이나 추가 설치 없이 프로젝트의 기존 테스트 프레임워크를 사용해 실행 가능한 테스트를 빠르게 생성합니다.
|
||||||
|
|
||||||
|
**트리거:** `QA`(개발자 에이전트를 통해) 또는 `bmad-qa-generate-e2e-tests`
|
||||||
|
|
||||||
|
### 하는 일
|
||||||
|
|
||||||
|
QA 자동화 워크플로는 다섯 단계를 거칩니다.
|
||||||
|
|
||||||
|
1. **테스트 프레임워크 감지** - `package.json`과 기존 테스트 파일을 스캔해 프레임워크(Jest, Vitest, Playwright, Cypress 또는 표준 러너)를 찾습니다. 없으면 프로젝트 스택을 분석해 제안합니다.
|
||||||
|
2. **기능 식별** - 무엇을 테스트할지 묻거나 코드베이스에서 기능을 자동으로 발견합니다.
|
||||||
|
3. **API 테스트 생성** - 상태 코드, 응답 구조, 정상 경로, 오류 사례 1-2개를 다룹니다.
|
||||||
|
4. **E2E 테스트 생성** - 의미 기반 로케이터와 사용자에게 보이는 결과 검증으로 사용자 워크플로를 다룹니다.
|
||||||
|
5. **실행 및 검증** - 생성된 테스트를 실행하고 실패를 즉시 수정합니다.
|
||||||
|
|
||||||
|
워크플로는 프로젝트의 구현 산출물 폴더에 저장되는 테스트 요약을 생성합니다.
|
||||||
|
|
||||||
|
### 테스트 패턴
|
||||||
|
|
||||||
|
생성된 테스트는 "단순하고 유지보수하기 쉬운" 철학을 따릅니다.
|
||||||
|
|
||||||
|
- **표준 프레임워크 API만 사용** - 외부 유틸리티나 커스텀 추상화 없음
|
||||||
|
- UI 테스트에는 CSS 선택자 대신 **의미 기반 로케이터** 사용(역할, 레이블, 텍스트)
|
||||||
|
- 순서 의존성이 없는 **독립 테스트**
|
||||||
|
- 하드코딩된 대기(`wait`/`sleep`) 없음
|
||||||
|
- 기능 문서처럼 읽히는 명확한 설명
|
||||||
|
|
||||||
|
:::note[범위]
|
||||||
|
QA 워크플로는 테스트만 생성합니다. 코드 리뷰와 스토리 검증에는 코드 리뷰 워크플로(`CR`)를 사용하세요.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 내장 QA 사용 시점
|
||||||
|
|
||||||
|
- 새 기능 또는 기존 기능의 빠른 테스트 커버리지
|
||||||
|
- 고급 설정 없는 초보자 친화적 테스트 자동화
|
||||||
|
- 모든 개발자가 읽고 유지할 수 있는 표준 테스트 패턴
|
||||||
|
- 포괄적인 테스트 전략이 불필요한 중소형 프로젝트
|
||||||
|
|
||||||
|
## 테스트 설계자(TEA) 모듈
|
||||||
|
|
||||||
|
TEA는 전문가 에이전트(Murat)와 엔터프라이즈급 테스트를 위한 9개 구조화된 워크플로를 제공하는 단독 실행 모듈입니다. 테스트 생성을 넘어 테스트 전략, 위험 기반 계획, 품질 게이트, 요구사항 추적성을 다룹니다.
|
||||||
|
|
||||||
|
- **문서:** [TEA 모듈 문서](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/)
|
||||||
|
- **설치:** `npx bmad-method install` 실행 후 TEA 모듈 선택
|
||||||
|
- **npm:** [`bmad-method-test-architecture-enterprise`](https://www.npmjs.com/package/bmad-method-test-architecture-enterprise)
|
||||||
|
|
||||||
|
### TEA가 제공하는 것
|
||||||
|
|
||||||
|
| 워크플로 | 목적 |
|
||||||
|
| --- | --- |
|
||||||
|
| 테스트 설계 | 요구사항에 연결된 포괄적 테스트 전략 생성 |
|
||||||
|
| ATDD | 이해관계자 기준을 활용한 인수 테스트 주도 개발 |
|
||||||
|
| 자동화 | 고급 패턴과 유틸리티로 테스트 생성 |
|
||||||
|
| 테스트 리뷰 | 전략 대비 테스트 품질과 커버리지 검증 |
|
||||||
|
| 추적성 | 감사 및 컴플라이언스를 위해 테스트를 요구사항에 매핑 |
|
||||||
|
| NFR 평가 | 성능, 보안 등 비기능 요구사항 평가 |
|
||||||
|
| CI 설정 | 지속적 통합 파이프라인에서 테스트 실행 구성 |
|
||||||
|
| 프레임워크 초기 구조 생성 | 테스트 인프라와 프로젝트 구조 설정 |
|
||||||
|
| 릴리스 게이트 | 데이터 기반 출시 여부 결정 |
|
||||||
|
|
||||||
|
TEA는 P0-P3 위험 기반 우선순위와 선택적 Playwright 유틸리티 및 MCP 도구 통합도 지원합니다.
|
||||||
|
|
||||||
|
### TEA 사용 시점
|
||||||
|
|
||||||
|
- 요구사항 추적성 또는 컴플라이언스 문서화가 필요한 프로젝트
|
||||||
|
- 많은 기능에 대해 위험 기반 테스트 우선순위가 필요한 팀
|
||||||
|
- 릴리스 전 공식 품질 게이트가 있는 엔터프라이즈 환경
|
||||||
|
- 테스트 작성 전에 테스트 전략이 계획되어야 하는 복잡한 도메인
|
||||||
|
- 내장 QA의 단일 워크플로 접근 방식으로는 부족한 프로젝트
|
||||||
|
|
||||||
|
## 테스트가 워크플로와 맞물리는 방식
|
||||||
|
|
||||||
|
QA 자동화 워크플로는 BMad Method 워크플로 맵의 단계 4(구현)에 나타납니다. **전체 에픽이 완료된 후**, 즉 에픽의 모든 스토리가 구현되고 코드 리뷰된 뒤 실행하도록 설계되었습니다. 일반적인 순서는 다음과 같습니다.
|
||||||
|
|
||||||
|
1. 에픽의 각 스토리마다 개발자(`DS`)로 구현하고 코드 리뷰(`CR`)로 검증합니다
|
||||||
|
2. 에픽 완료 후 `QA`(개발자 에이전트를 통해) 또는 TEA의 자동화 워크플로로 테스트를 생성합니다
|
||||||
|
3. `bmad-retrospective`를 실행해 배운 점을 기록합니다
|
||||||
|
|
||||||
|
내장 QA 워크플로는 계획 문서(PRD, 아키텍처)를 로드하지 않고 소스 코드에서 직접 작업합니다. TEA 워크플로는 추적성을 위해 상위 계획 산출물과 통합할 수 있습니다.
|
||||||
|
|
||||||
|
전체 프로세스에서 테스트가 어디에 맞물리는지는 [워크플로 맵](./workflow-map.md)을 참고하세요.
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
---
|
||||||
|
title: "워크플로 맵"
|
||||||
|
description: BMad Method 워크플로 단계와 출력의 시각적 참조
|
||||||
|
sidebar:
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
BMad Method(BMM)는 BMad 생태계의 모듈이며 컨텍스트 엔지니어링과 계획 모범 사례를 따르는 데 초점을 둡니다. AI 에이전트는 명확하고 구조화된 컨텍스트가 있을 때 가장 잘 작동합니다. BMM 시스템은 4개의 구분된 단계에 걸쳐 그 컨텍스트를 점진적으로 만듭니다. 각 단계와 단계 안의 여러 선택 워크플로는 다음 단계에 필요한 정보를 담은 문서를 만들고, 에이전트는 항상 무엇을 왜 만들어야 하는지 알게 됩니다.
|
||||||
|
|
||||||
|
그 근거와 개념은 업계 전반에서 성공적으로 사용되어 온 애자일 방법론에서 온 사고 프레임워크입니다.
|
||||||
|
|
||||||
|
언제든 무엇을 해야 할지 확실하지 않다면 `bmad-help` 스킬이 흐름을 잡아 주고 다음 단계를 알려줍니다. 이 문서를 참조로 사용할 수도 있지만, 이미 BMad Method를 설치했다면 `bmad-help`가 더 대화형이고 훨씬 빠릅니다. 또한 BMad Method를 확장한 다른 모듈이나 함께 쓰는 보완 모듈을 사용한다면 `bmad-help`도 사용 가능한 항목을 모두 파악해 현재 상황에 가장 적절한 조언을 제공합니다.
|
||||||
|
|
||||||
|
마지막으로 중요한 점: 아래 모든 워크플로는 스킬로 직접 실행하거나, 먼저 에이전트를 로드한 뒤 에이전트 메뉴 항목을 사용해 원하는 도구에서 실행할 수 있습니다.
|
||||||
|
|
||||||
|
<iframe src="/workflow-map-diagram-ko.html" title="BMad Method 워크플로 맵 다이어그램" width="100%" height="100%" style="border-radius: 8px; border: 1px solid #334155; min-height: 900px;"></iframe>
|
||||||
|
|
||||||
|
<p style="font-size: 0.8rem; text-align: right; margin-top: -0.5rem; margin-bottom: 1rem;">
|
||||||
|
<a href="/workflow-map-diagram-ko.html" target="_blank" rel="noopener noreferrer">다이어그램 새 탭에서 열기 ↗</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## 단계 1: 분석(선택)
|
||||||
|
|
||||||
|
계획을 확정하기 전에 문제 영역을 탐색하고 아이디어를 검증합니다. [**각 도구가 무엇을 하고 언제 쓰는지 알아보기**](../explanation/analysis-phase.md).
|
||||||
|
|
||||||
|
| 워크플로 | 목적 | 산출물 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `bmad-brainstorming` | 브레인스토밍 코치의 안내를 받아 프로젝트 아이디어를 발산합니다 | `brainstorming-report.md` |
|
||||||
|
| `bmad-domain-research`, `bmad-market-research`, `bmad-technical-research` | 시장, 기술, 도메인 가정을 검증합니다 | 연구 발견 사항 |
|
||||||
|
| `bmad-product-brief` | 전략적 비전을 포착합니다. 개념이 명확할 때 가장 좋습니다 | `product-brief.md` |
|
||||||
|
| `bmad-prfaq` | 워킹 백워드 방식으로 제품 개념을 스트레스 테스트하고 다듬습니다 | `prfaq-{project}.md` |
|
||||||
|
|
||||||
|
## 단계 2: 계획
|
||||||
|
|
||||||
|
무엇을 누구를 위해 만들지 정의합니다.
|
||||||
|
|
||||||
|
| 워크플로 | 목적 | 산출물 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `bmad-prd` | PRD를 생성, 업데이트, 검증합니다. 안내형 발견 과정과 세 가지 의도를 하나의 스킬에 담았습니다 | 생성/업데이트: `prd.md`, `addendum.md`, `decision-log.md`; 검증: `validation-report.html` + `.md` |
|
||||||
|
| `bmad-ux` | UX가 중요할 때 사용자 경험을 설계합니다. DESIGN.md(시각)와 EXPERIENCE.md(동작)라는 두 핵심 문서를 만듭니다 | `DESIGN.md`, `EXPERIENCE.md`, `.decision-log.md` |
|
||||||
|
|
||||||
|
:::tip[하나의 스킬 안에 세 의도]
|
||||||
|
`bmad-prd`는 전체 PRD 수명주기를 처리합니다. 호출할 때 의도를 말하거나 스킬이 물어보게 하세요.
|
||||||
|
|
||||||
|
- **생성** - 안내형 발견 과정을 통해 처음부터 새 PRD를 만듭니다. `prd.md`, `addendum.md`, `decision-log.md`를 생성합니다
|
||||||
|
- **업데이트** - 기존 PRD와 변경 신호를 조정하고, 변경을 적용하기 전에 충돌을 식별합니다
|
||||||
|
- **검증** - 설정 가능한 체크리스트로 PRD를 비판적으로 검토하고 구조화된 HTML 발견 사항 보고서를 생성합니다
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::tip[상위 입력: `bmad-product-brief`]
|
||||||
|
`bmad-product-brief`(단계 1)는 `bmad-prd`가 발견 과정에서 입력으로 사용할 수 있는 `product-brief.md`를 생성합니다. 재설명을 줄이고 두 문서를 서로 맞춰 유지합니다. 두 스킬이 서로 필수는 아닙니다. 무엇을 만들지 이미 안다면 `bmad-prd`로 바로 시작하세요.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 단계 3: 솔루션 설계
|
||||||
|
|
||||||
|
어떻게 만들지 결정하고 작업을 스토리로 나눕니다.
|
||||||
|
|
||||||
|
| 워크플로 | 목적 | 산출물 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `bmad-create-architecture` | 기술적 결정을 명시적으로 만듭니다 | ADR이 있는 `architecture.md` |
|
||||||
|
| `bmad-create-epics-and-stories` | 요구사항을 구현 가능한 작업으로 나눕니다 | 스토리가 있는 에픽 파일 |
|
||||||
|
| `bmad-check-implementation-readiness` | 구현 전 관문 점검 | 통과/우려/실패 결정 |
|
||||||
|
|
||||||
|
## 단계 4: 구현
|
||||||
|
|
||||||
|
스토리 하나씩 구현합니다. 전체 4단계 자동화는 곧 제공됩니다.
|
||||||
|
|
||||||
|
| 워크플로 | 목적 | 산출물 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `bmad-sprint-planning` | 추적 상태 초기화(프로젝트당 한 번, 개발 주기 순서화) | `sprint-status.yaml` |
|
||||||
|
| `bmad-create-story` | 구현을 위한 다음 스토리 준비 | `story-[slug].md` |
|
||||||
|
| `bmad-dev-story` | 스토리 구현 | 작동하는 코드 + 테스트 |
|
||||||
|
| `bmad-code-review` | 구현 품질 검증 | 승인 또는 변경 요청 |
|
||||||
|
| `bmad-correct-course` | 스프린트 중 의미 있는 변경 처리 | 업데이트된 계획 또는 경로 재조정 |
|
||||||
|
| `bmad-sprint-status` | 스프린트 진행 상황과 스토리 상태 추적 | 스프린트 상태 업데이트 |
|
||||||
|
| `bmad-retrospective` | 에픽 완료 후 회고 | 배운 점 |
|
||||||
|
| `bmad-investigate` | 입력에 맞춰 증거 등급을 매긴 발견 사항으로 포렌식 조사 파일을 작성합니다 | `{slug}-investigation.md` |
|
||||||
|
|
||||||
|
## 빠른 흐름(병렬 트랙)
|
||||||
|
|
||||||
|
작고 잘 이해된 작업에서는 단계 1-3을 건너뜁니다.
|
||||||
|
|
||||||
|
| 워크플로 | 목적 | 산출물 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `bmad-quick-dev` | 통합 빠른 흐름 - 의도 정리, 계획, 구현, 리뷰, 발표 | `spec-*.md` + 코드 |
|
||||||
|
|
||||||
|
## 컨텍스트 관리
|
||||||
|
|
||||||
|
각 문서는 다음 단계의 컨텍스트가 됩니다. PRD는 아키텍트에게 어떤 제약이 중요한지 알려줍니다. 아키텍처는 개발 에이전트에게 어떤 패턴을 따라야 하는지 알려줍니다. 스토리 파일은 구현을 위한 집중적이고 완결된 컨텍스트를 제공합니다. 이 구조가 없으면 에이전트는 일관되지 않은 결정을 내립니다.
|
||||||
|
|
||||||
|
### 프로젝트 컨텍스트
|
||||||
|
|
||||||
|
:::tip[권장]
|
||||||
|
AI 에이전트가 프로젝트의 규칙과 선호 사항을 따르도록 `project-context.md`를 만드세요. 이 파일은 프로젝트의 헌장처럼 작동해 모든 워크플로에서 구현 결정을 안내합니다. 이 선택 파일은 아키텍처 작성이 끝날 때 생성할 수 있고, 기존 프로젝트에서도 현재 관례와 맞춰야 할 중요한 내용을 포착하기 위해 생성할 수 있습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
**만드는 방법:**
|
||||||
|
|
||||||
|
- **수동으로** - `_bmad-output/project-context.md`를 만들고 기술 스택과 구현 규칙을 작성합니다
|
||||||
|
- **생성하기** - `bmad-generate-project-context`를 실행해 아키텍처 또는 코드베이스에서 자동 생성합니다
|
||||||
|
|
||||||
|
[**project-context.md 더 알아보기**](../explanation/project-context.md)
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
---
|
||||||
|
title: 로드맵
|
||||||
|
description: BMad의 다음 단계 - 기능, 개선 사항, 커뮤니티 기여
|
||||||
|
---
|
||||||
|
|
||||||
|
# BMad Method: 공개 로드맵
|
||||||
|
|
||||||
|
BMad Method, BMad Method 모듈(BMM), BMad 빌더(BMB)는 계속 발전하고 있습니다. 현재 진행 중인 작업과 앞으로 예정된 항목을 소개합니다.
|
||||||
|
|
||||||
|
<div class="roadmap-container">
|
||||||
|
|
||||||
|
<h2 class="roadmap-section-title">진행 중</h2>
|
||||||
|
|
||||||
|
<div class="roadmap-future">
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🧩</span>
|
||||||
|
<h4>범용 스킬 아키텍처</h4>
|
||||||
|
<p>스킬 하나를 어떤 플랫폼에서든 사용할 수 있게 합니다. 한 번 작성하고 어디서나 실행합니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🏗️</span>
|
||||||
|
<h4>BMad 빌더 v1</h4>
|
||||||
|
<p>평가, 팀 구성, 점진적 기능 저하를 내장한 프로덕션 준비 AI 에이전트와 워크플로를 만듭니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🧠</span>
|
||||||
|
<h4>프로젝트 컨텍스트 시스템</h4>
|
||||||
|
<p>AI가 실제로 프로젝트를 이해합니다. 코드베이스와 함께 진화하는, 프레임워크를 이해하는 컨텍스트입니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">📦</span>
|
||||||
|
<h4>중앙화된 스킬</h4>
|
||||||
|
<p>한 번 설치하고 어디서나 사용합니다. 파일이 어지럽게 늘어나지 않게 프로젝트 간 스킬을 공유합니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🔄</span>
|
||||||
|
<h4>적응형 스킬</h4>
|
||||||
|
<p>도구를 이해하는 스킬입니다. Claude, Codex, Kimi, OpenCode 등 다양한 도구에 맞춘 변형을 제공합니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">📝</span>
|
||||||
|
<h4>BMad 팀 전문가 블로그</h4>
|
||||||
|
<p>팀이 전하는 가이드, 글, 인사이트입니다. 곧 공개됩니다.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 class="roadmap-section-title">시작 단계</h2>
|
||||||
|
|
||||||
|
<div class="roadmap-future">
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🏪</span>
|
||||||
|
<h4>스킬 마켓플레이스</h4>
|
||||||
|
<p>커뮤니티가 만든 스킬을 발견하고 설치하고 업데이트합니다. curl 명령 하나로 기능을 확장합니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🎨</span>
|
||||||
|
<h4>워크플로 커스터마이징</h4>
|
||||||
|
<p>내 방식에 맞게 조정합니다. Jira, Linear, 커스텀 출력까지, 당신의 워크플로와 규칙에 맞춥니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🚀</span>
|
||||||
|
<h4>1-3단계 최적화</h4>
|
||||||
|
<p>서브 에이전트 컨텍스트 수집으로 빠른 계획을 지원합니다. YOLO 모드의 속도와 안내형 워크플로의 품질을 함께 가져갑니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🌐</span>
|
||||||
|
<h4>엔터프라이즈 준비</h4>
|
||||||
|
<p>SSO, 감사 로그, 팀 워크스페이스. 기업 도입에 필요한 기반 기능입니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">💎</span>
|
||||||
|
<h4>커뮤니티 모듈 확대</h4>
|
||||||
|
<p>엔터테인먼트, 보안, 테라피, 롤플레이 등 훨씬 더 많은 영역으로 BMad Method 플랫폼을 확장합니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">⚡</span>
|
||||||
|
<h4>개발 루프 자동화</h4>
|
||||||
|
<p>개발을 위한 선택형 자동 조종 기능입니다. 품질을 높게 유지하면서 AI가 흐름을 처리하게 합니다.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 class="roadmap-section-title">커뮤니티와 팀</h2>
|
||||||
|
|
||||||
|
<div class="roadmap-future">
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🎙️</span>
|
||||||
|
<h4>BMad Method 팟캐스트</h4>
|
||||||
|
<p>AI 네이티브 개발에 관한 대화입니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🎓</span>
|
||||||
|
<h4>BMad Method 마스터 클래스</h4>
|
||||||
|
<p>사용자에서 전문가로 나아갑니다. 모든 단계와 워크플로를 깊게 다룹니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🏗️</span>
|
||||||
|
<h4>BMad 빌더 마스터 클래스</h4>
|
||||||
|
<p>직접 에이전트를 만듭니다. 단순한 사용을 넘어 직접 만들 준비가 되었을 때 필요한 고급 기법입니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">⚡</span>
|
||||||
|
<h4>BMad Prototype First</h4>
|
||||||
|
<p>아이디어에서 작동하는 프로토타입까지 한 세션에 이어 갑니다. 구상하던 앱을 빠르게 실체로 만듭니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🌴</span>
|
||||||
|
<h4>BMad BALM!</h4>
|
||||||
|
<p>AI 네이티브 시대의 생활 관리입니다. 작업, 습관, 목표까지 아우르는 AI 코파일럿입니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🖥️</span>
|
||||||
|
<h4>공식 UI</h4>
|
||||||
|
<p>전체 BMad 생태계를 위한 세련된 인터페이스입니다. CLI의 힘과 GUI의 편의성을 함께 제공합니다.</p>
|
||||||
|
</div>
|
||||||
|
<div class="roadmap-future-card">
|
||||||
|
<span class="roadmap-emoji">🔒</span>
|
||||||
|
<h4>BMad in a Box</h4>
|
||||||
|
<p>셀프 호스팅, 망 분리, 엔터프라이즈급 배포를 지원합니다. 당신의 AI 어시스턴트를 당신의 인프라에서 직접 통제합니다.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="text-align: center; margin-top: 3rem; padding: 2rem; background: var(--color-bg-card); border-radius: 12px; border: 1px solid var(--color-border);">
|
||||||
|
<h3 style="margin: 0 0 1rem;">기여하고 싶나요?</h3>
|
||||||
|
<p style="color: var(--slate-color-400); margin: 0;">
|
||||||
|
이것은 계획된 항목의 일부일 뿐입니다. BMad 오픈 소스 팀은 기여자를 환영합니다!{" "}<br />
|
||||||
|
<a href="https://github.com/bmad-code-org/BMAD-METHOD" style="color: var(--color-in-progress);">GitHub에서 함께</a> AI 기반 개발의 미래를 만들어 주세요.
|
||||||
|
</p>
|
||||||
|
<p style="color: var(--slate-color-400); margin: 1.5rem 0 0;">
|
||||||
|
우리가 만드는 것을 좋아하시나요? 일회성 및 월간{" "}<a href="https://buymeacoffee.com/bmad" style="color: var(--color-in-progress);">후원</a> 모두 감사히 받습니다.
|
||||||
|
</p>
|
||||||
|
<p style="color: var(--slate-color-400); margin: 1rem 0 0;">
|
||||||
|
기업 후원, 파트너십 문의, 발표 요청, 교육, 미디어 문의는{" "}
|
||||||
|
<a href="mailto:contact@bmadcode.com" style="color: var(--color-in-progress);">contact@bmadcode.com</a>으로 연락하세요.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,289 @@
|
||||||
|
---
|
||||||
|
title: "시작하기"
|
||||||
|
description: BMad를 설치하고 첫 프로젝트를 만듭니다
|
||||||
|
---
|
||||||
|
|
||||||
|
계획, 아키텍처, 구현을 안내하는 전문 에이전트 기반 AI 워크플로로 소프트웨어를 더 빠르게 만드세요.
|
||||||
|
|
||||||
|
## 배울 내용
|
||||||
|
|
||||||
|
- 새 프로젝트에 BMad Method를 설치하고 초기화합니다
|
||||||
|
- 다음에 무엇을 해야 할지 아는 지능형 안내자 **BMad 도움말**을 사용합니다
|
||||||
|
- 프로젝트 규모에 맞는 계획 트랙을 선택합니다
|
||||||
|
- 요구사항부터 작동하는 코드까지 단계별로 진행합니다
|
||||||
|
- 에이전트와 워크플로를 효과적으로 사용합니다
|
||||||
|
|
||||||
|
:::note[필수 조건]
|
||||||
|
- **Node.js 20.12+** - 설치 프로그램에 필요합니다
|
||||||
|
- **Git** - 버전 관리를 위해 권장합니다
|
||||||
|
- **AI 기반 IDE** - Claude Code, Cursor 또는 유사 도구
|
||||||
|
- **프로젝트 아이디어** - 학습용이라면 단순한 아이디어도 충분합니다
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::tip[가장 쉬운 경로]
|
||||||
|
**설치** → `npx bmad-method install`
|
||||||
|
**질문** → `bmad-help 먼저 무엇을 해야 하나요?`
|
||||||
|
**빌드** → BMad 도움말의 안내에 따라 워크플로를 진행하세요
|
||||||
|
:::
|
||||||
|
|
||||||
|
## BMad 도움말 만나기: 지능형 안내자
|
||||||
|
|
||||||
|
**BMad 도움말은 BMad를 시작하는 가장 빠른 방법입니다.** 워크플로나 단계를 외울 필요가 없습니다. 그냥 물어보면 BMad 도움말이 다음을 수행합니다.
|
||||||
|
|
||||||
|
- **프로젝트를 검사**해 이미 완료된 작업을 확인합니다
|
||||||
|
- 설치된 모듈을 기준으로 **선택지를 보여줍니다**
|
||||||
|
- 첫 필수 작업을 포함해 **다음 단계를 추천합니다**
|
||||||
|
- "SaaS 아이디어가 있는데 어디서 시작하지?" 같은 **질문에 답합니다**
|
||||||
|
|
||||||
|
### BMad 도움말 사용 방법
|
||||||
|
|
||||||
|
AI IDE에서 스킬을 호출해 실행합니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
bmad-help
|
||||||
|
```
|
||||||
|
|
||||||
|
컨텍스트가 있는 안내를 받으려면 질문과 함께 사용할 수도 있습니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
bmad-help SaaS 제품 아이디어가 있고 원하는 기능도 모두 알고 있습니다. 어디서 시작하면 좋나요?
|
||||||
|
```
|
||||||
|
|
||||||
|
BMad 도움말은 다음을 답합니다.
|
||||||
|
|
||||||
|
- 현재 상황에 권장되는 선택지
|
||||||
|
- 첫 번째 필수 작업
|
||||||
|
- 나머지 과정의 모습
|
||||||
|
|
||||||
|
### 워크플로 끝에서도 동작합니다
|
||||||
|
|
||||||
|
BMad 도움말은 질문에 답하기만 하지 않습니다. **모든 워크플로 끝에서 자동으로 실행되어** 다음에 무엇을 해야 할지 알려줍니다. 추측하거나 문서를 뒤질 필요 없이 다음 필수 워크플로에 대한 명확한 안내를 받습니다.
|
||||||
|
|
||||||
|
:::tip[여기서 시작하세요]
|
||||||
|
BMad를 설치한 뒤 바로 `bmad-help` 스킬을 호출하세요. 설치된 모듈을 감지하고 프로젝트에 맞는 시작점으로 안내합니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## BMad 이해하기
|
||||||
|
|
||||||
|
BMad는 전문 AI 에이전트가 있는 안내형 워크플로를 통해 소프트웨어를 만들도록 돕습니다. 과정은 네 단계로 진행됩니다.
|
||||||
|
|
||||||
|
| 단계 | 이름 | 일어나는 일 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 1 | 분석 | 브레인스토밍, 리서치, 제품 개요 또는 PRFAQ *(선택)* |
|
||||||
|
| 2 | 계획 | 요구사항 작성(PRD 또는 사양) |
|
||||||
|
| 3 | 솔루션 설계 | 아키텍처 설계 *(BMad Method/엔터프라이즈 전용)* |
|
||||||
|
| 4 | 구현 | 에픽별, 스토리별 구현 |
|
||||||
|
|
||||||
|
단계, 워크플로, 컨텍스트 관리를 살펴보려면 **[워크플로 맵 열기](../reference/workflow-map.md)**를 확인하세요.
|
||||||
|
|
||||||
|
프로젝트 복잡도에 따라 BMad는 세 가지 계획 트랙을 제공합니다.
|
||||||
|
|
||||||
|
| 트랙 | 적합한 경우 | 생성되는 문서 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| **빠른 흐름** | 버그 수정, 단순 기능, 명확한 범위(1-15개 스토리) | 기술 사양만 |
|
||||||
|
| **BMad Method** | 제품, 플랫폼, 복잡한 기능(10-50개 이상 스토리) | PRD + 아키텍처 + UX |
|
||||||
|
| **엔터프라이즈** | 컴플라이언스, 멀티테넌트 시스템(30개 이상 스토리) | PRD + 아키텍처 + 보안 + DevOps |
|
||||||
|
|
||||||
|
:::note
|
||||||
|
스토리 수는 기준이 아니라 안내입니다. 스토리 수 계산보다 계획 필요성에 따라 트랙을 선택하세요.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 설치
|
||||||
|
|
||||||
|
프로젝트 디렉터리에서 터미널을 열고 실행합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx bmad-method install
|
||||||
|
```
|
||||||
|
|
||||||
|
기본 릴리스 채널 대신 최신 사전 릴리스 빌드를 원한다면 `npx bmad-method@next install`을 사용하세요.
|
||||||
|
|
||||||
|
모듈 선택 프롬프트가 나오면 **BMad Method**를 선택합니다.
|
||||||
|
|
||||||
|
설치 프로그램은 두 폴더를 만듭니다.
|
||||||
|
|
||||||
|
- `_bmad/` - 에이전트, 워크플로, 작업, 설정
|
||||||
|
- `_bmad-output/` - 지금은 비어 있지만 산출물이 저장될 위치입니다
|
||||||
|
|
||||||
|
:::tip[다음 단계]
|
||||||
|
프로젝트 폴더에서 AI IDE를 열고 다음을 실행하세요.
|
||||||
|
|
||||||
|
```
|
||||||
|
bmad-help
|
||||||
|
```
|
||||||
|
|
||||||
|
BMad 도움말이 완료된 작업을 감지하고 정확한 다음 단계를 추천합니다. "내 선택지는 무엇인가요?" 또는 "SaaS 아이디어가 있는데 어디서 시작해야 하나요?"처럼 물어볼 수도 있습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::note[에이전트를 로드하고 워크플로를 실행하는 방법]
|
||||||
|
각 워크플로에는 IDE에서 이름으로 호출하는 **스킬**이 있습니다(예: `bmad-prd`). AI 도구가 `bmad-*` 이름을 인식하고 실행하므로 에이전트를 따로 로드할 필요가 없습니다. 일반 대화를 위해 에이전트 스킬을 직접 호출할 수도 있습니다(예: PM 에이전트용 `bmad-agent-pm`).
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::caution[새 채팅]
|
||||||
|
각 워크플로는 항상 새 채팅에서 시작하세요. 이렇게 하면 컨텍스트 제한으로 인한 문제를 예방할 수 있습니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 1단계: 계획 만들기
|
||||||
|
|
||||||
|
1-3단계를 진행합니다. **각 워크플로는 새 채팅에서 실행하세요.**
|
||||||
|
|
||||||
|
:::tip[프로젝트 컨텍스트(선택)]
|
||||||
|
시작하기 전에 `project-context.md`를 만들어 기술 선호도와 구현 규칙을 문서화하는 것을 고려하세요. 이렇게 하면 모든 AI 에이전트가 프로젝트 전반에서 당신의 규칙을 따릅니다.
|
||||||
|
|
||||||
|
`_bmad-output/project-context.md`에 직접 만들거나 아키텍처 이후 `bmad-generate-project-context`로 생성할 수 있습니다. [자세히 알아보기](../explanation/project-context.md).
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 1단계: 분석(선택)
|
||||||
|
|
||||||
|
이 단계의 모든 워크플로는 선택 사항입니다. [**무엇을 써야 할지 모르겠나요?**](../explanation/analysis-phase.md)
|
||||||
|
|
||||||
|
- **브레인스토밍**(`bmad-brainstorming`) - 안내형 아이디어 발산
|
||||||
|
- **리서치**(`bmad-market-research` / `bmad-domain-research` / `bmad-technical-research`) - 시장, 도메인, 기술 리서치
|
||||||
|
- **제품 개요**(`bmad-product-brief`) - 개념이 명확할 때 권장되는 기초 문서
|
||||||
|
- **PRFAQ**(`bmad-prfaq`) - 제품 개념을 압박하고 다듬는 워킹 백워드 챌린지
|
||||||
|
|
||||||
|
### 2단계: 계획(필수)
|
||||||
|
|
||||||
|
**BMad Method 및 엔터프라이즈 트랙:**
|
||||||
|
|
||||||
|
1. 새 채팅에서 `bmad-prd`를 실행합니다. 의도(생성, 업데이트, 검증)를 직접 말하거나 스킬이 묻게 둡니다
|
||||||
|
2. 출력: `prd.md`, `addendum.md`, `decision-log.md`
|
||||||
|
|
||||||
|
:::note[`bmad-prd` 의도]
|
||||||
|
- **생성** - 처음부터 코칭형 발견 과정을 진행합니다. 스킬이 워크스페이스 폴더 이름을 정하고 만족할 만한 PRD까지 안내합니다
|
||||||
|
- **업데이트** - 기존 PRD와 변경 신호를 지정합니다. 변경을 적용하기 전에 충돌을 드러냅니다
|
||||||
|
- **검증** - 완료된 PRD를 체크리스트로 비평하고 HTML 발견 사항 보고서를 생성합니다
|
||||||
|
:::
|
||||||
|
|
||||||
|
**빠른 흐름 트랙:**
|
||||||
|
|
||||||
|
- `bmad-quick-dev`를 실행합니다. 계획과 구현을 하나의 워크플로에서 처리하므로 구현 단계로 바로 넘어갑니다
|
||||||
|
|
||||||
|
:::note[UX 설계(선택)]
|
||||||
|
프로젝트에 사용자 인터페이스가 있다면 PRD를 만든 뒤 **UX 디자이너 에이전트**(`bmad-agent-ux-designer`)를 호출하고 UX 설계 워크플로(`bmad-ux`)를 실행하세요.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 3단계: 솔루션 설계(BMad Method/엔터프라이즈)
|
||||||
|
|
||||||
|
**아키텍처 만들기**
|
||||||
|
|
||||||
|
1. 새 채팅에서 **아키텍트 에이전트**(`bmad-agent-architect`)를 호출합니다
|
||||||
|
2. `bmad-create-architecture`(`bmad-create-architecture`)를 실행합니다
|
||||||
|
3. 출력: 기술 결정이 담긴 아키텍처 문서
|
||||||
|
|
||||||
|
**에픽과 스토리 만들기**
|
||||||
|
|
||||||
|
:::tip[V6 개선]
|
||||||
|
이제 에픽과 스토리는 아키텍처 *이후* 생성됩니다. 데이터베이스, API 패턴, 기술 스택 같은 아키텍처 결정이 작업 분해 방식에 직접 영향을 주므로 스토리 품질이 좋아집니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
1. 새 채팅에서 **PM 에이전트**(`bmad-agent-pm`)를 호출합니다
|
||||||
|
2. `bmad-create-epics-and-stories`(`bmad-create-epics-and-stories`)를 실행합니다
|
||||||
|
3. 워크플로는 PRD와 아키텍처를 모두 사용해 기술적 맥락이 반영된 스토리를 만듭니다
|
||||||
|
|
||||||
|
**구현 준비도 점검** *(강력 권장)*
|
||||||
|
|
||||||
|
1. 새 채팅에서 **아키텍트 에이전트**(`bmad-agent-architect`)를 호출합니다
|
||||||
|
2. `bmad-check-implementation-readiness`(`bmad-check-implementation-readiness`)를 실행합니다
|
||||||
|
3. 모든 계획 문서 간 응집성을 검증합니다
|
||||||
|
|
||||||
|
## 2단계: 프로젝트 만들기
|
||||||
|
|
||||||
|
계획이 완료되면 구현으로 이동합니다. **각 워크플로는 새 채팅에서 실행해야 합니다.**
|
||||||
|
|
||||||
|
### 스프린트 계획 초기화
|
||||||
|
|
||||||
|
**개발자 에이전트**(`bmad-agent-dev`)를 호출하고 `bmad-sprint-planning`(`bmad-sprint-planning`)을 실행합니다. 모든 에픽과 스토리를 추적하는 `sprint-status.yaml`이 생성됩니다.
|
||||||
|
|
||||||
|
### 빌드 사이클
|
||||||
|
|
||||||
|
각 스토리마다 새 채팅으로 이 사이클을 반복합니다.
|
||||||
|
|
||||||
|
| 단계 | 에이전트 | 워크플로 | 명령 | 목적 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| 1 | DEV | `bmad-create-story` | `bmad-create-story` | 에픽에서 스토리 파일 생성 |
|
||||||
|
| 2 | DEV | `bmad-dev-story` | `bmad-dev-story` | 스토리 구현 |
|
||||||
|
| 3 | DEV | `bmad-code-review` | `bmad-code-review` | 품질 검증 *(권장)* |
|
||||||
|
|
||||||
|
에픽의 모든 스토리를 완료한 뒤 **개발자 에이전트**(`bmad-agent-dev`)를 호출하고 `bmad-retrospective`(`bmad-retrospective`)를 실행합니다.
|
||||||
|
|
||||||
|
## 달성한 것
|
||||||
|
|
||||||
|
BMad로 빌드하는 기초를 배웠습니다.
|
||||||
|
|
||||||
|
- BMad를 설치하고 IDE에 맞게 설정했습니다
|
||||||
|
- 선택한 계획 트랙으로 프로젝트를 초기화했습니다
|
||||||
|
- 계획 문서(PRD, 아키텍처, 에픽과 스토리)를 만들었습니다
|
||||||
|
- 구현을 위한 빌드 사이클을 이해했습니다
|
||||||
|
|
||||||
|
이제 프로젝트에는 다음이 있습니다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
your-project/
|
||||||
|
├── _bmad/ # BMad 설정
|
||||||
|
├── _bmad-output/
|
||||||
|
│ ├── planning-artifacts/
|
||||||
|
│ │ ├── PRD.md # 요구사항 문서
|
||||||
|
│ │ ├── architecture.md # 기술 결정
|
||||||
|
│ │ └── epics/ # 에픽과 스토리 파일
|
||||||
|
│ ├── implementation-artifacts/
|
||||||
|
│ │ └── sprint-status.yaml # 스프린트 추적
|
||||||
|
│ └── project-context.md # 구현 규칙(선택)
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
## 빠른 참조
|
||||||
|
|
||||||
|
| 워크플로 | 명령 | 에이전트 | 목적 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| **`bmad-help`** | `bmad-help` | 무관 | **무엇이든 물어볼 수 있는 지능형 안내자** |
|
||||||
|
| `bmad-prd` | `bmad-prd` | 무관 | PRD 생성, 업데이트 또는 검증 |
|
||||||
|
| `bmad-create-architecture` | `bmad-create-architecture` | 아키텍트 | 아키텍처 문서 생성 |
|
||||||
|
| `bmad-generate-project-context` | `bmad-generate-project-context` | 분석가 | 프로젝트 컨텍스트 파일 생성 |
|
||||||
|
| `bmad-create-epics-and-stories` | `bmad-create-epics-and-stories` | PM | PRD를 에픽으로 분해 |
|
||||||
|
| `bmad-check-implementation-readiness` | `bmad-check-implementation-readiness` | 아키텍트 | 계획 응집성 검증 |
|
||||||
|
| `bmad-sprint-planning` | `bmad-sprint-planning` | DEV | 스프린트 추적 초기화 |
|
||||||
|
| `bmad-create-story` | `bmad-create-story` | DEV | 스토리 파일 생성 |
|
||||||
|
| `bmad-dev-story` | `bmad-dev-story` | DEV | 스토리 구현 |
|
||||||
|
| `bmad-code-review` | `bmad-code-review` | DEV | 구현된 코드 리뷰 |
|
||||||
|
|
||||||
|
## 자주 묻는 질문
|
||||||
|
|
||||||
|
**항상 아키텍처가 필요한가요?**
|
||||||
|
오직 BMad Method와 엔터프라이즈 트랙에서만 필요합니다. 빠른 흐름은 사양에서 구현으로 바로 넘어갑니다.
|
||||||
|
|
||||||
|
**나중에 계획을 바꿀 수 있나요?**
|
||||||
|
네. `bmad-correct-course` 워크플로가 구현 중 범위 변경을 처리합니다.
|
||||||
|
|
||||||
|
**먼저 브레인스토밍하고 싶다면요?**
|
||||||
|
PRD를 시작하기 전에 분석가 에이전트(`bmad-agent-analyst`)를 호출하고 `bmad-brainstorming`(`bmad-brainstorming`)을 실행하세요.
|
||||||
|
|
||||||
|
**엄격한 순서를 따라야 하나요?**
|
||||||
|
반드시 그렇지는 않습니다. 흐름에 익숙해지면 위의 빠른 참조를 사용해 워크플로를 직접 실행할 수 있습니다.
|
||||||
|
|
||||||
|
## 도움 받기
|
||||||
|
|
||||||
|
:::tip[첫 번째 목적지: BMad 도움말]
|
||||||
|
**언제든 `bmad-help`를 호출하세요.** 막혔을 때 가장 빠른 방법입니다. 무엇이든 물어보세요.
|
||||||
|
|
||||||
|
- "설치 후 무엇을 해야 하나요?"
|
||||||
|
- "워크플로 X에서 막혔어요"
|
||||||
|
- "Y에 대한 선택지는 무엇인가요?"
|
||||||
|
- "지금까지 완료된 것을 보여 주세요"
|
||||||
|
|
||||||
|
BMad 도움말은 프로젝트를 검사하고 완료한 작업을 감지한 뒤 다음에 무엇을 해야 할지 정확히 알려줍니다.
|
||||||
|
:::
|
||||||
|
|
||||||
|
- **워크플로 중** - 에이전트가 질문과 설명으로 안내합니다
|
||||||
|
- **커뮤니티** - [Discord](https://discord.gg/gk8jAdXWmj)(#bmad-method-help, #report-bugs-and-issues)
|
||||||
|
|
||||||
|
## 핵심 요약
|
||||||
|
|
||||||
|
:::tip[이것만 기억하세요]
|
||||||
|
- **`bmad-help`로 시작하세요** - 프로젝트와 선택지를 아는 지능형 안내자입니다
|
||||||
|
- **항상 새 채팅을 사용하세요** - 각 워크플로마다 새 채팅을 시작합니다
|
||||||
|
- **트랙이 중요합니다** - 빠른 흐름은 `bmad-quick-dev`를 사용하고, BMad Method/엔터프라이즈는 PRD와 아키텍처가 필요합니다
|
||||||
|
- **BMad 도움말은 자동으로 실행됩니다** - 모든 워크플로는 다음 단계 안내로 끝납니다
|
||||||
|
:::
|
||||||
|
|
||||||
|
시작할 준비가 되었나요? BMad를 설치하고 `bmad-help`를 호출한 뒤 안내에 따라 첫 흐름을 시작하세요.
|
||||||
|
|
@ -113,7 +113,7 @@ The magic happens in ideas 50–100. The workflow encourages generating 100+ ide
|
||||||
1. Reads the input and any ancillary linked materials.
|
1. Reads the input and any ancillary linked materials.
|
||||||
2. Distills into the five-field kernel using a configurable template; routes overflow into appropriately-named companions.
|
2. Distills into the five-field kernel using a configurable template; routes overflow into appropriately-named companions.
|
||||||
3. Runs a two-pass self-validate (coherence rules, then preservation of every load-bearing source claim).
|
3. Runs a two-pass self-validate (coherence rules, then preservation of every load-bearing source claim).
|
||||||
4. Writes `SPEC.md`, sibling companions, and a `.decision-log.md` under `{output_folder}/specs/spec-{slug}/`.
|
4. Writes `SPEC.md`, sibling companions, and a `.memlog.md` under `{output_folder}/specs/spec-{slug}/`.
|
||||||
|
|
||||||
Spec Law enforces eight rules: capabilities carry both intent and success; intents are WHAT not HOW; constraints actually bend decisions; non-goals are explicit; success signals are concrete; capability IDs are stable; every load-bearing source claim is preserved; prose is lean.
|
Spec Law enforces eight rules: capabilities carry both intent and success; intents are WHAT not HOW; constraints actually bend decisions; non-goals are explicit; success signals are concrete; capability IDs are stable; every load-bearing source claim is preserved; prose is lean.
|
||||||
|
|
||||||
|
|
@ -123,7 +123,7 @@ Spec Law enforces eight rules: capabilities carry both intent and success; inten
|
||||||
- `slug` (optional) — required only when input is sparse and no slug is derivable from a source filename.
|
- `slug` (optional) — required only when input is sparse and no slug is derivable from a source filename.
|
||||||
- `target_spec_path` (optional) — set to update an existing spec instead of creating a new one.
|
- `target_spec_path` (optional) — set to update an existing spec instead of creating a new one.
|
||||||
|
|
||||||
**Output:** Spec folder containing `SPEC.md`, any companion files, and a `.decision-log.md`. Headless callers receive a JSON response with the result status and the list of files written or modified.
|
**Output:** Spec folder containing `SPEC.md`, any companion files, and a `.memlog.md`. Headless callers receive a JSON response with the result status and the list of files written or modified.
|
||||||
|
|
||||||
:::note[Mutation contract]
|
:::note[Mutation contract]
|
||||||
`bmad-spec` is the only writer of `SPEC.md` and of spec-authored companions. Other skills produce their own native artifacts and invoke `bmad-spec` headless when they need to express intent as the canonical contract or propose updates.
|
`bmad-spec` is the only writer of `SPEC.md` and of spec-authored companions. Other skills produce their own native artifacts and invoke `bmad-spec` headless when they need to express intent as the canonical contract or propose updates.
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,13 @@ Define what to build and for whom.
|
||||||
|
|
||||||
| Workflow | Purpose | Produces |
|
| Workflow | Purpose | Produces |
|
||||||
|-------------------------|-------------------------------------------------------------------------------------|---------------------------------------------------|
|
|-------------------------|-------------------------------------------------------------------------------------|---------------------------------------------------|
|
||||||
| `bmad-prd` | Create, update, or validate a PRD — facilitated discovery, three intents in one skill | Create/Update: `prd.md`, `addendum.md`, `decision-log.md`; Validate: `validation-report.html` + `.md` |
|
| `bmad-prd` | Create, update, or validate a PRD — facilitated discovery, three intents in one skill | Create/Update: `prd.md`, `addendum.md`, `.memlog.md`; Validate: `validation-report.html` + `.md` |
|
||||||
| `bmad-ux` | Design user experience (when UX matters) — DESIGN.md (visual) + EXPERIENCE.md (behavioral) spine pair | `DESIGN.md`, `EXPERIENCE.md`, `.decision-log.md` |
|
| `bmad-ux` | Design user experience (when UX matters) — DESIGN.md (visual) + EXPERIENCE.md (behavioral) spine pair | `DESIGN.md`, `EXPERIENCE.md`, `.memlog.md` |
|
||||||
|
|
||||||
:::tip[Three intents in one skill]
|
:::tip[Three intents in one skill]
|
||||||
`bmad-prd` handles the full PRD lifecycle. State your intent when invoking or the skill will ask:
|
`bmad-prd` handles the full PRD lifecycle. State your intent when invoking or the skill will ask:
|
||||||
|
|
||||||
- **Create** — new PRD from scratch via coached discovery; produces `prd.md`, `addendum.md`, and `decision-log.md`
|
- **Create** — new PRD from scratch via coached discovery; produces `prd.md`, `addendum.md`, and `.memlog.md`
|
||||||
- **Update** — reconcile an existing PRD with a change signal, surfacing conflicts before applying changes
|
- **Update** — reconcile an existing PRD with a change signal, surfacing conflicts before applying changes
|
||||||
- **Validate** — critique a PRD against a configurable checklist and produce a structured HTML findings report
|
- **Validate** — critique a PRD against a configurable checklist and produce a structured HTML findings report
|
||||||
:::
|
:::
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ All workflows in this phase are optional. [**Not sure which to use?**](../explan
|
||||||
**For BMad Method and Enterprise tracks:**
|
**For BMad Method and Enterprise tracks:**
|
||||||
|
|
||||||
1. Run `bmad-prd` in a new chat — state your intent (Create / Update / Validate) or let the skill ask
|
1. Run `bmad-prd` in a new chat — state your intent (Create / Update / Validate) or let the skill ask
|
||||||
2. Output: `prd.md`, `addendum.md`, `decision-log.md`
|
2. Output: `prd.md`, `addendum.md`, `.memlog.md`
|
||||||
|
|
||||||
:::note[`bmad-prd` intents]
|
:::note[`bmad-prd` intents]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,237 +0,0 @@
|
||||||
{
|
|
||||||
"skill_name": "bmad-product-brief",
|
|
||||||
"_design_notes": "Single-shot evals across two patterns. Pattern A (A1-A8) tests artifact correctness given complete inputs in headless mode. Pattern B tests process discipline (decision log fidelity, polish execution, intent boundaries) by inspecting transcript and side-artifacts. Facilitation/conversation-quality evals are deferred to a future multi-turn simulator.",
|
|
||||||
"evals": [
|
|
||||||
{
|
|
||||||
"id": "A1",
|
|
||||||
"_pattern": "artifact-correctness",
|
|
||||||
"prompt": "Run headless. Create a product brief for InsuLens.\n\nContext (use exactly this — do not invent):\n- Product: a smartphone app that pairs with off-the-shelf $200 thermal imaging accessories (FLIR ONE Pro and Seek Compact Pro). The app guides homeowners through a structured walkthrough and produces a professional-grade insulation audit in under 20 minutes.\n- Target: suburban homeowners aged 35-65 with houses built before 2000 (poor original insulation, rising energy bills).\n- Validation evidence: 50 user interviews completed in Q4 2025; 78% expressed willingness to pay $49 for a one-time audit if results were credible.\n- Stakes: this brief is the primary input investors will read before our first Series A pitch call.\n- Hardware dependency: requires a thermal imaging accessory (we do not manufacture hardware).\n- Known unknowns: insurance/warranty implications of homeowner-driven audits; whether the 78% intent translates to paid conversion at scale.\nRight-size for investor-stage rigor. Output a JSON status block at the end with status, intent, and artifact paths.",
|
|
||||||
"expected_output": "A run folder containing brief.md (with valid YAML frontmatter) and decision-log.md. Brief is 1-2 pages, addresses target audience, hardware dependency, validation evidence, and surfaces unknowns alongside knowns. Final assistant message includes JSON with status='complete', intent='create', and artifact paths.",
|
|
||||||
"files": [],
|
|
||||||
"expectations": [
|
|
||||||
"A run folder is created with brief.md and decision-log.md",
|
|
||||||
"brief.md has YAML frontmatter containing all four required fields: title, status, created (ISO 8601), updated (ISO 8601)",
|
|
||||||
"brief.md frontmatter status is 'draft' or 'final' (not missing or empty)",
|
|
||||||
"brief.md word count is between 250 and 1500",
|
|
||||||
"brief.md identifies the suburban-homeowner-aged-35-65 target audience",
|
|
||||||
"brief.md references the thermal imaging hardware dependency (FLIR ONE Pro / Seek Compact Pro or equivalent)",
|
|
||||||
"brief.md references the 50-user interview validation OR the 78% willingness-to-pay finding",
|
|
||||||
"brief.md surfaces at least one explicit unknown or unvalidated assumption",
|
|
||||||
"brief.md does not introduce facts absent from the input prompt (no invented competitors, fabricated metrics, or unstated partnerships)",
|
|
||||||
"The final assistant message contains a JSON object with keys 'status', 'intent', and at least one artifact path",
|
|
||||||
"The JSON 'intent' value is 'create'"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "A2",
|
|
||||||
"_pattern": "artifact-correctness",
|
|
||||||
"prompt": "Run headless. Create a brief for our app idea.",
|
|
||||||
"expected_output": "Headless mode with insufficient context should halt with status='blocked' and a reason field. No (or only skeleton) brief should be written. The skill must not invent a product to draft against.",
|
|
||||||
"files": [],
|
|
||||||
"expectations": [
|
|
||||||
"The final assistant message contains a JSON object with key 'status' set to 'blocked'",
|
|
||||||
"The JSON output includes a 'reason' field explaining what context is missing",
|
|
||||||
"If brief.md exists at all, its body content (excluding frontmatter) is fewer than 100 words OR is a placeholder skeleton — the skill did not invent a product",
|
|
||||||
"The transcript contains no clarifying questions sent back to the user (headless mode honored)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "A3",
|
|
||||||
"_pattern": "artifact-correctness",
|
|
||||||
"prompt": "Run headless. Create a brief for our neighborhood compost coordinator app idea — we are moving forward with it. Q2 brainstorming session notes are at evals/bmm-skills/bmad-product-brief/files/q2-brainstorm.md; pull only what is relevant to the compost concept.",
|
|
||||||
"expected_output": "Brief focuses tightly on the compost coordinator concept. Source brainstorm is filtered, not ingested wholesale. Decision-log records that filtering occurred.",
|
|
||||||
"files": ["evals/bmm-skills/bmad-product-brief/files/q2-brainstorm.md"],
|
|
||||||
"expectations": [
|
|
||||||
"brief.md addresses the neighborhood compost coordinator concept",
|
|
||||||
"brief.md does not introduce content from unrelated brainstorm topics (weather + mood, meditation chime, podcasting tool, craft beer subscription, AI sommelier, office plants, ride coordinator, cookbook app, AR home staging)",
|
|
||||||
"brief.md word count is between 250 and 1500",
|
|
||||||
"brief.md incorporates at least 2 specific details from the compost section of the brainstorm (e.g., two-sided market with apartment dwellers and home compost-pile owners, hyperlocal neighborhood scope, free-at-launch with eventual subscription, Portland Sunnyside/Hawthorne pilot)",
|
|
||||||
"decision-log.md indicates the brainstorm was filtered for relevance, not ingested whole"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "A4",
|
|
||||||
"_pattern": "artifact-correctness",
|
|
||||||
"prompt": "Run headless. Validate the brief at evals/bmm-skills/bmad-product-brief/files/mossridge-brief/brief.md — the Mossridge Public Library board meets Monday and we need this to land. Read the addendum and decision-log in the same folder first. Cite specific sections, identify weaknesses, caveat what cannot be evaluated. Return inline only — no separate validation file.",
|
|
||||||
"expected_output": "Inline critique citing specific sections from the input brief. No new files. Caveats at least one claim that cannot be evaluated from the brief alone. Offers to roll findings into an Update.",
|
|
||||||
"files": [
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/mossridge-brief/brief.md",
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/mossridge-brief/addendum.md",
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/mossridge-brief/decision-log.md"
|
|
||||||
],
|
|
||||||
"expectations": [
|
|
||||||
"The final output cites specific section names or line content from the input brief (not generic feedback)",
|
|
||||||
"The output identifies at least one specific weakness or area for improvement in the input brief",
|
|
||||||
"The output explicitly caveats at least one claim that cannot be evaluated from the brief alone (e.g., community demand, funding feasibility, volunteer sustainability)",
|
|
||||||
"The output offers to roll findings into an Update (or equivalent next-step proposal)",
|
|
||||||
"The final assistant message contains a JSON object with intent='validate'"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "A5",
|
|
||||||
"_pattern": "artifact-correctness",
|
|
||||||
"prompt": "Run headless. Create a brief for: a weekend-project iOS app called Sproutkeeper that reminds houseplant owners when to water their plants based on plant type and indoor humidity sensor data. Target is hobbyist plant owners. MVP scope only, single-developer side project, no investors, no team, just personal evening project.",
|
|
||||||
"expected_output": "Lightweight brief right-sized to a side project. Low rigor. No investor-grade framing.",
|
|
||||||
"files": [],
|
|
||||||
"expectations": [
|
|
||||||
"The final assistant message contains a JSON object with intent='create'",
|
|
||||||
"brief.md exists at the path referenced in the JSON output",
|
|
||||||
"brief.md is right-sized for a side project (closer to 250-500 words than 1500)",
|
|
||||||
"brief.md does not include investor-grade framing (no 'Series A inputs', 'TAM/SAM/SOM', 'go-to-market strategy' boilerplate when the user said this is a personal evening project)",
|
|
||||||
"The transcript contains no clarifying questions to the user",
|
|
||||||
"Sections that do not earn their place for a side project are dropped or kept minimal (e.g., no extensive Risk or Success Criteria padding)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "A6",
|
|
||||||
"_pattern": "artifact-correctness",
|
|
||||||
"prompt": "Run headless. Create a brief from this memo. It is from our last working group on a new microcredential program at Branfield Community College. Memo is at evals/bmm-skills/bmad-product-brief/files/branfield-memo.md. Use what is there; do not re-elicit facts already present.",
|
|
||||||
"expected_output": "Brief reflects content from the memo. No re-asking for facts already present. Decision-log notes ingestion of the memo.",
|
|
||||||
"files": ["evals/bmm-skills/bmad-product-brief/files/branfield-memo.md"],
|
|
||||||
"expectations": [
|
|
||||||
"brief.md incorporates at least 3 distinct facts or decisions present in the input memo",
|
|
||||||
"decision-log.md references having used the memo as source material",
|
|
||||||
"The transcript does not ask the user to re-state the program name, target student, or core curriculum focus if those are present in the memo",
|
|
||||||
"brief.md does not invent program details not present in the memo"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "A7",
|
|
||||||
"_pattern": "artifact-correctness",
|
|
||||||
"prompt": "Run headless. Create a brief for Brightway — our smart bike helmet with crash detection, turn signals, and braking lights. Meridian Insights produced a market research report on e-mobility at evals/bmm-skills/bmad-product-brief/files/meridian-mobility-report.md. Use only what is relevant to the safety helmet category — do not let the e-scooter, charging-infrastructure, or bike-share segments bleed into the brief.",
|
|
||||||
"expected_output": "Brief focuses on the smart bike helmet concept. Pulls relevant findings from the helmet section. Other mobility segments do not appear.",
|
|
||||||
"files": ["evals/bmm-skills/bmad-product-brief/files/meridian-mobility-report.md"],
|
|
||||||
"expectations": [
|
|
||||||
"brief.md addresses the Brightway smart bike helmet concept",
|
|
||||||
"brief.md does not introduce content from unrelated mobility segments (e-scooters, charging infrastructure, bike-share, vehicle-to-grid)",
|
|
||||||
"brief.md word count is between 250 and 1500",
|
|
||||||
"brief.md incorporates at least 2 specific findings from the smart helmet section of the report (e.g., market sizing, key players, crash detection technology trends, regulatory or insurance landscape)",
|
|
||||||
"decision-log.md indicates the report was filtered to the helmet category rather than ingested whole"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "A8",
|
|
||||||
"_pattern": "artifact-correctness",
|
|
||||||
"prompt": "Run headless. Create a brief for Pantry Bridge — a meal-kit subscription targeted at adults 65+ who live alone and want fresh meals without grocery shopping. Customer research transcripts are at evals/bmm-skills/bmad-product-brief/files/pantry-bridge-interviews.md. Pull what is relevant from the older-adult interviews; do not conflate insights from the working-parent, student, or corporate-buyer personas.",
|
|
||||||
"expected_output": "Brief focuses on the older-adult target persona. Eleanor's interview drives the insights. Other personas do not pollute the brief.",
|
|
||||||
"files": ["evals/bmm-skills/bmad-product-brief/files/pantry-bridge-interviews.md"],
|
|
||||||
"expectations": [
|
|
||||||
"brief.md addresses the Pantry Bridge older-adult meal-kit concept",
|
|
||||||
"brief.md does not conflate insights from non-target personas (working parent Susan, college student Marcus, corporate cafeteria buyer Dimitri)",
|
|
||||||
"brief.md word count is between 250 and 1500",
|
|
||||||
"brief.md incorporates at least 2 specific insights from Eleanor's interview (e.g., grocery-trip difficulty, portion sizing, dietary restrictions, social aspects of meals, trust concerns)",
|
|
||||||
"decision-log.md notes which interviews were used and which were excluded"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "B1",
|
|
||||||
"_pattern": "process-discipline",
|
|
||||||
"prompt": "Run headless. Create a brief for HelmStack — an open-source observability platform for distributed systems.\n\nWe have made these specific decisions and want each captured in the decision log with rationale:\n\n1. Pricing: Free open-source core; paid SaaS at $29/seat/month. Rejected paid-one-shot-license model because it would limit network effects in the OSS community.\n2. Launch: Invite-only beta for 6 weeks before public launch. Rejected open public launch — operational risk too high before stability is proven on real workloads.\n3. Stack: TypeScript + Postgres for the backend. Rejected Go + MongoDB — TypeScript aligned better with our team's existing skills and the frontend codebase.\n4. ICP: 5-50 person engineering teams for MVP. Rejected enterprise-first focus because the sales cycle is too long for our capital runway.\n5. Self-host: SaaS-only at launch; self-host arrives in v2. Rejected concurrent self-host because it would slow shipping velocity past our funding window.\n\nProduce brief.md and decision-log.md.",
|
|
||||||
"expected_output": "Decision log contains all five named decisions with rationale captured. Brief reflects the decisions but the decision log is the canonical record.",
|
|
||||||
"files": [],
|
|
||||||
"expectations": [
|
|
||||||
"decision-log.md exists in the run folder",
|
|
||||||
"decision-log.md captures the pricing decision (free OSS + $29/seat SaaS) with the rejected alternative (paid one-shot license) and rationale (network effects)",
|
|
||||||
"decision-log.md captures the invite-only-beta decision with the rejected alternative (open public launch) and rationale (operational risk before stability)",
|
|
||||||
"decision-log.md captures the platform-stack decision (TypeScript + Postgres) with the rejected alternative (Go + MongoDB) and rationale (team skills / frontend alignment)",
|
|
||||||
"decision-log.md captures the ICP decision (5-50 person eng teams) with rationale referencing sales cycle / runway",
|
|
||||||
"decision-log.md captures the self-host-timing decision (SaaS-only at launch, self-host v2) with rationale (shipping velocity / funding window)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "B2",
|
|
||||||
"_pattern": "process-discipline",
|
|
||||||
"prompt": "Run headless. Create a brief for HelmStack — an open-source observability platform for distributed systems.\n\nWe have made these specific decisions and want each captured in the decision log with rationale:\n\n1. Pricing: Free open-source core; paid SaaS at $29/seat/month. Rejected paid-one-shot-license model because it would limit network effects in the OSS community.\n2. Launch: Invite-only beta for 6 weeks before public launch. Rejected open public launch — operational risk too high before stability is proven on real workloads.\n3. Stack: TypeScript + Postgres for the backend. Rejected Go + MongoDB — TypeScript aligned better with our team's existing skills and the frontend codebase.\n4. ICP: 5-50 person engineering teams for MVP. Rejected enterprise-first focus because the sales cycle is too long for our capital runway.\n5. Self-host: SaaS-only at launch; self-host arrives in v2. Rejected concurrent self-host because it would slow shipping velocity past our funding window.\n\nProduce brief.md and decision-log.md.",
|
|
||||||
"expected_output": "Brief is consistent with the decision log: every decision in the log is reflected in the brief, and no claim in the brief is absent from the input prompt or the log. Tests bidirectional fidelity.",
|
|
||||||
"files": [],
|
|
||||||
"expectations": [
|
|
||||||
"brief.md mentions the OSS-core + paid-SaaS pricing structure",
|
|
||||||
"brief.md references the invite-only-beta launch sequencing OR identifies the launch model consistent with the decision log",
|
|
||||||
"brief.md references the platform-stack choice (TypeScript + Postgres) OR is silent on stack — but does not contradict it (no mention of Go, MongoDB, etc.)",
|
|
||||||
"brief.md identifies 5-50 person eng teams as the ICP (or equivalent — small-to-mid-size eng teams)",
|
|
||||||
"brief.md does not introduce decisions, competitors, partnerships, metrics, or product features absent from both the input prompt and decision-log.md (no invented facts)",
|
|
||||||
"Each substantive decision in decision-log.md has a corresponding reflection in brief.md (no log-to-brief drops)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "B3",
|
|
||||||
"_pattern": "process-discipline",
|
|
||||||
"prompt": "Run headless. Create a product brief for InsuLens.\n\nContext (use exactly this — do not invent):\n- Product: a smartphone app that pairs with off-the-shelf $200 thermal imaging accessories (FLIR ONE Pro and Seek Compact Pro). The app guides homeowners through a structured walkthrough and produces a professional-grade insulation audit in under 20 minutes.\n- Target: suburban homeowners aged 35-65 with houses built before 2000.\n- Validation: 50 user interviews completed in Q4 2025; 78% willingness to pay $49 for a one-time audit.\n- Stakes: Series A pitch input.\n- Hardware: requires a thermal accessory (we do not manufacture hardware).\n\nProduce brief.md and decision-log.md. Run the polish phase before presenting.",
|
|
||||||
"expected_output": "The transcript shows the polish phase executing — the skill invokes bmad-editorial-review-structure and bmad-editorial-review-prose, either via the Skill tool directly or via Agent tool calls whose description or prompt targets those editorial skills. Both passes must occur after the initial draft is written and before the final JSON status block.",
|
|
||||||
"files": [],
|
|
||||||
"expectations": [
|
|
||||||
"The transcript contains either a Skill tool call invoking bmad-editorial-review-structure, OR an Agent tool call whose description or prompt references structural review or bmad-editorial-review-structure",
|
|
||||||
"The transcript contains either a Skill tool call invoking bmad-editorial-review-prose, OR an Agent tool call whose description or prompt references prose review or bmad-editorial-review-prose",
|
|
||||||
"Both editorial-pass dispatches (Skill or Agent) occur after the first Write tool call that creates brief.md",
|
|
||||||
"Both editorial-pass dispatches (Skill or Agent) occur before the final assistant message containing the JSON status block"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "B5",
|
|
||||||
"_pattern": "process-discipline",
|
|
||||||
"prompt": "Run headless. Update the brief at evals/bmm-skills/bmad-product-brief/files/forkbird-brief/brief.md — we have decided to add B2B catering services for corporate events, in addition to the direct-to-consumer delivery model. Read the existing decision-log.md and addendum.md in the same folder first.",
|
|
||||||
"expected_output": "The skill MUST detect the contradiction with the prior 'rejected B2B catering for MVP' decision (in decision-log.md) before applying the change. Acceptable resolutions: (a) halt with blocked status surfacing the conflict, or (b) apply the change with addendum.md capturing the override and rationale. Brief must not silently flip without acknowledging the prior decision.",
|
|
||||||
"files": [
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/forkbird-brief/brief.md",
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/forkbird-brief/addendum.md",
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/forkbird-brief/decision-log.md"
|
|
||||||
],
|
|
||||||
"expectations": [
|
|
||||||
"The transcript or output explicitly references the prior 'rejected B2B catering for MVP' decision from decision-log.md",
|
|
||||||
"The contradiction is surfaced before the brief body is modified (a Read of decision-log.md occurs before the Edit/Write to brief.md, AND the conflict is named in the assistant output)",
|
|
||||||
"Either the JSON status is 'blocked' with the conflict in the reason field, OR addendum.md is updated with an override entry capturing the rationale for reversing the prior decision",
|
|
||||||
"If the brief is updated, decision-log.md gains a new entry referencing the catering reversal",
|
|
||||||
"If the brief is updated, the YAML frontmatter 'updated' field is later than the original 'created' field"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "B6",
|
|
||||||
"_pattern": "process-discipline",
|
|
||||||
"prompt": "Run headless. Update the brief at evals/bmm-skills/bmad-product-brief/files/forkbird-brief/brief.md — we have signed our fifth chef partner (Chicago metro). Add this to the existing operating-model and what's-known sections. Read the existing decision-log.md first.",
|
|
||||||
"expected_output": "Clean update — does not contradict any prior decision. Brief gets updated, decision-log gains a new entry, YAML 'updated' bumps but 'created' stays the same. No spurious addendum since this is a status update, not an override.",
|
|
||||||
"files": [
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/forkbird-brief/brief.md",
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/forkbird-brief/addendum.md",
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/forkbird-brief/decision-log.md"
|
|
||||||
],
|
|
||||||
"expectations": [
|
|
||||||
"brief.md is updated to reflect the signed fifth chef partner in Chicago",
|
|
||||||
"brief.md frontmatter 'updated' field is later than the original 'created' timestamp; 'created' is unchanged",
|
|
||||||
"decision-log.md contains a new entry referencing the fifth chef signing",
|
|
||||||
"The transcript does not surface a fictional contradiction — this is a clean update, not an override of a prior decision"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "B7",
|
|
||||||
"_pattern": "process-discipline",
|
|
||||||
"prompt": "Run headless. Validate the brief at evals/bmm-skills/bmad-product-brief/files/mossridge-brief/brief.md — we are presenting to the library board Monday. Read the addendum and decision-log in the same folder. Cite specific sections. Return inline only.",
|
|
||||||
"expected_output": "Validate is read-only. No new files created. No existing files modified. Critique returned inline in the assistant output.",
|
|
||||||
"files": [
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/mossridge-brief/brief.md",
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/mossridge-brief/addendum.md",
|
|
||||||
"evals/bmm-skills/bmad-product-brief/files/mossridge-brief/decision-log.md"
|
|
||||||
],
|
|
||||||
"expectations": [
|
|
||||||
"No new files appear in the mossridge-brief artifacts directory after the run (only the three input files)",
|
|
||||||
"The input brief.md, addendum.md, and decision-log.md are byte-identical to the staged fixtures (no Edit/Write tool calls modified them)",
|
|
||||||
"The transcript contains no Write tool calls and no Edit tool calls targeting the mossridge-brief folder",
|
|
||||||
"The final assistant message contains a JSON object with intent='validate'"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "C1",
|
|
||||||
"_pattern": "config-compliance",
|
|
||||||
"prompt": "Run headless. Create a product brief for TaskFlow — a lightweight daily planning app for freelancers who juggle multiple clients. Core idea: a single daily view that pulls together tasks, time blocks, and client context so the freelancer always knows what to work on next. Target is independent freelancers, 1-3 clients at a time, who currently manage their day across sticky notes, calendar apps, and spreadsheets. MVP is mobile-first. No investors — the founder is bootstrapping.",
|
|
||||||
"expected_output": "Brief written in Spanish (document_output_language=Spanish). Assistant's conversational output reflects the configured British-accent communication style. Brief lands at the custom output path (test-output/artifacts/briefs/...) rather than the default _bmad-output path. Brief is right-sized for a bootstrapped solo project.",
|
|
||||||
"files": [],
|
|
||||||
"expectations": [
|
|
||||||
"brief.md exists under test-output/artifacts/briefs/ (the custom planning_artifacts path), not under _bmad-output/",
|
|
||||||
"The final JSON status block artifact paths reference test-output/ rather than _bmad-output/",
|
|
||||||
"brief.md body is written in Spanish — the majority of prose content (headings, section bodies) is in Spanish, not English",
|
|
||||||
"brief.md covers the TaskFlow concept: freelancer daily planning, multi-client context, the sticky-notes-plus-calendar-plus-spreadsheet problem",
|
|
||||||
"brief.md is right-sized for a bootstrapped side project — appropriate depth and scope for a solo-founder app with no investor audience, no TAM/SAM/SOM framing, no Series A language, and no sections that pad for enterprise credibility",
|
|
||||||
"The assistant's non-document output (transcript text content outside of brief.md) contains at least one marker of British informal register (e.g., 'mate', 'cheers', 'brilliant', 'sorted', 'innit', 'blimey', 'proper', 'right then', or equivalent pub-idiom phrasing)"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
# Working Group Notes — Microcredential Program
|
|
||||||
|
|
||||||
**Branfield Community College**
|
|
||||||
**Meeting:** 2026-04-22
|
|
||||||
**Attendees:** Provost, Workforce Dev Director, Chair of Industry Advisory Board, two faculty leads (Data Analytics, Healthcare Admin), Financial Aid Director
|
|
||||||
|
|
||||||
## Why we're doing this
|
|
||||||
|
|
||||||
Regional employer survey (Q1 2026) showed 340+ unfilled mid-skill jobs in the three-county area. State workforce board approved a $1.4M grant if we can launch by fall 2027 with at least three tracks. Existing AAS programs are too long for working adults — average completion 3.5 years.
|
|
||||||
|
|
||||||
## What we're building
|
|
||||||
|
|
||||||
Six-month stackable microcredentials. Three tracks at launch:
|
|
||||||
|
|
||||||
1. **Data Analytics** (SQL, Excel/Power BI, intro Python). Faculty lead Marisol Reyes. Strongest employer demand. Will be MVP — first to launch, used to validate format.
|
|
||||||
2. **Healthcare Admin** (medical coding, EHR systems, patient workflow). Faculty lead Dev Patel. Aging population in region drives demand.
|
|
||||||
3. **Sustainable Construction** (green building practices, retrofit basics, code compliance). New faculty hire required.
|
|
||||||
|
|
||||||
Stackable means credits transfer into related AAS or BAS later if the student wants.
|
|
||||||
|
|
||||||
## Decisions made today
|
|
||||||
|
|
||||||
- **Data Analytics is MVP.** Launch fall 2027, others phase in spring/fall 2028. Validate format before scaling.
|
|
||||||
- **Hybrid delivery.** Two evenings/week in person + asynchronous online. Board rejected pure-online (concerns about adult learner outcomes data).
|
|
||||||
- **Stipend program.** Up to $3,000/student for low-income students, funded from the state grant. Means-tested.
|
|
||||||
- **Industry Advisory Board** has approval authority on curriculum. Three employers committed (regional hospital, mid-size data consultancy, county housing authority). All three commit to interview every graduate.
|
|
||||||
- **Cohort cap: 24 per track per term.** Driven by classroom size and faculty load.
|
|
||||||
|
|
||||||
## Open questions
|
|
||||||
|
|
||||||
- Childcare for evening sessions — can we partner with the campus childcare center? Deferred to next meeting.
|
|
||||||
- Marketing — provost wants to know cost per enrolled student before approving budget. Need workforce dev to model.
|
|
||||||
- Do we offer a tuition payment plan in addition to the stipend? Financial aid director thinks yes; provost wants to see uptake projections first.
|
|
||||||
|
|
||||||
## What we're NOT doing
|
|
||||||
|
|
||||||
- Not pursuing pure-online delivery (rejected — see above).
|
|
||||||
- Not launching all three tracks at once (rejected — risk concentration, faculty bandwidth).
|
|
||||||
- Not building employer-customized cohorts (rejected — too operationally complex for MVP).
|
|
||||||
|
|
||||||
## Next steps
|
|
||||||
|
|
||||||
- Workforce Dev: marketing cost model by 2026-05-15.
|
|
||||||
- Provost: childcare partnership exploratory conversation.
|
|
||||||
- Faculty leads: draft data analytics curriculum outline by 2026-06-01.
|
|
||||||
- Reconvene 2026-05-20.
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
# Addendum — Forkbird Kitchen
|
|
||||||
|
|
||||||
## Options considered (and not taken)
|
|
||||||
|
|
||||||
### B2B / corporate catering
|
|
||||||
|
|
||||||
Considered as a parallel revenue stream from day one. Rejected for MVP. Different operational rhythm (bulk orders, fixed delivery windows, invoiced billing), different customer (procurement, not eaters), different unit economics. Splitting attention at launch risked degrading both. Revisit if consumer foundation is established by month 12.
|
|
||||||
|
|
||||||
### Subscription / meal plan
|
|
||||||
|
|
||||||
Considered as a recurring-revenue layer. Rejected for MVP. Operationally expensive at our planned scale: requires demand forecasting per subscriber, kitchen scheduling locked further out, and packaging/refrigerated handling we are not yet equipped for. Reasonable to revisit once kitchen utilization stabilizes.
|
|
||||||
|
|
||||||
### Retail / grocery channel
|
|
||||||
|
|
||||||
Considered (refrigerated meals in Whole Foods, Sprouts). Rejected for MVP. Different product (cold meals, longer shelf life, different texture profile), different go-to-market (broker relationships, slotting fees, category management). Parked for year 2 — would require a separate product line, not a channel extension.
|
|
||||||
|
|
||||||
### Lower-priced everyday tier
|
|
||||||
|
|
||||||
Considered. Rejected for now. The brand position is chef-driven; introducing a value tier alongside risks the premium signal in marketplace search ranking and review patterns. Explored alternative of separate brand for value tier; deferred.
|
|
||||||
|
|
||||||
## Personas (extended)
|
|
||||||
|
|
||||||
**The plant-based weekday professional.** Lives in a dense urban neighborhood, orders 4–6 times a month, splits between own-cooking and delivery. Sources of dissatisfaction with current options: chain plant-based menus feel formulaic, fine-dining plant-based is too expensive for weeknight, marketplace search surfaces too many low-quality options.
|
|
||||||
|
|
||||||
**The dietary-flex household member.** One person in a household is plant-based by preference; the other(s) are not. Ordering pattern is "tonight one of us wants Forkbird, the other wants something else." We benefit from being a dependable single-cuisine option that doesn't require negotiating across diets.
|
|
||||||
|
|
||||||
## Sizing notes
|
|
||||||
|
|
||||||
- Total addressable: ~6.2M urban professionals across 5 metros eating plant-based 3+ times/week (based on 2024 Plant Based Foods Association data, urban segmentation).
|
|
||||||
- Serviceable addressable (within delivery radius of planned kitchens at launch): ~840K.
|
|
||||||
- Realistic Y1 capture (per metro forecast): 0.4% of SAM = 3,360 active customers across all metros.
|
|
||||||
|
|
||||||
## Sourcing standard — exact wording
|
|
||||||
|
|
||||||
"For each dish on the menu, we publish the source of every ingredient that represents at least 5% of cost. We commit that at least 60% of total ingredient weight is sourced within 200 miles of the kitchen preparing that dish. Both numbers are auditable; we publish them per-dish in the app. If we cannot meet the 60% local threshold for a dish, the dish does not ship."
|
|
||||||
|
|
||||||
## Technical constraints
|
|
||||||
|
|
||||||
- Marketplace integration (DoorDash, UberEats, Grubhub) requires their menu management API. We are using a third-party middleware (Olo) to avoid maintaining three separate integrations.
|
|
||||||
- Ingredient transparency display requires structured data per dish. We need an ingredient-master database; current option is to extend our recipe-management software vendor.
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
---
|
|
||||||
title: Forkbird Kitchen — Product Brief
|
|
||||||
status: final
|
|
||||||
created: 2026-02-14
|
|
||||||
updated: 2026-02-14
|
|
||||||
---
|
|
||||||
|
|
||||||
# Forkbird Kitchen
|
|
||||||
|
|
||||||
## What it is
|
|
||||||
|
|
||||||
A delivery-only ghost kitchen brand offering chef-driven plant-based meals in five US metros: San Francisco, New York, Los Angeles, Seattle, and Chicago. Launch operating model is direct-to-consumer through our own iOS/Android app and the major third-party marketplaces (DoorDash, UberEats, Grubhub).
|
|
||||||
|
|
||||||
## Who it's for
|
|
||||||
|
|
||||||
Urban professionals aged 28–45 who eat plant-based meals at least three times a week, value chef-driven food over chain alternatives, and order delivery 4+ times monthly. Initial geographic focus is dense neighborhoods within 3-mile delivery radii of partner kitchens.
|
|
||||||
|
|
||||||
We are not building for: families with children (different ticket size and ordering pattern), occasional plant-based eaters (price sensitivity too high for our positioning), or office lunch (different time-of-day operation).
|
|
||||||
|
|
||||||
## Why it wins
|
|
||||||
|
|
||||||
Three things are deliberately stacked:
|
|
||||||
|
|
||||||
1. **Chef partnerships, not chef-as-marketing.** Each metro has a named chef (with prior fine-dining or notable plant-based credit) who designs the rotating menu and earns equity in that metro's P&L. They are not endorsers; they are operators.
|
|
||||||
2. **Ingredient sourcing standards.** Published per-dish: where it came from, how it was farmed, what portion of cost it represents. No dish ships if we can't source within 200 miles for ≥60% of ingredient weight. This is auditable, not marketing copy.
|
|
||||||
3. **Speed without cars.** Average ticket-to-door is 28 minutes from order placement, achieved by tight delivery radii and dense order density per kitchen. Long delivery erodes plant-based texture more than animal protein — speed is product, not logistics.
|
|
||||||
|
|
||||||
## Operating model
|
|
||||||
|
|
||||||
Five kitchens, one per metro, each leased space inside an existing food-prep facility. No customer-facing storefronts. App orders go through our stack; marketplace orders pass through their stacks. Menu rotates every six weeks per chef.
|
|
||||||
|
|
||||||
Pricing tier: $14–$22 per entrée before delivery. We are deliberately at chef-driven positioning, not value positioning.
|
|
||||||
|
|
||||||
## What's known
|
|
||||||
|
|
||||||
- Demand validated through three pop-up dinners in SF and NY (Q4 2025). 480 covers, 78% repeat intent based on post-event survey.
|
|
||||||
- Operating partner identified in each metro. Leases signed for SF, NY, LA. Seattle and Chicago in negotiation.
|
|
||||||
- Three of five chefs signed; two in active conversations.
|
|
||||||
|
|
||||||
## What's unknown
|
|
||||||
|
|
||||||
- Whether ingredient-sourcing transparency is a differentiator at point of sale (in-app) or only in marketing. Our hypothesis is "both" but we have not tested in-app.
|
|
||||||
- Marketplace economics. DoorDash takes 15–30% depending on tier; we are modeling the lower tier but have not negotiated.
|
|
||||||
- Whether the 3-mile radius holds outside SF/NY (lower density in LA/Chicago).
|
|
||||||
|
|
||||||
## Risks
|
|
||||||
|
|
||||||
- Chef churn. If a metro chef leaves, the metro brand loses its anchor. Mitigation: equity vesting over 24 months, named-chef terms in operating agreement.
|
|
||||||
- Sourcing cost volatility. 60% local-within-200-miles can spike with weather/supply disruption. We have not modeled the worst case.
|
|
||||||
- Marketplace dependency. If DoorDash terms shift adversely, our blended margin is at risk. We are deliberately building the owned-app channel to reduce this dependency.
|
|
||||||
|
|
||||||
## Success criteria for first 12 months
|
|
||||||
|
|
||||||
- 4 of 5 metros operating profitably at the unit level (kitchen + chef + delivery economics) by month 9
|
|
||||||
- 30% of orders through owned app (vs. marketplaces) by month 12
|
|
||||||
- Chef retention 100% through year 1
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
# Decision Log — Forkbird Kitchen
|
|
||||||
|
|
||||||
## 2026-01-08
|
|
||||||
- **Brand position: chef-driven, premium plant-based.** Considered value tier; rejected for MVP. Premium positioning is the wedge against marketplace generic plant-based.
|
|
||||||
|
|
||||||
## 2026-01-12
|
|
||||||
- **Five-metro launch: SF, NY, LA, Seattle, Chicago.** Considered three-metro start; rejected as not enough density to test the chef-equity model meaningfully.
|
|
||||||
- **Ghost kitchen, no storefront.** Storefronts ruled out — capex too high for MVP, dilutes the speed advantage.
|
|
||||||
|
|
||||||
## 2026-01-19
|
|
||||||
- **Pricing tier $14–$22 per entrée.** Modeled against three competitor sets: chain plant-based, fine-dining plant-based delivery, generic mid-tier delivery. Sits cleanly above chain, below fine-dining.
|
|
||||||
- **Chef equity in metro P&L.** Rejected flat fee + revenue share alternative; equity creates the operator incentive we want.
|
|
||||||
|
|
||||||
## 2026-01-26
|
|
||||||
- **Rejected B2B catering segment for MVP.** Different operational rhythm and customer; would split attention at launch and risk degrading both consumer and B2B execution. Revisit in year 2 if consumer foundation is solid. (Discussion: 2 hours; chef partners weighed in against splitting focus; CFO modeled the dilution effect on consumer kitchen utilization.)
|
|
||||||
- **Rejected subscription model for MVP.** Operationally expensive at planned scale; revisit once kitchen utilization stabilizes.
|
|
||||||
|
|
||||||
## 2026-02-02
|
|
||||||
- **Sourcing standard: 60% within 200 miles, published per-dish.** Considered weaker thresholds (50% / 250 miles); rejected as not differentiating enough to be worth publishing. The number has to be defensible.
|
|
||||||
- **Marketplace channel mix: own app + DoorDash + UberEats + Grubhub.** Considered own-app only; rejected as too slow on demand acquisition. Considered marketplaces only; rejected — own app is critical to long-term margin.
|
|
||||||
|
|
||||||
## 2026-02-09
|
|
||||||
- **Six-week menu rotation per chef.** Considered four-week (more freshness) and eight-week (more operational stability). Six is the compromise; reassess after first two cycles.
|
|
||||||
- **Marketing budget: 60% acquisition / 40% brand.** Rejected pure-acquisition because chef-driven positioning needs brand-level signal that paid acquisition alone won't carry.
|
|
||||||
|
|
||||||
## 2026-02-14
|
|
||||||
- **Brief finalized for Series A inputs.** Status moved to final.
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
# E-Mobility Market Report 2026
|
|
||||||
|
|
||||||
**Prepared by:** Meridian Insights
|
|
||||||
**Date:** Q2 2026
|
|
||||||
**Coverage:** North America, with comparative reference to EU markets
|
|
||||||
**Engagement code:** MI-2026-EMOB-007
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Executive Summary
|
|
||||||
|
|
||||||
The e-mobility category continues a multi-year structural shift from "alternative transportation" to mainstream mobility infrastructure. North American unit volume across e-bikes, e-scooters, and connected safety hardware grew 18% year-over-year in 2025, against a 6% growth rate for traditional bicycles. Three macro factors are durably reshaping the category: regulatory clarity at the state level (29 US states now have explicit e-bike classifications, up from 14 in 2022), insurance industry interest in telematics-style risk pricing, and a generational shift in commuting preferences among the 28-44 cohort.
|
|
||||||
|
|
||||||
This report covers seven segments of the broader e-mobility landscape: e-bike retail, e-scooter regulation, bike-share systems, charging infrastructure, smart helmet hardware, and grid-integration trends. Findings are synthesized from 142 stakeholder interviews, 18 retailer site visits, government regulatory filings, and proprietary point-of-sale data from 4,200 specialty retail outlets.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Methodology
|
|
||||||
|
|
||||||
Quantitative data was sourced from Meridian's proprietary Mobility Retail Panel (MRP), which aggregates POS data from independent specialty retailers and select chain operators. Where panel data is incomplete or lagging, we supplemented with manufacturer-reported shipment volumes and customs/import filings. Qualitative findings draw on 142 interviews conducted between November 2025 and March 2026 with retailers, fleet operators, regulators, manufacturers, and end users.
|
|
||||||
|
|
||||||
Helmet category sizing uses a separate methodology described in Section 8, blending CPSC compliance filings, manufacturer disclosures, and a sample purchase-intent survey of 3,400 cyclists.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Section 3: Market Sizing — Total E-Mobility
|
|
||||||
|
|
||||||
The North American e-mobility market reached an estimated $14.7B in retail volume in 2025, up from $12.5B in 2024. The largest segment by volume is e-bikes at $7.2B, followed by e-scooter retail at $2.8B (excluding shared-fleet operations), bike-share and dockless mobility services at $2.1B, charging infrastructure at $1.8B, and connected safety hardware at $0.8B.
|
|
||||||
|
|
||||||
Compound annual growth rate (CAGR) forecasts through 2030 vary substantially by segment. We forecast 14% CAGR for e-bikes, 6% for e-scooters (decelerating as the regulatory regime stabilizes), 9% for bike-share, 22% for charging infrastructure (driven by both bike and scooter charging), and 31% for connected safety hardware (off a smaller base). Vehicle-to-grid (V2G) integration is too early to forecast reliably; we treat it as an emerging segment.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Section 4: E-Bike Market Deep Dive
|
|
||||||
|
|
||||||
E-bikes represent the largest single segment by retail value. The 2025 unit mix favored Class 1 (pedal-assist, max assisted speed 20 mph) at 58% of units, Class 2 (throttle, max 20 mph) at 24%, and Class 3 (pedal-assist, max 28 mph) at 18%. Class 3 is the fastest-growing classification on a unit basis, driven by suburban commuter demand.
|
|
||||||
|
|
||||||
Manufacturer concentration shifted in 2025. The top 10 brands by unit volume now hold 64% of the market, up from 51% in 2022 — consolidation that mirrors patterns seen in the traditional bicycle market in the early 2000s. Specialized, Trek, and Cannondale (operating their respective electric sub-brands) represent the top three. Direct-to-consumer brands (Rad Power, Lectric, Aventon) collectively hold approximately 19% of retail value.
|
|
||||||
|
|
||||||
Retail channel split favored independent specialty bike shops at 47% of unit volume, with direct-to-consumer at 28%, big-box retail at 17%, and e-commerce marketplaces (Amazon, Walmart.com) at 8%. The independent specialty channel commands a price premium of approximately 22% over comparable D2C alternatives, attributed to in-store fitting, post-sale service relationships, and higher-margin component upgrades.
|
|
||||||
|
|
||||||
Notable trends in 2025: cargo e-bike sub-segment grew 41% YoY (small base, dense urban geographies); battery range claims continue to drift upward with manufacturer claims of 60+ mile range becoming standard for $2,500+ price points; bottom-bracket motor placement (mid-drive) gained share over hub-drive in the $3,000+ tier.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Section 5: E-Scooter Regulatory Landscape
|
|
||||||
|
|
||||||
The North American e-scooter regulatory environment matured significantly during 2024-2025 after several years of municipal experimentation and reactive policymaking. Forty-one US cities now operate under what we classify as "stable" regulatory regimes (defined as: explicit operating permit framework, defined sidewalk/bike-lane rules, helmet provisions, and revenue-share or fee structures with the city). This is up from 19 cities in 2022.
|
|
||||||
|
|
||||||
The regulatory shift has compressed operator margins. Permit fees and per-trip surcharges in major markets (Los Angeles, Chicago, Atlanta, Denver) range from $0.15 to $0.42 per trip, against average ride revenue of $5.40. Several major operators have exited markets where permit economics have proven unviable; Lime exited five secondary US markets in 2025 citing exactly this reason.
|
|
||||||
|
|
||||||
Helmet requirements remain inconsistent. Thirteen US states require helmets for riders under 18 only; seven require them for all riders; the rest leave it to municipalities. Enforcement is widely acknowledged to be minimal even where mandates exist. EU markets are substantially stricter, with mandatory helmet provisions in France, Germany, and Italy applying to all e-scooter riders.
|
|
||||||
|
|
||||||
Insurance treatment is also fragmenting. Five US states have classified e-scooters as "motor vehicles" requiring liability coverage, raising the floor on operating costs for shared-fleet providers. Most states still treat them as bicycles for insurance purposes.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Section 6: Bike-Share and Dockless Mobility
|
|
||||||
|
|
||||||
Docked bike-share systems (Citi Bike, Divvy, Bluebikes, Capital Bikeshare) continue stable, slow growth. Capital Bikeshare reported 5.1M trips in 2025 (5% growth); Citi Bike reported 38M (8% growth). Docked systems benefit from station infrastructure that creates predictability for riders and meters demand-side adoption.
|
|
||||||
|
|
||||||
Dockless bike-share (without fixed stations) is largely consolidated; the experimentation phase ended in 2023. Lyft operates the dominant national network through its acquired bike-share division, with regional players in select markets. Operating economics for dockless are structurally weaker than docked due to vehicle redistribution costs, vandalism rates, and the absence of station-driven advertising revenue.
|
|
||||||
|
|
||||||
A notable trend is the convergence of bike-share and dockless e-bike subscription models. Several operators now offer monthly memberships that include unlimited 30-minute trips on dockless e-bikes within a service zone. Adoption is concentrated in dense urban cores where car-free lifestyles are practical.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Section 7: Charging Infrastructure Trends
|
|
||||||
|
|
||||||
Charging infrastructure for e-bikes and e-scooters has emerged as a meaningful sub-segment, growing 28% in 2025. The dominant form factor remains residential at-home wall chargers (87% of installed base), but commercial charging — at workplaces, transit stations, and apartment buildings — is the fastest-growing sub-segment.
|
|
||||||
|
|
||||||
Standardization remains a constraint. Battery interfaces have not converged; Bosch, Shimano, and various proprietary systems coexist. The European Union's USB-C mandate for portable electronics has not yet extended to e-mobility; industry observers expect regulatory pressure to follow within 3-5 years.
|
|
||||||
|
|
||||||
Workplace charging is increasingly common in tech and creative-industry employers; we estimate 31% of large urban employers in tech-heavy metros now offer workplace e-bike charging, up from 12% in 2022. Apartment buildings lag — 7% of class-A multifamily properties offer common-area charging, with retrofit cost cited as the primary barrier.
|
|
||||||
|
|
||||||
Public charging at transit hubs (subway/light rail stations) remains a stated priority across most major metro transit authorities, but actual installation lags policy commitments significantly. Funding fragmentation and permitting delays are the consistently cited bottlenecks.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Section 8: Smart Helmet Category
|
|
||||||
|
|
||||||
The connected safety hardware category — colloquially "smart helmets" — is the smallest segment we cover by retail value but has the strongest growth profile. The North American smart helmet market reached $810M in retail value in 2025, up from $480M in 2023, representing a 30% CAGR. We forecast $2.4B by 2030, contingent on the resolution of two open questions detailed below.
|
|
||||||
|
|
||||||
**Category definition.** We define "smart helmets" as helmets that include at least one connected safety feature: turn signals (typically wireless-controlled), braking lights (auto-activated via accelerometer), crash detection (auto-notification to emergency contacts on detected impact), or integrated navigation/audio (bone-conduction speakers, often paired with smartphone apps). Helmets with passive integrated lighting only (no connectivity) are excluded from this category and tracked under traditional helmet retail.
|
|
||||||
|
|
||||||
**Key players.** The category remains fragmented; no single manufacturer commands more than 15% market share. Top five by 2025 retail volume: Lumos Helmet (US, market leader at ~14% share with strong DTC presence), Sena Technologies (Korea, intercom heritage, ~11%), Coros (US/China, multi-sport, ~9%), Specialized ANGi (US, premium tier at ~7%), and POC Aid (Sweden, premium safety positioning at ~6%). Approximately 30 smaller brands hold the remaining share.
|
|
||||||
|
|
||||||
**Crash detection technology.** Two architectures dominate: single-accelerometer crash detection (lower cost, higher false-positive rate) and multi-sensor fusion (accelerometer + gyroscope + GPS movement signature, lower false-positive rate but higher BOM cost). Insurance industry sources indicate that multi-sensor systems are likely to become a baseline requirement for any insurance discount programs, given that single-accelerometer systems triggered roughly 1 false alert per 47 hours of riding in our test panel.
|
|
||||||
|
|
||||||
**Regulatory landscape.** Smart helmets sit at the intersection of two regulatory regimes: the Consumer Product Safety Commission's bicycle helmet standard (16 CFR 1203, governing impact protection) and the Federal Communications Commission's regulation of intentional radiators (governing the radio components for Bluetooth/cellular). Compliance with both is non-trivial. Eight smart helmet brands have had FCC Part 15 violations issued since 2023, typically for emissions exceeding limits during compliance testing. EU markets additionally require EN 1078 certification for the helmet shell; this is widely held but adds 3-5 months to a typical product development timeline.
|
|
||||||
|
|
||||||
**Insurance industry interest.** Major auto insurers (State Farm, Progressive, Geico, Nationwide) are actively piloting telematics-style discount programs for cyclists who use connected safety helmets. The proposed structure mirrors auto-insurance "good driver" discount frameworks, with discounts of 5-15% on cycling-specific insurance riders or umbrella policies. As of Q1 2026, three insurers have public pilot programs and one (Progressive) has announced general availability for 2027. This could materially accelerate category adoption if discounts materialize at the upper end of the proposed range.
|
|
||||||
|
|
||||||
**Distribution.** D2C dominates at 58% of retail value, reflecting the still-emerging category and the absence of strong channel inventory in independent bike shops. The specialty bike shop channel is growing rapidly (up from 12% to 22% of retail value over 2023-2025) as the category gains category-management attention from major distributors. Big-box channels (REI, Dick's Sporting Goods) are present but shallow in selection — typically 4-8 SKUs versus 40+ in dedicated specialty.
|
|
||||||
|
|
||||||
**Open questions for the segment.** Our growth forecast is conditioned on (a) the proportion of insurers that follow Progressive into general availability of connected-safety discounts; (b) whether multi-sensor crash detection becomes a category baseline (lifting ASP) or remains a premium-tier feature; and (c) whether the current high false-positive rate of single-accelerometer systems triggers a consumer backlash that suppresses category trust before insurance discounts arrive. The downside scenario produces a 2030 category size of $1.4B versus our base-case $2.4B.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Section 9: Vehicle-to-Grid Integration
|
|
||||||
|
|
||||||
Vehicle-to-grid (V2G) integration of e-bike and e-scooter batteries is an emerging area, but practical commercial deployment is years away. The thesis is that fleet-scale dockless e-bikes and e-scooters represent meaningful aggregate battery capacity that could participate in demand-response markets, particularly in deregulated electricity markets.
|
|
||||||
|
|
||||||
Several technical preconditions must be met: standardized battery interfaces (currently absent), bidirectional charging hardware (rare), aggregator software stack (early-stage), and regulatory clarity on energy market participation by mobility fleets (pre-policy). We treat this as a watch item for 2028+ rather than a current investable theme.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Section 10: Outlook
|
|
||||||
|
|
||||||
Our base-case forecast for North American e-mobility is $22.5B by 2030, with the e-bike segment reaching $11.8B (the largest), connected safety hardware reaching $2.4B (the fastest-growing in percentage terms), and charging infrastructure reaching $4.2B (driven by commercial and multifamily retrofit demand). Bike-share and dockless mobility plateau in the $2.5-3.0B range as urban density limits adoption ceilings.
|
|
||||||
|
|
||||||
The largest single uncertainty in this forecast is the trajectory of insurance industry adoption of connected-safety telematics, which could accelerate or substantially constrain the smart helmet segment and, secondarily, influence rider behavior across the broader category. We will revisit forecasts in our Q4 2026 update.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*This report is prepared for the exclusive use of Meridian Insights subscribers. Reproduction or external distribution without written permission is prohibited.*
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
# Addendum — Mossridge Tool Lending Library
|
|
||||||
|
|
||||||
## Options considered
|
|
||||||
|
|
||||||
### Paid lending model (rejected)
|
|
||||||
|
|
||||||
Considered charging a nominal per-loan fee ($2–$5) to cover replacement and maintenance. Rejected as inconsistent with library mission of free access. Board has previously stated free access is non-negotiable for core services. A donation jar at checkout was proposed as a soft alternative; deferred.
|
|
||||||
|
|
||||||
### Hardware store partnership (considered, deferred)
|
|
||||||
|
|
||||||
Mossridge Hardware (the store committing in-kind donations) offered to host a satellite lending point. Considered; deferred to year 2. The integration adds operational complexity (split inventory, cross-location tracking) we are not equipped for at launch. Reasonable to revisit once the main location is established.
|
|
||||||
|
|
||||||
### Mobile lending van (rejected)
|
|
||||||
|
|
||||||
Proposed by a board member to serve outlying areas. Rejected for MVP — capital cost ($35K+ for vehicle + outfitting) exceeds the entire grant. Could be a year-three expansion if demand validates.
|
|
||||||
|
|
||||||
### Skills classes alongside tool loans (deferred)
|
|
||||||
|
|
||||||
Considered offering "how to use a power drill" classes as a value-add. Deferred — interesting but distinct programming, not part of the lending service's MVP scope. Adult Services Librarian is interested in piloting separately.
|
|
||||||
|
|
||||||
## Reference programs reviewed
|
|
||||||
|
|
||||||
- Berkeley Tool Lending Library (operating since 1979, ~3,000 tools, 250+ daily loans). Funded as a city service.
|
|
||||||
- Oakland Tool Lending Library (operating since 2000, smaller catalog, library-staffed).
|
|
||||||
- Toronto Tool Library (nonprofit, member-supported, paid model — different funding architecture).
|
|
||||||
|
|
||||||
Direct correspondence with Berkeley TLL staff (March 2026) suggested:
|
|
||||||
- Theft has been low (~2% annually) due to library card requirement and community norms
|
|
||||||
- The biggest sustainability risk has been staff hours, not tool replacement
|
|
||||||
- Most successful programs have a paid coordinator role, not pure volunteer
|
|
||||||
|
|
||||||
## Potential expansion (year 2+)
|
|
||||||
|
|
||||||
- Hardware store satellite location
|
|
||||||
- Specialty tool categories: woodworking, automotive, sewing
|
|
||||||
- Skills classes paired with relevant tool checkouts
|
|
||||||
- Seed/cuttings library co-located in spring/summer
|
|
||||||
|
|
||||||
## Insurance and liability — current state
|
|
||||||
|
|
||||||
Library counsel (Town of Mossridge legal department) has been consulted informally. Formal opinion pending. Existing policy covers patrons in the building; coverage for tool use off-premises is the open question. Awaiting written response before submitting grant application.
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
---
|
|
||||||
title: Mossridge Public Library — Tool Lending Library Proposal
|
|
||||||
status: final
|
|
||||||
created: 2026-04-30
|
|
||||||
updated: 2026-04-30
|
|
||||||
---
|
|
||||||
|
|
||||||
# Tool Lending Library at Mossridge Public Library
|
|
||||||
|
|
||||||
## What we're proposing
|
|
||||||
|
|
||||||
A free tool-lending service operated out of the Mossridge Public Library, modeled on similar programs in Berkeley, Oakland, and Toronto. Cardholders borrow hand and power tools (drills, saws, ladders, sanders, plumbing snakes, gardening tools) for up to seven days, free of charge.
|
|
||||||
|
|
||||||
## Why now
|
|
||||||
|
|
||||||
Mossridge residents face rising costs of home maintenance and DIY supplies. Anecdotally, demand for community-shared resources is high — staff have fielded "do you lend tools?" requests for years. A tool library extends the library's mission of equitable access to information and skill-building into the practical-skills domain.
|
|
||||||
|
|
||||||
## Who it serves
|
|
||||||
|
|
||||||
Mossridge residents with active library cards. Primary audience: single-family homeowners doing their own home repairs, renters making minor improvements with landlord permission, hobbyist woodworkers and gardeners. Estimated 8,000 households in the library's service area.
|
|
||||||
|
|
||||||
## Service design
|
|
||||||
|
|
||||||
- **Catalog:** Approximately 200 tools to start, prioritizing the most-requested categories (drilling, cutting, sanding, ladders, garden).
|
|
||||||
- **Loan period:** Seven days, one renewal allowed if no holds.
|
|
||||||
- **Borrower requirements:** Active library card, signed liability waiver, completed safety briefing for power tools.
|
|
||||||
- **Location:** Library basement, currently underutilized storage. Accessible by elevator.
|
|
||||||
- **Hours:** Tuesday–Saturday during library hours; tools returned via after-hours drop slot when closed.
|
|
||||||
|
|
||||||
## Funding
|
|
||||||
|
|
||||||
- ARPA infrastructure grant: $42,000 (anticipated, application pending)
|
|
||||||
- Friends of the Mossridge Library matching funds: $10,000 (committed)
|
|
||||||
- In-kind tool donations from Mossridge Hardware (committed in principle)
|
|
||||||
|
|
||||||
Year-one operating cost is estimated at $48,000, primarily tool purchase, maintenance supplies, and shelving/storage retrofit. Ongoing cost (year two and beyond) projected at $12,000 annually for replacement tools and consumables.
|
|
||||||
|
|
||||||
## Operations
|
|
||||||
|
|
||||||
The service will be run by trained library volunteers, supervised by the Adult Services Librarian. Volunteer training program to be developed in partnership with Mossridge Vocational Center. Estimated 4–6 active volunteers needed at any given time, with a roster of 12–15 trained volunteers to provide coverage.
|
|
||||||
|
|
||||||
## Risks
|
|
||||||
|
|
||||||
- **Theft and loss.** Tools are valuable and portable. Mitigation: deposit on power tools (refundable), card-required checkout, photo documentation at loan and return.
|
|
||||||
- **Liability.** Borrower waivers will be required; the library's existing insurance policy is being reviewed for coverage.
|
|
||||||
- **Demand uncertainty.** We do not yet know the actual borrowing volume the service will see.
|
|
||||||
|
|
||||||
## Success criteria
|
|
||||||
|
|
||||||
- Launch by Q3 2027 with a catalog of 200 tools.
|
|
||||||
- 300 unique borrowers in the first year of operation.
|
|
||||||
- Zero serious injury incidents.
|
|
||||||
- Tool loss rate under 5% per year.
|
|
||||||
|
|
||||||
## What we're asking
|
|
||||||
|
|
||||||
Board approval to proceed with the ARPA grant application and finalize the service design for fall 2027 launch.
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
# Decision Log — Mossridge Tool Lending Library
|
|
||||||
|
|
||||||
## 2026-03-04
|
|
||||||
- **Pursuing the project.** Adult Services Librarian + Library Director agreed there's enough informal demand signal (years of "do you lend tools?" inquiries) to investigate seriously. Acknowledged that informal inquiries are not the same as validated demand.
|
|
||||||
|
|
||||||
## 2026-03-11
|
|
||||||
- **Reference programs to study: Berkeley, Oakland, Toronto.** Selected based on size, longevity, and accessibility of operational data.
|
|
||||||
|
|
||||||
## 2026-03-25
|
|
||||||
- **Initial scope: hand and power tools only.** Rejected including specialty categories (sewing, electronics test gear, automotive) for MVP. Reason: staff expertise and storage. Revisit year 2.
|
|
||||||
- **Free model.** Confirmed — paid model rejected as inconsistent with library mission. Donation jar approved as soft revenue.
|
|
||||||
|
|
||||||
## 2026-04-01
|
|
||||||
- **Volunteer-run model.** Selected to keep ongoing operating costs low. Acknowledged risk: Berkeley correspondence flagged staff-hours as the biggest sustainability concern in similar programs. Plan to revisit at year-one review.
|
|
||||||
|
|
||||||
## 2026-04-08
|
|
||||||
- **Funding architecture: ARPA grant + Friends matching + in-kind donations.** Considered municipal budget request; rejected as too slow (next budget cycle is 18 months out). Grant is faster but requires fall 2027 launch deadline.
|
|
||||||
|
|
||||||
## 2026-04-15
|
|
||||||
- **Launch timing: Q3 2027.** Driven by ARPA grant deadline, not by service-readiness analysis. Acknowledged this is grant-driven, not user-driven, timing.
|
|
||||||
- **Year-one target: 300 unique borrowers.** Set by analogy to comparable programs scaled to Mossridge population. No local validation underlying this number.
|
|
||||||
|
|
||||||
## 2026-04-22
|
|
||||||
- **Hardware store satellite deferred to year 2.** Operational complexity exceeds our launch capacity.
|
|
||||||
- **Liability: pending formal opinion from town legal.** Borrower waiver in draft.
|
|
||||||
|
|
||||||
## 2026-04-30
|
|
||||||
- **Brief finalized for board meeting.** Status moved to final.
|
|
||||||
- **Open items acknowledged for board discussion:** demand validation method, volunteer sustainability, written legal opinion on off-premises tool use coverage.
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
# Pantry Bridge — Customer Research Transcripts
|
|
||||||
|
|
||||||
**Project:** Pantry Bridge meal-kit concept exploration
|
|
||||||
**Research firm:** In-house
|
|
||||||
**Round:** Discovery interviews, March 2026
|
|
||||||
**Format:** 45-minute semi-structured interviews, video; excerpts below are lightly edited for length and clarity
|
|
||||||
|
|
||||||
The four interviews below cover four distinct potential customer segments. We are sharing all four for context, though the team's current product hypothesis targets one specific segment.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Interview 1 — Susan, 38, working parent
|
|
||||||
|
|
||||||
**Household:** Two kids (ages 6 and 9), spouse works full-time, both parents work demanding office jobs. Suburban Chicago.
|
|
||||||
|
|
||||||
**Susan:** "Honestly, the question is just — can I get dinner on the table by 6:30 without it being chicken nuggets again? My kids don't eat anything green unless we play games about it. My husband and I both have late meetings sometimes. We've tried HelloFresh, we've tried Blue Apron, we tried Home Chef. They all kind of work, and they all kind of don't.
|
|
||||||
|
|
||||||
The thing that breaks them for us is the prep time. The boxes say 30 minutes but you need to add 10-15 to actually get it done. By Wednesday night I don't have 45 minutes. So we end up using the boxes on weekends and ordering takeout three nights a week, which is the opposite of what the boxes are supposed to do.
|
|
||||||
|
|
||||||
If you really wanted to crack it for families like ours: pre-chopped vegetables, sauces that are actually finished and not 'whisk these eight things together.' I'll pay more for less prep. And the recipe books need to read like the kid is going to eat it — not like 'spicy harissa-rubbed cauliflower steaks.'
|
|
||||||
|
|
||||||
Portion sizing — most kits send way too much for our family. We're a family of four but the kids each eat about 60% of a meal. We end up with leftovers that go bad. Better sizing would help."
|
|
||||||
|
|
||||||
**Interviewer:** What about price?
|
|
||||||
|
|
||||||
**Susan:** "We spend $250-350 a week on groceries currently and probably another $200 on takeout. So a meal kit that replaces three nights of takeout could be $200 a month and we'd still come out ahead. Most kits are priced fine; it's the time that breaks them."
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Interview 2 — Marcus, 21, college student
|
|
||||||
|
|
||||||
**Household:** Junior at state university, off-campus apartment shared with two roommates, kitchen has a microwave, a stovetop, and a half-broken oven. Limited budget.
|
|
||||||
|
|
||||||
**Marcus:** "I'm probably the wrong person for this conversation, no offense. I'm not really a meal-kit person. My food situation is, like, dining hall meal plan when I can use it, and the rest is whatever's cheap and fast. Trader Joe's frozen stuff. Eggs. Pasta. Costco runs with my roommates once a month.
|
|
||||||
|
|
||||||
I tried a meal kit when my mom signed me up as a 'starting college' gift. It was nice, but it was $80 a week for two people, which is way out of budget. And honestly, the thing they don't get is that I don't have time at 7 PM to cook. I have time at 11 PM. I want to grab something on my way back from the library and not think.
|
|
||||||
|
|
||||||
If you're trying to do meal kits for college students — and I don't really think you should — but if you were, the price has to be like $5 a meal. And it has to be food that survives in a fridge for two weeks because we don't shop on a weekly schedule. We shop when we run out.
|
|
||||||
|
|
||||||
Snacks matter more to us than meals, actually. Like, the moment when I'm desperate is 10 PM in the library, not 7 PM. Solve that and I might pay attention."
|
|
||||||
|
|
||||||
**Interviewer:** Do you have any dietary restrictions?
|
|
||||||
|
|
||||||
**Marcus:** "I'm vegetarian, sort of. I eat fish. So pescatarian I guess. But mostly because meat is expensive."
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Interview 3 — Eleanor, 71, retired, lives alone
|
|
||||||
|
|
||||||
**Household:** Widow, lives alone in the same single-family home she's been in for 36 years. Suburban Cleveland. Two adult children live out of state. Drives during the day but no longer at night.
|
|
||||||
|
|
||||||
**Eleanor:** "I'll tell you what I miss. I miss cooking for someone. My husband Walter passed five years ago this June, and the hardest thing — well, not the hardest, but one of them — is that I don't really cook anymore. I cook eggs. I cook a piece of fish. I open a can of soup more often than I'd like to admit. I used to make Sunday dinners that would feed eight people. Now I eat standing up at the counter half the time.
|
|
||||||
|
|
||||||
The grocery store is genuinely difficult. I drive there, I park in the back of the lot because I can usually find a spot, and then it's a long walk in. I get tired by the time I'm in the dairy aisle. Carrying the bags from the car to the kitchen — that's a project. My daughter wants me to use grocery delivery and I've tried, but the apps are all designed for someone twenty years younger than me. Tiny buttons, asking me to click through six screens to add a single tomato. I get frustrated and give up.
|
|
||||||
|
|
||||||
What I would actually want — and I've thought about this — is meals for one person. Real portions. Not a frozen TV dinner. Not 'serves four, freeze the rest.' I have a freezer full of leftovers I'll never eat. Just one good meal that I can heat up or finish cooking, that tastes like food I would have made.
|
|
||||||
|
|
||||||
I'm watching my sodium because of my blood pressure. Watching sugar too — borderline diabetic, my doctor calls it. So I read labels carefully. The frozen meals you can buy in stores are loaded with both. I'd pay more for less of both, if I trusted that the labels were accurate.
|
|
||||||
|
|
||||||
The other thing — and please put this in your notes — is that I'm careful about who I let into my house and what I sign up for. There are scams. My friend Marian got taken for $4,000 last year. So if some company asks for my information, I want to know who they are. I want a real customer service number with a real person. I want it to feel like a real business, not a flashy app.
|
|
||||||
|
|
||||||
I don't want it to feel like 'old-people food.' That's an important thing. The Meals on Wheels program in our township is wonderful but it's clearly designed for people who are sicker than I am. I'm not sick. I just live alone and grocery shopping is a lot."
|
|
||||||
|
|
||||||
**Interviewer:** What would the ideal experience look like?
|
|
||||||
|
|
||||||
**Eleanor:** "Someone delivers good food, in real portions, made with the kind of ingredients I would have used. I can heat it up or finish it. It doesn't taste like a hospital. The packaging is something I can actually open without a knife. I get a phone call once in a while from a person, not a robot. The price is reasonable — I'm on a fixed income but I can spend on things that matter. Eating well matters."
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Interview 4 — Dimitri, 44, Director of Food Services, mid-size hospital
|
|
||||||
|
|
||||||
**Organization:** 340-bed hospital, food service operates patient meals, staff cafeteria, and a small retail café. Reports to the COO.
|
|
||||||
|
|
||||||
**Dimitri:** "I'm probably also not who you should be talking to, but happy to share. We don't buy meal kits. We buy ingredients in institutional volumes from Sysco and US Foods primarily, with some specialty buys for dietary restrictions. We feed about 1,800 people a day across patients, staff, and visitors.
|
|
||||||
|
|
||||||
What I deal with that you might find interesting is the patient diet matrix. We have to produce meals that meet specific medical requirements — renal diets, cardiac diets, diabetic diets, dysphagia textures, allergen-free, religious restrictions. Each patient gets a tray that meets their specific orders. It's complex.
|
|
||||||
|
|
||||||
If a meal kit company wanted to play in our world, they'd be selling to me at the institutional level — bulk pricing, multi-year contracts, ability to deliver consistent specs across thousands of meals. That's not really a 'meal kit' anymore; that's wholesale food service.
|
|
||||||
|
|
||||||
Now, where I might be a buyer in a different sense: my staff cafeteria. We're trying to compete with grab-and-go culture. If you produced ready-to-heat meals targeting our staff demographic — nurses, doctors, techs, who are working 12-hour shifts and want real food, not a sandwich — I might pay attention. But the price point would have to make sense for institutional buying, and you'd need to integrate with our existing food safety protocols.
|
|
||||||
|
|
||||||
For consumer meal kits, I'm probably not your customer. We did try one when my wife and I were both working through COVID, and we let the subscription lapse after about three months. Fine product, just didn't fit our patterns."
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Note from the research lead
|
|
||||||
|
|
||||||
These four interviews were selected to represent the range of segments we've considered. The team's working hypothesis after this round is that the older-adult-living-alone segment is the strongest fit for the Pantry Bridge concept — distinctive needs, acknowledged friction with current options, willingness to pay for quality, and a meaningful unmet need around portion sizing and trust. Working parent segment is well-served by existing competitors. College student segment is too price-sensitive. Institutional segment is a different business entirely.
|
|
||||||
|
|
||||||
The brief should target the older-adult segment based on the Eleanor interview specifically.
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
# Q2 Brainstorm — Hatchet & Loop Studio
|
|
||||||
|
|
||||||
**Date:** 2026-04-15
|
|
||||||
**Present:** Mira, Devon, Sofia, Theo
|
|
||||||
|
|
||||||
Annual Q2 ideation. We're hunting for our next side-project-that-could-become-a-product. Format: 10 minutes wild ideas, 3 minutes per idea on quick takes, then we vote on one to dig into.
|
|
||||||
|
|
||||||
## Round 1: Everything goes
|
|
||||||
|
|
||||||
(10 minutes, no filtering. We just throw stuff out.)
|
|
||||||
|
|
||||||
- A weather app that tracks your mood alongside the forecast (Devon)
|
|
||||||
- Meditation chime that learns your sleep cycle and chimes only at the right wake-window (Theo)
|
|
||||||
- A podcasting tool for non-podcasters — like, you record voice notes and it auto-edits and posts (Sofia)
|
|
||||||
- Craft beer subscription with detailed brewer notes you can read while drinking (Mira)
|
|
||||||
- AI sommelier app that tells you what wine to buy at Trader Joe's based on a photo (Theo)
|
|
||||||
- Office-plant-care subscription with auto-replacement when one dies (Devon)
|
|
||||||
- Neighborhood ride coordinator — like a private Uber pool for one neighborhood (Mira)
|
|
||||||
- Neighborhood compost coordinator — connect people with food scraps to people with active compost piles (Sofia)
|
|
||||||
- Cookbook app where you click "I'll cook this Tuesday" and it auto-generates the shopping list and sends it to your delivery service (Devon)
|
|
||||||
- AR home staging — point your phone at a room and it shows you what it would look like with different furniture (Theo)
|
|
||||||
|
|
||||||
## Round 2: Quick takes
|
|
||||||
|
|
||||||
### Weather + mood
|
|
||||||
|
|
||||||
Devon: "I'd use it." Sofia thinks the data correlation isn't strong enough to be useful — interesting concept but the science doesn't support a product. Park.
|
|
||||||
|
|
||||||
### Sleep-cycle meditation chime
|
|
||||||
|
|
||||||
Theo's pitch — exists already (Sleep Cycle, etc.). Differentiation would be the chime, which is hardware. Out of scope for a software-first studio.
|
|
||||||
|
|
||||||
### Podcasting for non-podcasters
|
|
||||||
|
|
||||||
Sofia: "There are like fifty of these." She's right. Skip.
|
|
||||||
|
|
||||||
### Craft beer subscription
|
|
||||||
|
|
||||||
Mira admits this is mostly her wanting it for herself. We're not in the logistics business. Skip.
|
|
||||||
|
|
||||||
### AI sommelier
|
|
||||||
|
|
||||||
Theo: "The model would have to be incredibly good at label recognition." Sofia: "And there's already Vivino." Skip.
|
|
||||||
|
|
||||||
### Office-plant-care subscription
|
|
||||||
|
|
||||||
Devon: "I worked at a place that had this. They were always sad plants." Operational nightmare, low margin. Skip.
|
|
||||||
|
|
||||||
### Neighborhood ride coordinator
|
|
||||||
|
|
||||||
Mira: "Saturated. Lyft and Uber both have pool features. Uber Neighborhood was a thing and they killed it." Skip.
|
|
||||||
|
|
||||||
### Neighborhood compost coordinator
|
|
||||||
|
|
||||||
Sofia: "Hear me out. Cities are mandating organic waste separation but most apartments don't have a composting option. People in single-family homes often have active compost piles and would love more material. There's a missing match-making layer." General agreement this is more interesting than the others. Theo: "How do we make money?" Sofia: "Eventually a small fee on the compost-pile-host side, but for MVP just free and prove the demand." Group lights up. We agree to dig into this in Round 3.
|
|
||||||
|
|
||||||
### Cookbook → shopping list
|
|
||||||
|
|
||||||
Devon's pitch. Already exists (Mealime, Plan to Eat). Skip.
|
|
||||||
|
|
||||||
### AR home staging
|
|
||||||
|
|
||||||
Theo: "IKEA already has this." Skip.
|
|
||||||
|
|
||||||
## Round 3: Compost coordinator deep dive
|
|
||||||
|
|
||||||
We spent 45 minutes on this. Notes:
|
|
||||||
|
|
||||||
**Who is the user?**
|
|
||||||
Two-sided market. Side A: apartment dwellers and renters who generate food scraps and want them composted (motivated by environmental values, sometimes by city mandates). Side B: people with active backyard compost piles who want more "browns and greens" — single-family homeowners, urban farmers, school gardens, community gardens.
|
|
||||||
|
|
||||||
Sofia thinks Side A is the harder side to acquire (weak intent — recycling-adjacent behavior). Side B is easier but smaller. The product has to be designed around Side A's friction points.
|
|
||||||
|
|
||||||
**Geographic scope.**
|
|
||||||
Hyperlocal — neighborhood-level, not city-wide. The whole point is short-distance handoff: Side A doesn't want to drive their food scraps across town. We're talking 5-block radius matches.
|
|
||||||
|
|
||||||
**Business model (later).**
|
|
||||||
Free at launch. Eventually: subscription for Side B (compost-pile hosts) — they pay to access more matches. Side A always free. Possibly partner with cities that have green-waste mandates (B2G channel).
|
|
||||||
|
|
||||||
**Technical approach.**
|
|
||||||
Web app first, mobile second. Map-based discovery. Identity verification light-touch (apartment dwellers are skittish about strangers; need trust signals). Match-and-message pattern, not real-time logistics.
|
|
||||||
|
|
||||||
**Competition.**
|
|
||||||
ShareWaste exists but is global and not focused on hyperlocal density. Some city-specific apps (NYC's GrowNYC). No one has cracked the neighborhood-density model.
|
|
||||||
|
|
||||||
**MVP scope.**
|
|
||||||
One pilot neighborhood. Sofia knows people in a Portland neighborhood (Sunnyside / Hawthorne area) where compost culture is strong. Start there.
|
|
||||||
|
|
||||||
**Open questions.**
|
|
||||||
- How do we acquire Side A (apartment dwellers)? They have low intent and lots of competing options (just throwing scraps in trash, paying a service, signing up for city pickup if available).
|
|
||||||
- What does the trust layer look like? Reviews? Vouching? Real-name only?
|
|
||||||
- Does Side B saturation become a problem fast (one compost pile can only take so much)? How do we route demand?
|
|
||||||
|
|
||||||
## Action items
|
|
||||||
|
|
||||||
- Sofia: write up the compost coordinator concept as a brief by next Wednesday. Take it to Mira and Devon for first read.
|
|
||||||
- Devon: research ShareWaste's user numbers and any teardowns of why they haven't dominated.
|
|
||||||
- Theo: sketch the trust-layer UX concepts.
|
|
||||||
- Mira: talk to Sofia's Portland contacts about doing user interviews.
|
|
||||||
|
|
||||||
Next meeting: 2026-04-29 — review brief draft, decide on go/no-go.
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
[
|
|
||||||
{ "query": "Help me write a product brief for my new app idea", "should_trigger": true },
|
|
||||||
{ "query": "I need to draft a brief for a feature we're scoping", "should_trigger": true },
|
|
||||||
{ "query": "Update this product brief — we changed the target audience", "should_trigger": true },
|
|
||||||
{ "query": "Review my brief and tell me if it's investor-ready", "should_trigger": true },
|
|
||||||
{ "query": "Validate this brief before our board meeting Monday", "should_trigger": true },
|
|
||||||
{ "query": "Pressure-test my product brief for weak assumptions", "should_trigger": true },
|
|
||||||
{ "query": "Help me put together a one-page summary of my product idea for stakeholders", "should_trigger": true },
|
|
||||||
|
|
||||||
{ "query": "Help me brainstorm ideas for a new feature", "should_trigger": false },
|
|
||||||
{ "query": "Write me a PRD for our checkout flow redesign", "should_trigger": false },
|
|
||||||
{ "query": "Run a working backwards exercise for my product idea", "should_trigger": false },
|
|
||||||
{ "query": "Document this existing codebase for AI agents", "should_trigger": false },
|
|
||||||
{ "query": "Help me write user stories for the next sprint", "should_trigger": false },
|
|
||||||
{ "query": "Generate a system architecture for my app", "should_trigger": false },
|
|
||||||
{ "query": "Write code to parse JSON in Python", "should_trigger": false },
|
|
||||||
{ "query": "Create a marketing landing page for my product", "should_trigger": false }
|
|
||||||
]
|
|
||||||
|
|
@ -15,7 +15,7 @@ At the opening greeting, let the user know they can invoke `bmad-party-mode` for
|
||||||
|
|
||||||
## On Activation
|
## On Activation
|
||||||
|
|
||||||
1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
||||||
2. Execute each entry in `{workflow.activation_steps_prepend}` in order.
|
2. Execute each entry in `{workflow.activation_steps_prepend}` in order.
|
||||||
3. Treat every entry in `{workflow.persistent_facts}` as foundational context for the rest of the run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
|
3. Treat every entry in `{workflow.persistent_facts}` as foundational context for the rest of the run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
|
||||||
4. `{workflow.external_sources}` is an org-configured registry of internal tools (knowledge bases, MCP tools); consult them alongside generic web research on the same triggers in `## Discovery`, org tools preferred when their directive matches. If a named tool is unavailable at runtime, fall back to standard behavior and note the gap when relevant.
|
4. `{workflow.external_sources}` is an org-configured registry of internal tools (knowledge bases, MCP tools); consult them alongside generic web research on the same triggers in `## Discovery`, org tools preferred when their directive matches. If a named tool is unavailable at runtime, fall back to standard behavior and note the gap when relevant.
|
||||||
|
|
@ -28,11 +28,11 @@ Activation is complete. If `activation_steps_prepend` or `activation_steps_appen
|
||||||
|
|
||||||
## Intent Operating Modes
|
## Intent Operating Modes
|
||||||
|
|
||||||
**Create.** A brief the user is proud of, that meets their needs, drawn out through real conversation — do not assume: instead converse and understand, and then help craft the best product brief for their needs. Begin in `## Discovery` before drafting; the brief comes after the picture is on the table. Shape follows the product and need. Treat `{workflow.brief_template}` as a starting structure, not a contract: drop sections that do not earn their place, add sections the product needs, reorder freely - create sections for specialized domains or concerns also as needed. The brief serves the product's story, not the template's shape. Bind `{doc_workspace}` to a fresh folder at `{workflow.brief_output_path}/{workflow.run_folder_pattern}/` and write `brief.md` there with YAML frontmatter (title, status, created, updated). For Update and Validate, `{doc_workspace}` is the existing folder of the brief being targeted.
|
**Create.** A brief the user is proud of, that meets their needs, drawn out through real conversation — do not assume: instead converse and understand, and then help craft the best product brief for their needs. Begin in `## Discovery` before drafting; the brief comes after the picture is on the table. Shape follows the product and need. Treat `{workflow.brief_template}` as a starting structure, not a contract: drop sections that do not earn their place, add sections the product needs, reorder freely - create sections for specialized domains or concerns also as needed. The brief serves the product's story, not the template's shape. Bind `{doc_workspace}` to a fresh folder at `{workflow.brief_output_path}/{workflow.run_folder_pattern}/`, write `brief.md` there with YAML frontmatter (title, status, created, updated), and seed the memlog: `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace} --field topic="<product>"`. For Update and Validate, `{doc_workspace}` is the existing folder of the brief being targeted.
|
||||||
|
|
||||||
**Update.** Reconcile an existing brief with a change signal. Before proposing changes, read the brief, addendum, `.decision-log.md`, and original inputs — and run the `## Discovery` posture against the change signal (a patch applied without context becomes drift). Surface conflicts with prior decisions before changing. Headless override: log the reversal to `.decision-log.md`, then apply; halt `blocked` if intent is ambiguous. If the change is fundamental, offer Create instead of patching.
|
**Update.** Reconcile an existing brief with a change signal. Before proposing changes, read the brief, addendum, `.memlog.md`, and original inputs — and run the `## Discovery` posture against the change signal (a patch applied without context becomes drift). If `.memlog.md` is missing (a legacy or pre-standard brief), init it with `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace}` first — this update is its first entry. Surface conflicts with prior decisions before changing. Headless override: log the reversal via `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type override --text "<reversal + rationale>"`, then apply; halt `blocked` if intent is ambiguous. If the change is fundamental, offer Create instead of patching.
|
||||||
|
|
||||||
**Validate.** Honest critique against the brief's own purpose. Read the brief, the addendum if present, `.decision-log.md`, and any original inputs first — a validation that ignores prior decisions, rejected ideas, or context the user supplied is shallow. Cite specific lines. Caveat what cannot be evaluated. Return inline — no separate file unless asked. Always offer to roll findings into an Update, even in headless mode — include `"offer_to_update": true` in the JSON status block.
|
**Validate.** Honest critique against the brief's own purpose. Read the brief, the addendum if present, `.memlog.md`, and any original inputs first — a validation that ignores prior decisions, rejected ideas, or context the user supplied is shallow. Cite specific lines. Caveat what cannot be evaluated. Return inline — no separate file unless asked. Always offer to roll findings into an Update, even in headless mode — include `"offer_to_update": true` in the JSON status block.
|
||||||
|
|
||||||
## Headless Mode
|
## Headless Mode
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ When invoked headless, do not ask. Complete the intent using what is provided, w
|
||||||
"intent": "create",
|
"intent": "create",
|
||||||
"brief": "{doc_workspace}/brief.md",
|
"brief": "{doc_workspace}/brief.md",
|
||||||
"addendum": "{doc_workspace}/addendum.md",
|
"addendum": "{doc_workspace}/addendum.md",
|
||||||
"decision_log": "{doc_workspace}/.decision-log.md",
|
"memlog": "{doc_workspace}/.memlog.md",
|
||||||
"open_questions": [],
|
"open_questions": [],
|
||||||
"external_handoffs": [
|
"external_handoffs": [
|
||||||
{"directive": "Confluence upload", "tool": "corp:confluence_upload", "url": "https://confluence.corp/PROD/123", "status": "ok"}
|
{"directive": "Confluence upload", "tool": "corp:confluence_upload", "url": "https://confluence.corp/PROD/123", "status": "ok"}
|
||||||
|
|
@ -76,15 +76,15 @@ The workspace persists; stop and resume freely. The opener's philosophy (not in
|
||||||
## Constraints
|
## Constraints
|
||||||
|
|
||||||
- **Right-size to purpose.** A passion project does not need investor-grade rigor. A VC pitch input does. Read the room.
|
- **Right-size to purpose.** A passion project does not need investor-grade rigor. A VC pitch input does. Read the room.
|
||||||
- **Persistence is real-time.** Once Create intent is confirmed, the workspace (run folder, `brief.md` skeleton with `status: draft`, `.decision-log.md`) exists on disk and the user knows the path.
|
- **Persistence is real-time.** Once Create intent is confirmed, the workspace (run folder, `brief.md` skeleton with `status: draft`, `.memlog.md` seeded via `memlog.py init`) exists on disk and the user knows the path.
|
||||||
- **File roles.** `.decision-log.md` is canonical memory and audit trail — every decision, change, and override (including headless overrides) is recorded there as the conversation unfolds. `addendum.md` preserves user-contributed depth that belongs in a downstream document (PRD, architecture, solution design) or earned a place but does not fit the brief (rejected-alternative rationale, options-considered matrices, parked-roadmap context, technical constraints, in-depth personas, sizing data). Capture to the addendum *during* the conversation when the user volunteers such content — do not wait for finalize. Audit and override information never goes in the addendum.
|
- **File roles.** `.memlog.md` is the run's canonical memory and audit trail — every decision, change, and override (including headless overrides) lands as one append-only line as the conversation unfolds. All writes go through the shared script, never by hand: `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type <decision|change|override|assumption|event> --text "<one-line gist, reason included>"` (atomic; read it back only to resume or audit). The brief is distilled toward it; whatever isn't logged is lost on resume. `addendum.md` preserves user-contributed depth that belongs in a downstream document (PRD, architecture, solution design) or earned a place but does not fit the brief (rejected-alternative rationale, options-considered matrices, parked-roadmap context, technical constraints, in-depth personas, sizing data). Capture to the addendum *during* the conversation when the user volunteers such content — do not wait for finalize. Audit and override information never goes in the addendum.
|
||||||
- **Continuity across sessions.** If a prior in-progress draft for this project exists, the user is offered to resume.
|
- **Continuity across sessions.** If a prior in-progress draft for this project exists, the user is offered to resume.
|
||||||
- **Extract, don't ingest.** Source artifacts (provided by the user or discovered during the run — transcripts, brainstorms, research reports, code, web results, prior briefs) enter the parent conversation as relevance-filtered extracts, not loaded wholesale. Subagents do the extraction against the user's stated focus; the parent context stays lean.
|
- **Extract, don't ingest.** Source artifacts (provided by the user or discovered during the run — transcripts, brainstorms, research reports, code, web results, prior briefs) enter the parent conversation as relevance-filtered extracts, not loaded wholesale. Subagents do the extraction against the user's stated focus; the parent context stays lean.
|
||||||
- **Length and coherence.** Aim for 1-2 pages — if it is longer, the detail belongs in the addendum. Structure in service of the product; downstream consumers (PRD workflow, etc.) read this, so coherent shape matters.
|
- **Length and coherence.** Aim for 1-2 pages — if it is longer, the detail belongs in the addendum. Structure in service of the product; downstream consumers (PRD workflow, etc.) read this, so coherent shape matters.
|
||||||
|
|
||||||
## Finalize
|
## Finalize
|
||||||
|
|
||||||
1. Decision log audit + addendum review: the user ends this step with an explicit, shared accounting of how the meaningful contents of `.decision-log.md` were handled — captured in the brief, captured in `addendum.md` (which may already hold detail captured during the conversation — see `## Constraints` for what belongs there), or set aside as process noise.
|
1. Memlog audit + addendum review: the user ends this step with an explicit, shared accounting of how the meaningful contents of `.memlog.md` were handled — captured in the brief, captured in `addendum.md` (which may already hold detail captured during the conversation — see `## Constraints` for what belongs there), or set aside as process noise.
|
||||||
2. Polish: apply each entry in `{workflow.doc_standards}` (a `skill:`, `file:`, or plain-text directive) to `brief.md` (and `addendum.md` if it exists). Run passes as parallel subagents - apply all doc standards to `brief.md` first, then `addendum.md` so we present a high-quality draft for the user to review and finalize.
|
2. Polish: apply each entry in `{workflow.doc_standards}` (a `skill:`, `file:`, or plain-text directive) to `brief.md` (and `addendum.md` if it exists). Run passes as parallel subagents - apply all doc standards to `brief.md` first, then `addendum.md` so we present a high-quality draft for the user to review and finalize.
|
||||||
3. External handoffs: execute each entry in `{workflow.external_handoffs}` to route artifacts beyond local files (Confluence, Notion, ticket systems, etc.) — each directive names the MCP tool and the fields it needs. Invoke the tool, capture any URLs or IDs returned, and surface them in the user message. If a named tool is unavailable, skip that handoff and flag it; local files always exist regardless.
|
3. External handoffs: execute each entry in `{workflow.external_handoffs}` to route artifacts beyond local files (Confluence, Notion, ticket systems, etc.) — each directive names the MCP tool and the fields it needs. Invoke the tool, capture any URLs or IDs returned, and surface them in the user message. If a named tool is unavailable, skip that handoff and flag it; local files always exist regardless.
|
||||||
4. Tell the user it is ready: local paths and external destinations (URLs returned from handoffs). Invoke `bmad-help` to suggest what next steps make sense in the bmad method ecosystem.
|
4. Tell the user it is ready: local paths and external destinations (URLs returned from handoffs). Invoke `bmad-help` to suggest what next steps make sense in the bmad method ecosystem.
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@ You are a master facilitator and coach helping the user create, edit, or validat
|
||||||
- Bare paths resolve from skill root; `{skill-root}` is this skill's install dir; `{project-root}` is the project working dir.
|
- Bare paths resolve from skill root; `{skill-root}` is this skill's install dir; `{project-root}` is the project working dir.
|
||||||
- `{workflow.<name>}` resolves to fields in `customize.toml`'s `[workflow]` table (overrides win per BMad merge rules).
|
- `{workflow.<name>}` resolves to fields in `customize.toml`'s `[workflow]` table (overrides win per BMad merge rules).
|
||||||
- `{doc_workspace}` is the bound run folder.
|
- `{doc_workspace}` is the bound run folder.
|
||||||
- **File roles.** `.decision-log.md` is canonical memory and audit trail — every decision, change, and override (including headless overrides) is recorded there as the conversation unfolds. `addendum.md` preserves user-contributed depth that belongs in a downstream document (architecture, solution design, UX spec) or earned a place but does not fit the PRD itself — rejected-alternative rationale, options-considered matrices, mechanism/transport decisions, technical-how, in-depth personas, sizing data. Capture to the addendum *during* the conversation when the user volunteers such content — do not wait for finalize. Audit and override information never goes in the addendum.
|
- **File roles.** `.memlog.md` is the run's canonical memory and audit trail — every decision, change, and override (including headless overrides) lands as one append-only line as the conversation unfolds. All writes go through the shared script, never by hand: `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type <decision|change|override|assumption|event> --text "<one-line gist, reason included>"` (atomic; read it back only to resume or audit). The PRD is distilled toward it; whatever isn't logged is lost on resume. `addendum.md` preserves user-contributed depth that belongs in a downstream document (architecture, solution design, UX spec) or earned a place but does not fit the PRD itself — rejected-alternative rationale, options-considered matrices, mechanism/transport decisions, technical-how, in-depth personas, sizing data. Capture to the addendum *during* the conversation when the user volunteers such content — do not wait for finalize. Audit and override information never goes in the addendum.
|
||||||
|
|
||||||
## On Activation
|
## On Activation
|
||||||
|
|
||||||
1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
||||||
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (entries prefixed `file:` are loaded). `{workflow.external_sources}` is an org-configured registry of internal tools (knowledge bases, MCP tools); consult them alongside generic web research on the same triggers, org tools preferred when their directive matches. Research itself fires during Discovery — see **Research subagents**.
|
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (entries prefixed `file:` are loaded). `{workflow.external_sources}` is an org-configured registry of internal tools (knowledge bases, MCP tools); consult them alongside generic web research on the same triggers, org tools preferred when their directive matches. Research itself fires during Discovery — see **Research subagents**.
|
||||||
3. Load `{project-root}/_bmad/bmm/config.yaml` (+ `config.user.yaml` if present). Resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`. Missing keys → neutral defaults; never block.
|
3. Load `{project-root}/_bmad/bmm/config.yaml` (+ `config.user.yaml` if present). Resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`. Missing keys → neutral defaults; never block.
|
||||||
4. If headless, follow `references/headless.md` for the whole run. Otherwise greet the user **by name** using `{user_name}` and **in their language** using `{communication_language}` — and stay in `{communication_language}` for every turn for the entire run, not just the greeting. In the greeting, let the user know that at any point they can invoke `bmad-party-mode` for multi-agent perspectives or `bmad-advanced-elicitation` for deeper exploration on a specific section. Then scan for misroute on the first message: if the signal points elsewhere (game → BMad GDS; express build → `bmad-quick-dev`; one-pager → `bmad-product-brief`; vet product idea → `bmad-prfaq`; agent skill or custom agent → `bmad-workflow-builder`), suggest they might want the other options before continuing.
|
4. If headless, follow `references/headless.md` for the whole run. Otherwise greet the user **by name** using `{user_name}` and **in their language** using `{communication_language}` — and stay in `{communication_language}` for every turn for the entire run, not just the greeting. In the greeting, let the user know that at any point they can invoke `bmad-party-mode` for multi-agent perspectives or `bmad-advanced-elicitation` for deeper exploration on a specific section. Then scan for misroute on the first message: if the signal points elsewhere (game → BMad GDS; express build → `bmad-quick-dev`; one-pager → `bmad-product-brief`; vet product idea → `bmad-prfaq`; agent skill or custom agent → `bmad-workflow-builder`), suggest they might want the other options before continuing.
|
||||||
|
|
@ -27,9 +27,9 @@ Activation is complete. If `activation_steps_prepend` or `activation_steps_appen
|
||||||
|
|
||||||
## Intent Modes
|
## Intent Modes
|
||||||
|
|
||||||
**Create.** Bind `{doc_workspace}` to `{workflow.prd_output_path}/{workflow.run_folder_pattern}/`. Write `prd.md` with YAML frontmatter (title, status, created, updated — initial `status: draft`), and create the `.decision-log.md` skeleton at the workspace root so subsequent decisions land in a known file. Tell the user the path. Run `## Discovery`, then `## Finalize`.
|
**Create.** Bind `{doc_workspace}` to `{workflow.prd_output_path}/{workflow.run_folder_pattern}/`. Write `prd.md` with YAML frontmatter (title, status, created, updated — initial `status: draft`), and seed the memlog with `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace} --field topic="<PRD/product name>"` so subsequent decisions land in a known file. Tell the user the path. Run `## Discovery`, then `## Finalize`.
|
||||||
|
|
||||||
**Update.** Reconcile the PRD with a change signal. Source-extract against PRD, addendum, `.decision-log.md`, and original inputs (extract, don't ingest). If `.decision-log.md` is missing, spawn a one-time bootstrap subagent to reverse-engineer a thin log from the PRD before continuing. Surface conflicts with prior decisions before applying. Then `## Finalize`.
|
**Update.** Reconcile the PRD with a change signal. Source-extract against PRD, addendum, `.memlog.md`, and original inputs (extract, don't ingest). If `.memlog.md` is missing, init it with `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace}`, then spawn a one-time bootstrap subagent to reverse-engineer a thin log from the PRD (one `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type decision --text "<recovered decision>"` per recovered decision) before continuing. Surface conflicts with prior decisions before applying. Then `## Finalize`.
|
||||||
|
|
||||||
**Validate** (or *analyze*). Critique without changing. Load `references/validate.md`.
|
**Validate** (or *analyze*). Critique without changing. Load `references/validate.md`.
|
||||||
|
|
||||||
|
|
@ -82,11 +82,11 @@ Under Validate intent, the parent additionally runs the synthesis pipeline in `r
|
||||||
|
|
||||||
Tell the user the sequence in one sentence, then walk it. Polish goes last so it does not redo work after reviewer fixes.
|
Tell the user the sequence in one sentence, then walk it. Polish goes last so it does not redo work after reviewer fixes.
|
||||||
|
|
||||||
1. **Decision log audit.** Walk `.decision-log.md` with the user; each entry captured in PRD, in addendum, or set aside.
|
1. **Memlog audit.** Walk `.memlog.md` with the user; each entry captured in PRD, in addendum, or set aside.
|
||||||
2. **Input reconciliation.** Subagent per user-supplied input against `prd.md` + `addendum.md`. Each writes its extract to `{doc_workspace}/reconcile-{slug}.md` and returns ONLY a compact summary (input name, gaps 2-5, file path). Surface gaps — especially qualitative ideas (tone, voice, feel) the FR structure silently drops. Must happen before polish.
|
2. **Input reconciliation.** Subagent per user-supplied input against `prd.md` + `addendum.md`. Each writes its extract to `{doc_workspace}/reconcile-{slug}.md` and returns ONLY a compact summary (input name, gaps 2-5, file path). Surface gaps — especially qualitative ideas (tone, voice, feel) the FR structure silently drops. Must happen before polish.
|
||||||
3. **Reviewer pass.** Run `## Reviewer Gate`. Resolve before polish.
|
3. **Reviewer pass.** Run `## Reviewer Gate`. Resolve before polish.
|
||||||
4. **Triage open items.** All Open Questions, `[ASSUMPTION]` tags, `[NOTE FOR PM]` callouts. Phase-blockers (would make the PRD unsafe for UX/architecture/epics) surfaced one at a time and resolved; non-blockers deferred with owner + revisit condition logged to `.decision-log.md`. If phase-blocker count is high, flag it.
|
4. **Triage open items.** All Open Questions, `[ASSUMPTION]` tags, `[NOTE FOR PM]` callouts. Phase-blockers (would make the PRD unsafe for UX/architecture/epics) surfaced one at a time and resolved; non-blockers deferred with owner + revisit condition logged via `memlog.py append`. If phase-blocker count is high, flag it.
|
||||||
5. **Polish.** Apply `{workflow.doc_standards}` to `prd.md` and `addendum.md` in declared order (structural passes before prose — prose should not polish soon-to-be-cut text). Parallelize across documents, sequential within.
|
5. **Polish.** Apply `{workflow.doc_standards}` to `prd.md` and `addendum.md` in declared order (structural passes before prose — prose should not polish soon-to-be-cut text). Parallelize across documents, sequential within.
|
||||||
6. **External handoffs.** Execute `{workflow.external_handoffs}`; surface returned URLs/IDs. Skip and flag unavailable tools.
|
6. **External handoffs.** Execute `{workflow.external_handoffs}`; surface returned URLs/IDs. Skip and flag unavailable tools.
|
||||||
7. **Close.** Set `prd.md` frontmatter `status: final` and `updated` to `{date}` so future invocations distinguish this PRD from in-progress drafts. Record finalization to `.decision-log.md`. Share artifact paths. Common next: `bmad-ux`, `bmad-architecture`, `bmad-create-epics-and-stories`; invoke `bmad-help` for authoritative routing.
|
7. **Close.** Set `prd.md` frontmatter `status: final` and `updated` to `{date}` so future invocations distinguish this PRD from in-progress drafts. Record finalization via `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type event --text "PRD finalized"`. Share artifact paths. Common next: `bmad-ux`, `bmad-architecture`, `bmad-create-epics-and-stories`; invoke `bmad-help` for authoritative routing.
|
||||||
8. Run `{workflow.on_complete}` if non-empty.
|
8. Run `{workflow.on_complete}` if non-empty.
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ Every headless run ends with one of these payloads. Omit keys for artifacts not
|
||||||
"intent": "create",
|
"intent": "create",
|
||||||
"prd": "{doc_workspace}/prd.md",
|
"prd": "{doc_workspace}/prd.md",
|
||||||
"addendum": "{doc_workspace}/addendum.md",
|
"addendum": "{doc_workspace}/addendum.md",
|
||||||
"decision_log": "{doc_workspace}/.decision-log.md",
|
"memlog": "{doc_workspace}/.memlog.md",
|
||||||
"open_questions": [],
|
"open_questions": [],
|
||||||
"assumptions": [],
|
"assumptions": [],
|
||||||
"external_handoffs": [
|
"external_handoffs": [
|
||||||
|
|
@ -34,7 +34,7 @@ Every headless run ends with one of these payloads. Omit keys for artifacts not
|
||||||
"status": "complete",
|
"status": "complete",
|
||||||
"intent": "update",
|
"intent": "update",
|
||||||
"prd": "{doc_workspace}/prd.md",
|
"prd": "{doc_workspace}/prd.md",
|
||||||
"decision_log": "{doc_workspace}/.decision-log.md",
|
"memlog": "{doc_workspace}/.memlog.md",
|
||||||
"changes_summary": "1-3 sentences describing what changed and why",
|
"changes_summary": "1-3 sentences describing what changed and why",
|
||||||
"conflicts_with_prior_decisions": [],
|
"conflicts_with_prior_decisions": [],
|
||||||
"open_questions": [],
|
"open_questions": [],
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ validation_checklist_template = "assets/prd-validation-checklist.md"
|
||||||
# collapse — no JS.
|
# collapse — no JS.
|
||||||
validation_report_template = "assets/validation-report-template.html"
|
validation_report_template = "assets/validation-report-template.html"
|
||||||
|
|
||||||
# Run folder location. The PRD, optional addendum, decision log, and optional
|
# Run folder location. The PRD, optional addendum, memlog, and optional
|
||||||
# validation report all land inside `{prd_output_path}/{run_folder_pattern}/`.
|
# validation report all land inside `{prd_output_path}/{run_folder_pattern}/`.
|
||||||
# Resume-check scans `{prd_output_path}` for prior unfinished runs.
|
# Resume-check scans `{prd_output_path}` for prior unfinished runs.
|
||||||
prd_output_path = "{planning_artifacts}/prds"
|
prd_output_path = "{planning_artifacts}/prds"
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,6 @@ End with the JSON response (full schemas with examples in `assets/headless-schem
|
||||||
|
|
||||||
## Mode-specific overrides
|
## Mode-specific overrides
|
||||||
|
|
||||||
**Update.** Apply the change, log to `.decision-log.md` with rationale, and surface any conflict-with-prior-decision in `conflicts_with_prior_decisions[]` in the JSON status. Halt `blocked` if intent is ambiguous.
|
**Update.** Apply the change, log it via `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type change --text "<change + rationale>"`, and surface any conflict-with-prior-decision in `conflicts_with_prior_decisions[]` in the JSON status. Halt `blocked` if intent is ambiguous.
|
||||||
|
|
||||||
**Validate.** Always write both `validation-report.html` and `validation-report.md` to `{doc_workspace}` regardless of finding count. Always include `"offer_to_update": true` in the JSON status. Skip the browser-open step in `references/validate.md` — write the artifacts and return.
|
**Validate.** Always write both `validation-report.html` and `validation-report.md` to `{doc_workspace}` regardless of finding count. Always include `"offer_to_update": true` in the JSON status. Skip the browser-open step in `references/validate.md` — write the artifacts and return.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ The Validate intent playbook. Standalone — this intent critiques an existing P
|
||||||
|
|
||||||
## Orient
|
## Orient
|
||||||
|
|
||||||
Source-extract against `.decision-log.md`, any original inputs, and the PRD/addendum themselves. Delegate to subagents per PRD Discipline → "Extract, don't ingest" (in SKILL.md); the parent assembles from extracts.
|
Source-extract against `.memlog.md`, any original inputs, and the PRD/addendum themselves. Delegate to subagents per PRD Discipline → "Extract, don't ingest" (in SKILL.md); the parent assembles from extracts.
|
||||||
|
|
||||||
## Run the Reviewer Gate
|
## Run the Reviewer Gate
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ UX may lead, follow, or stand alone. Inherit `sources:` by reference; the spines
|
||||||
|
|
||||||
## On Activation
|
## On Activation
|
||||||
|
|
||||||
1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
||||||
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (entries prefixed `file:` are loaded). `{workflow.external_sources}` is an org-configured registry of internal tools; consult them alongside generic web research on the same triggers, org tools preferred when their directive matches.
|
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (entries prefixed `file:` are loaded). `{workflow.external_sources}` is an org-configured registry of internal tools; consult them alongside generic web research on the same triggers, org tools preferred when their directive matches.
|
||||||
3. Load `{project-root}/_bmad/bmm/config.yaml` (+ `config.user.yaml` if present). Resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`. Missing keys → neutral defaults; never block.
|
3. Load `{project-root}/_bmad/bmm/config.yaml` (+ `config.user.yaml` if present). Resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`. Missing keys → neutral defaults; never block.
|
||||||
4. If headless, follow `references/headless.md` for the whole run. Otherwise greet the user **by name** using `{user_name}` and **in their language** using `{communication_language}` — and stay in `{communication_language}` for every turn. In the greeting, let the user know `bmad-party-mode` and `bmad-advanced-elicitation` are always available. Then scan for misroute on the first message: PRD → `bmad-prd`; architecture → `bmad-architecture`; game UX → BMad GDS; agent/skill → `bmad-workflow-builder`; brief → `bmad-product-brief`.
|
4. If headless, follow `references/headless.md` for the whole run. Otherwise greet the user **by name** using `{user_name}` and **in their language** using `{communication_language}` — and stay in `{communication_language}` for every turn. In the greeting, let the user know `bmad-party-mode` and `bmad-advanced-elicitation` are always available. Then scan for misroute on the first message: PRD → `bmad-prd`; architecture → `bmad-architecture`; game UX → BMad GDS; agent/skill → `bmad-workflow-builder`; brief → `bmad-product-brief`.
|
||||||
|
|
@ -42,15 +42,15 @@ Activation is complete. If `activation_steps_prepend` or `activation_steps_appen
|
||||||
|
|
||||||
## Modes
|
## Modes
|
||||||
|
|
||||||
**Create.** Bind `{doc_workspace}` to `{workflow.ux_output_path}/{workflow.run_folder_pattern}/`. Create `.working/`, `imports/`, `.decision-log.md`, `DESIGN.md` (frontmatter only), and `EXPERIENCE.md` (frontmatter only). Run Discovery → Finalize.
|
**Create.** Bind `{doc_workspace}` to `{workflow.ux_output_path}/{workflow.run_folder_pattern}/`. Create `.working/` and `imports/`; seed the memlog with `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace} --field topic="<product/UX>"`; create `DESIGN.md` (frontmatter only) and `EXPERIENCE.md` (frontmatter only). Run Discovery → Finalize.
|
||||||
|
|
||||||
**Update.** Read spines + log + sources. Create the log if missing — this update is entry one. Surface conflicts with prior decisions. Run Finalize.
|
**Update.** Read spines + memlog + sources. If `.memlog.md` is missing, init it with `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace}` — this update is entry one. Surface conflicts with prior decisions. Run Finalize.
|
||||||
|
|
||||||
**Validate.** See `references/validate.md`.
|
**Validate.** See `references/validate.md`.
|
||||||
|
|
||||||
## Discovery
|
## Discovery
|
||||||
|
|
||||||
**Capture; do not author.** The spines are distilled at Finalize. Decisions → `.decision-log.md` (canonical). Creative-tool artifacts → `.working/`. User-supplied visuals (Figma, sketches, brand decks, image folders) → `imports/`, one log line per item. Spines win on conflict.
|
**Capture; do not author.** The spines are distilled at Finalize toward the memlog. Decisions → `.memlog.md` (canonical), each appended via `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type <decision|change|override|assumption|event> --text "…"` — never hand-edited; a resume reloads it. Creative-tool artifacts → `.working/`. User-supplied visuals (Figma, sketches, brand decks, image folders) → `imports/`, one `memlog.py append` per item. Spines win on conflict.
|
||||||
|
|
||||||
**Source scan.** Glob `{planning_artifacts}/` for candidate input paths; surface paths only — never read content in the parent. User confirms which apply or adds others; subagent-extracts on confirm.
|
**Source scan.** Glob `{planning_artifacts}/` for candidate input paths; surface paths only — never read content in the parent. User confirms which apply or adds others; subagent-extracts on confirm.
|
||||||
|
|
||||||
|
|
@ -80,11 +80,11 @@ Used by Validate and Finalize. **Opt-in, lens-selectable** — reviewers are cos
|
||||||
|
|
||||||
Outcomes, in order:
|
Outcomes, in order:
|
||||||
|
|
||||||
- **Spines distilled.** Subagent reads `.decision-log.md`, `.working/`, `imports/`, sources; produces `DESIGN.md` against `## The DESIGN.md spine` + `{workflow.design_md_examples}` and `EXPERIENCE.md` against `## The EXPERIENCE.md spine` + `{workflow.experience_md_examples}`. Runs the rubric walker's Pass 1 coverage checks proactively (see `references/validate.md`). Surface gaps; never invent.
|
- **Spines distilled.** Subagent reads `.memlog.md`, `.working/`, `imports/`, sources; produces `DESIGN.md` against `## The DESIGN.md spine` + `{workflow.design_md_examples}` and `EXPERIENCE.md` against `## The EXPERIENCE.md spine` + `{workflow.experience_md_examples}`. Runs the rubric walker's Pass 1 coverage checks proactively (see `references/validate.md`). Surface gaps; never invent.
|
||||||
- **Inputs reconciled.** Subagent per user-supplied input → `reconcile-{slug}.md`. Surface dropped qualitative ideas.
|
- **Inputs reconciled.** Subagent per user-supplied input → `reconcile-{slug}.md`. Surface dropped qualitative ideas.
|
||||||
- **Reviewer Gate offered.** Ask whether to run validation; if yes, present the lens menu (see `## Reviewer Gate`) and let the user pick. If any lens ran, resolve findings before polish; otherwise proceed.
|
- **Reviewer Gate offered.** Ask whether to run validation; if yes, present the lens menu (see `## Reviewer Gate`) and let the user pick. If any lens ran, resolve findings before polish; otherwise proceed.
|
||||||
- **Open items triaged.** Open Questions, `[ASSUMPTION]`, `[NOTE FOR UX]`. Phase-blockers one at a time; non-blockers → log.
|
- **Open items triaged.** Open Questions, `[ASSUMPTION]`, `[NOTE FOR UX]`. Phase-blockers one at a time; non-blockers → `memlog.py append`.
|
||||||
- **Key-screen mocks rendered.** Key-screens tool → `.working/` for surfaces where layout drives behavior or anchors visual language.
|
- **Key-screen mocks rendered.** Key-screens tool → `.working/` for surfaces where layout drives behavior or anchors visual language.
|
||||||
- **Mock coverage confirmed.** Walk every IA surface; classify *mocked* vs *spine-only*. Ask: *"These will be built from spine tables alone — any need a visual reference?"* Render more if named; log spine-only choices.
|
- **Mock coverage confirmed.** Walk every IA surface; classify *mocked* vs *spine-only*. Ask: *"These will be built from spine tables alone — any need a visual reference?"* Render more if named; log spine-only choices.
|
||||||
- **Layout extracted, artifacts promoted.** Distill subagent re-reads each `.working/` and `imports/` artifact; lifts visual decisions into DESIGN.md and behavioral decisions into EXPERIENCE.md. Promote `.working/` keepers to `mockups/` (HTML) or `wireframes/` (Excalidraw); imports stay. Inline relative links at relevant spine sections; state spines-win-on-conflict once.
|
- **Layout extracted, artifacts promoted.** Distill subagent re-reads each `.working/` and `imports/` artifact; lifts visual decisions into DESIGN.md and behavioral decisions into EXPERIENCE.md. Promote `.working/` keepers to `mockups/` (HTML) or `wireframes/` (Excalidraw); imports stay. Inline relative links at relevant spine sections; state spines-win-on-conflict once.
|
||||||
- **Polished, handed off, closed.** Apply `{workflow.doc_standards}` in order. Execute `{workflow.external_handoffs}`; surface URLs. Set both files' `status: final`, `updated: {date}`. Log finalization. Share paths. Common next: `bmad-architecture`, `bmad-create-epics-and-stories`, `bmad-dev-story`. Run `{workflow.on_complete}`.
|
- **Polished, handed off, closed.** Apply `{workflow.doc_standards}` in order. Execute `{workflow.external_handoffs}`; surface URLs. Set both files' `status: final`, `updated: {date}`. Log finalization via `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type event --text "spines finalized"`. Share paths. Common next: `bmad-architecture`, `bmad-create-epics-and-stories`, `bmad-dev-story`. Run `{workflow.on_complete}`.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,6 @@ Subagent prompt. Produce 3-6 distinct visual directions for the product's hero s
|
||||||
|
|
||||||
Each direction is a *complete visual personality* applied to the same key screen — not a palette swap. Differ on density, type weight, motion implication, brand register. Each file: 2-3 sentence rationale, near-1:1 hero screen mockup in a phone or browser frame, ideally a secondary screen, at least one state variant visible (aging row, empty state, etc).
|
Each direction is a *complete visual personality* applied to the same key screen — not a palette swap. Differ on density, type weight, motion implication, brand register. Each file: 2-3 sentence rationale, near-1:1 hero screen mockup in a phone or browser frame, ideally a secondary screen, at least one state variant visible (aging row, empty state, etc).
|
||||||
|
|
||||||
Use real product content from the conversation. Voice/tone from `.decision-log.md` applied to every visible string — no lorem. Inline CSS, system fonts, no JS or network. Document hex values in `<style>` comments per direction.
|
Use real product content from the conversation. Voice/tone from `.memlog.md` applied to every visible string — no lorem. Inline CSS, system fonts, no JS or network. Document hex values in `<style>` comments per direction.
|
||||||
|
|
||||||
Return to the parent: file paths, one-line personality summary per direction, what hero screen was depicted. Do not dump HTML into parent context. If interactive, open each file in the browser.
|
Return to the parent: file paths, one-line personality summary per direction, what hero screen was depicted. Do not dump HTML into parent context. If interactive, open each file in the browser.
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ Every headless run ends with one of these payloads. Omit keys for artifacts not
|
||||||
"intent": "create",
|
"intent": "create",
|
||||||
"design": "{doc_workspace}/DESIGN.md",
|
"design": "{doc_workspace}/DESIGN.md",
|
||||||
"experience": "{doc_workspace}/EXPERIENCE.md",
|
"experience": "{doc_workspace}/EXPERIENCE.md",
|
||||||
"decision_log": "{doc_workspace}/.decision-log.md",
|
"memlog": "{doc_workspace}/.memlog.md",
|
||||||
"working_artifacts": ["{doc_workspace}/.working/color-themes-1.html"],
|
"working_artifacts": ["{doc_workspace}/.working/color-themes-1.html"],
|
||||||
"promoted_artifacts": {
|
"promoted_artifacts": {
|
||||||
"mockups": ["{doc_workspace}/mockups/direction-calm-sage.html"],
|
"mockups": ["{doc_workspace}/mockups/direction-calm-sage.html"],
|
||||||
|
|
@ -42,7 +42,7 @@ The `working_artifacts` and `promoted_artifacts` keys are optional and omitted e
|
||||||
"intent": "update",
|
"intent": "update",
|
||||||
"design": "{doc_workspace}/DESIGN.md",
|
"design": "{doc_workspace}/DESIGN.md",
|
||||||
"experience": "{doc_workspace}/EXPERIENCE.md",
|
"experience": "{doc_workspace}/EXPERIENCE.md",
|
||||||
"decision_log": "{doc_workspace}/.decision-log.md",
|
"memlog": "{doc_workspace}/.memlog.md",
|
||||||
"changes_summary": "1-3 sentences describing what changed and why",
|
"changes_summary": "1-3 sentences describing what changed and why",
|
||||||
"conflicts_with_prior_decisions": [],
|
"conflicts_with_prior_decisions": [],
|
||||||
"open_questions": [],
|
"open_questions": [],
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ Subagent prompt. Fired at Finalize (or during late Discovery once layout decisio
|
||||||
|
|
||||||
## Inputs
|
## Inputs
|
||||||
|
|
||||||
`.decision-log.md`, the current drafts `DESIGN.md` and `EXPERIENCE.md`, `.working/` (especially the chosen color-theme and direction mocks), source PRD. The user names which surfaces to render — typically 2-4: the canonical entry surface, the most complex flow's hero screen, any load-bearing overlay/modal, and (when present) the Week / list / dashboard view.
|
`.memlog.md`, the current drafts `DESIGN.md` and `EXPERIENCE.md`, `.working/` (especially the chosen color-theme and direction mocks), source PRD. The user names which surfaces to render — typically 2-4: the canonical entry surface, the most complex flow's hero screen, any load-bearing overlay/modal, and (when present) the Week / list / dashboard view.
|
||||||
|
|
||||||
## What to render
|
## What to render
|
||||||
|
|
||||||
One HTML file per screen, at `.working/key-{slug}.html`. Each file: realistic device frame (phone or browser), real product content from the conversation (no lorem), every visible string voice-checked against `.decision-log.md`, all decided tokens applied. Show one canonical state per screen; if a surface has a load-bearing alternate state (focus, error, crisis-card-present), render it as a second column or section in the same file.
|
One HTML file per screen, at `.working/key-{slug}.html`. Each file: realistic device frame (phone or browser), real product content from the conversation (no lorem), every visible string voice-checked against `.memlog.md`, all decided tokens applied. Show one canonical state per screen; if a surface has a load-bearing alternate state (focus, error, crisis-card-present), render it as a second column or section in the same file.
|
||||||
|
|
||||||
Inline CSS, system fonts, no JS, no network. The mock must render fully offline. Comment block at the top of the `<style>` notes which spine sections govern this screen so a future reader knows what to check.
|
Inline CSS, system fonts, no JS, no network. The mock must render fully offline. Comment block at the top of the `<style>` notes which spine sections govern this screen so a future reader knows what to check.
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ The parent, at Finalize "Promote working artifacts," uses this summary to insert
|
||||||
|
|
||||||
## Anti-patterns
|
## Anti-patterns
|
||||||
|
|
||||||
- Do not invent layout — every composition decision must trace to a `.working/` artifact or a confirmation in `.decision-log.md`. If a layout question is open, the mock is premature.
|
- Do not invent layout — every composition decision must trace to a `.working/` artifact or a confirmation in `.memlog.md`. If a layout question is open, the mock is premature.
|
||||||
- Do not show every screen of every flow — 2-4 load-bearing surfaces, not 14.
|
- Do not show every screen of every flow — 2-4 load-bearing surfaces, not 14.
|
||||||
- Do not stage marketing copy. Strings come from `.decision-log.md` and voice rules.
|
- Do not stage marketing copy. Strings come from `.memlog.md` and voice rules.
|
||||||
- Do not introduce a new pattern not in the spine's Component Patterns table. If you need one, log it and ask before rendering.
|
- Do not introduce a new pattern not in the spine's Component Patterns table. If you need one, log it and ask before rendering.
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ design_handoffs = [
|
||||||
# HTML skeleton filled in by the validation synthesis pass.
|
# HTML skeleton filled in by the validation synthesis pass.
|
||||||
validation_report_template = "assets/validation-report-template.html"
|
validation_report_template = "assets/validation-report-template.html"
|
||||||
|
|
||||||
# Run folder. DESIGN.md, EXPERIENCE.md, .decision-log.md, .working/
|
# Run folder. DESIGN.md, EXPERIENCE.md, .memlog.md, .working/
|
||||||
# (creative-tool artifacts), imports/ (user-supplied screens / brand decks /
|
# (creative-tool artifacts), imports/ (user-supplied screens / brand decks /
|
||||||
# Figma exports / sketches), optional mockups/ and wireframes/ (promoted
|
# Figma exports / sketches), optional mockups/ and wireframes/ (promoted
|
||||||
# artifacts), optional validation-report.* all land inside
|
# artifacts), optional validation-report.* all land inside
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,6 @@ Every renderer writes to `{doc_workspace}/.working/` with a descriptive filename
|
||||||
|
|
||||||
## Renderer contract
|
## Renderer contract
|
||||||
|
|
||||||
The parent passes the subagent: current `.decision-log.md`, relevant prior `.working/` captures, the user's stated intent for this pass, the output path. The subagent writes its artifact under `.working/` and returns ONLY a compact summary (file path, one line per variant, mode coverage). Parent never holds the full payload.
|
The parent passes the subagent: current `.memlog.md`, relevant prior `.working/` captures, the user's stated intent for this pass, the output path. The subagent writes its artifact under `.working/` and returns ONLY a compact summary (file path, one line per variant, mode coverage). Parent never holds the full payload.
|
||||||
|
|
||||||
For HTML, open in browser when interactive: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"`. Skip in headless.
|
For HTML, open in browser when interactive: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"`. Skip in headless.
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,6 @@ End with JSON matching `assets/headless-schemas.md`. `intent` reflects detected
|
||||||
|
|
||||||
## Mode-specific overrides
|
## Mode-specific overrides
|
||||||
|
|
||||||
**Update.** Apply the change. Log to `.decision-log.md` with rationale. Surface conflicts in `conflicts_with_prior_decisions[]`.
|
**Update.** Apply the change. Log it via `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type change --text "<change + rationale>"`. Surface conflicts in `conflicts_with_prior_decisions[]`.
|
||||||
|
|
||||||
**Validate.** Always write both `validation-report.html` and `validation-report.md` regardless of finding count. Always include `"offer_to_update": true`. Skip the browser-open step.
|
**Validate.** Always write both `validation-report.html` and `validation-report.md` regardless of finding count. Always include `"offer_to_update": true`. Skip the browser-open step.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Critique an existing spine pair (`DESIGN.md` + `EXPERIENCE.md`) or any format of
|
||||||
|
|
||||||
## Orient
|
## Orient
|
||||||
|
|
||||||
Subagent-extract from `.decision-log.md`, sources in frontmatter, `imports/`, `mockups/`, `wireframes/`, `DESIGN.md`, `EXPERIENCE.md`. Parent assembles from extracts.
|
Subagent-extract from `.memlog.md`, sources in frontmatter, `imports/`, `mockups/`, `wireframes/`, `DESIGN.md`, `EXPERIENCE.md`. Parent assembles from extracts.
|
||||||
|
|
||||||
## Reviewer Gate
|
## Reviewer Gate
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ Rubric walker prompt:
|
||||||
>
|
>
|
||||||
> 7. **Inheritance discipline.** `sources` frontmatter resolves. UJ / requirement names verbatim from sources. Glossary identical across spines and sources. Component names identical across all sections in both files. EXPERIENCE.md token references resolve to DESIGN.md tokens by name.
|
> 7. **Inheritance discipline.** `sources` frontmatter resolves. UJ / requirement names verbatim from sources. Glossary identical across spines and sources. Component names identical across all sections in both files. EXPERIENCE.md token references resolve to DESIGN.md tokens by name.
|
||||||
>
|
>
|
||||||
> 8. **Shape fit.** DESIGN.md sections in canonical order (Brand & Style → Colors → Typography → Layout & Spacing → Elevation & Depth → Shapes → Components → Do's and Don'ts; omittable but order-locked when present). EXPERIENCE.md required defaults present (Foundation, IA, Voice and Tone, Component Patterns, State Patterns, Interaction Primitives, Accessibility Floor, Key Flows). Dropped defaults defensible. Required-when-applicable present where triggered (Inspiration when sources / log show reference products or rejects; Responsive when multi-surface or breakpoints). Invented sections earn their place.
|
> 8. **Shape fit.** DESIGN.md sections in canonical order (Brand & Style → Colors → Typography → Layout & Spacing → Elevation & Depth → Shapes → Components → Do's and Don'ts; omittable but order-locked when present). EXPERIENCE.md required defaults present (Foundation, IA, Voice and Tone, Component Patterns, State Patterns, Interaction Primitives, Accessibility Floor, Key Flows). Dropped defaults defensible. Required-when-applicable present where triggered (Inspiration when sources / memlog show reference products or rejects; Responsive when multi-surface or breakpoints). Invented sections earn their place.
|
||||||
>
|
>
|
||||||
> Severity = downstream impact, not fix difficulty.
|
> Severity = downstream impact, not fix difficulty.
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,12 @@ The input itself tells you what kind of job this is — read it rather than quiz
|
||||||
|
|
||||||
## How a run works
|
## How a run works
|
||||||
|
|
||||||
The **memlog** (`.memlog.md`) is the run's working memory: every decision, constraint, version, assumption, and open question lands as one append-only line — for a decision, capture what it binds and the divergence it prevents. It is the shared canonical memlog (the same `{project-root}/_bmad/scripts/memlog.py` bmad-spec writes through), so it carries no lifecycle status — terminal moments are logged as `event` entries, not a frontmatter flag. The spine is **distilled from the memlog at the end**, not written as you go. Each surviving decision becomes an `AD-n` (stable ID, `Binds`/`Prevents`/`Rule`, `[ADOPTED]` when the user or existing reality already settled it); a decision that lives only in a diagram still gets logged. Resume a prior run by reloading its memlog.
|
The **memlog** (`.memlog.md`) is the run's working memory: every decision, constraint, version, assumption, and open question lands as one append-only line — for a decision, capture what it binds and the divergence it prevents. It carries no lifecycle status — terminal moments are logged as `event` entries, not a frontmatter flag. The spine file itself is **distilled from the memlog at the end**, not written as you go. Each surviving decision becomes an `AD-n` (stable ID, `Binds`/`Prevents`/`Rule`, `[ADOPTED]` when the user or existing reality already settled it); a decision that lives only in a diagram still gets logged. Resume a prior run by reloading its memlog.
|
||||||
|
|
||||||
Writes go through the shared script (don't read the file back except on resume):
|
Writes go through the shared script (don't read the file back except on resume):
|
||||||
|
|
||||||
- `python3 {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace} --field scope="…" --field purpose="…" --field altitude="…"`
|
- `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace} --field scope="…" --field purpose="…" --field altitude="…"`
|
||||||
- `python3 {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type <decision|constraint|version|assumption|question|direction|event> --text "…"`
|
- `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type <decision|constraint|version|assumption|question|direction|event> --text "…"`
|
||||||
|
|
||||||
## Resolution rules
|
## Resolution rules
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ Writes go through the shared script (don't read the file back except on resume):
|
||||||
|
|
||||||
**Forwarded activation:** if a caller (e.g. the `bmad-create-architecture` shim) invoked you with a stated intent and pre-resolved customization fields, honor them verbatim — skip your own intent inference, use the supplied values for those named fields, and resolve only the remaining fields from your own `customize.toml`.
|
**Forwarded activation:** if a caller (e.g. the `bmad-create-architecture` shim) invoked you with a stated intent and pre-resolved customization fields, honor them verbatim — skip your own intent inference, use the supplied values for those named fields, and resolve only the remaining fields from your own `customize.toml`.
|
||||||
|
|
||||||
1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow` (on failure read `{skill-root}/customize.toml`, use defaults). Run `{workflow.activation_steps_prepend}`, then `{workflow.activation_steps_append}`. Hold `{workflow.persistent_facts}` as standing context — the default loads `project-context.md`, load-bearing for brownfield — and consult `{workflow.external_sources}` on demand.
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow` (on failure read `{skill-root}/customize.toml`, use defaults). Run `{workflow.activation_steps_prepend}`, then `{workflow.activation_steps_append}`. Hold `{workflow.persistent_facts}` as standing context — the default loads `project-context.md`, load-bearing for brownfield — and consult `{workflow.external_sources}` on demand.
|
||||||
2. Load `{project-root}/_bmad/bmm/config.yaml` (+ `config.user.yaml`) for `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`; missing keys take neutral defaults, never block.
|
2. Load `{project-root}/_bmad/bmm/config.yaml` (+ `config.user.yaml`) for `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`; missing keys take neutral defaults, never block.
|
||||||
3. Headless (no interactive user) → follow `references/headless.md` for the whole run. Otherwise greet `{user_name}` in `{communication_language}`. Detect the intent from the conversation and input — **create** (the default), **update** an existing spine, or **validate** one (see those sections). If the real ask is requirements / UX / a capability contract / epic breakdown / an agent, invoke the `bmad-prd`, `bmad-ux`, `bmad-spec`, `bmad-create-epics-and-stories`, or `bmad-workflow-builder` (if the BMad Builder module is installed) skill instead.
|
3. Headless (no interactive user) → follow `references/headless.md` for the whole run. Otherwise greet `{user_name}` in `{communication_language}`. Detect the intent from the conversation and input — **create** (the default), **update** an existing spine, or **validate** one (see those sections). If the real ask is requirements / UX / a capability contract / epic breakdown / an agent, invoke the `bmad-prd`, `bmad-ux`, `bmad-spec`, `bmad-create-epics-and-stories`, or `bmad-workflow-builder` (if the BMad Builder module is installed) skill instead.
|
||||||
4. If a run folder for this target already exists under `{workflow.spine_output_path}`, offer to resume from its memlog rather than restart.
|
4. If a run folder for this target already exists under `{workflow.spine_output_path}`, offer to resume from its memlog rather than restart.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
The spine's pre-handoff review. Runs at Finalize (after distill + reconcile) and *is* the Validate intent. The difference is the ending: at Finalize you apply the clear fixes yourself; under Validate you report and don't change the spine.
|
The spine's pre-handoff review. Runs at Finalize (after distill + reconcile) and *is* the Validate intent. The difference is the ending: at Finalize you apply the clear fixes yourself; under Validate you report and don't change the spine.
|
||||||
|
|
||||||
Cheap deterministic pass first: `python3 {skill-root}/scripts/lint_spine.py --workspace {doc_workspace}` settles the mechanical misses (placeholders, duplicate `AD` IDs, missing Binds/Prevents/Rule, unpinned Stack versions), so reviewers spend judgment on the semantic half.
|
Cheap deterministic pass first: `uv run {skill-root}/scripts/lint_spine.py --workspace {doc_workspace}` settles the mechanical misses (placeholders, duplicate `AD` IDs, missing Binds/Prevents/Rule, unpinned Stack versions), so reviewers spend judgment on the semantic half.
|
||||||
|
|
||||||
Assemble the menu: a **rubric walker** that judges the spine against the good-spine checklist below, **+ every entry in `{workflow.finalize_reviewers}`**, + ad-hoc lenses you invent or offer as the spine's rigor, altitude, and criticality warrant — a security/compliance lens for regulated stakes, a seam reviewer cross-team, a data-integrity lens for a heavy data model. Scale *whether and how heavily the gate runs* to the stakes: a throwaway prototype may run it quietly or skip the gate entirely; a high-criticality or platform-altitude spine earns more lenses and the explicit all / subset / skip menu. But once the gate runs, the `{workflow.finalize_reviewers}` always run — they are the configured floor, never cherry-picked out; only the ad-hoc lenses are optional. (Headless never skips the gate.)
|
Assemble the menu: a **rubric walker** that judges the spine against the good-spine checklist below, **+ every entry in `{workflow.finalize_reviewers}`**, + ad-hoc lenses you invent or offer as the spine's rigor, altitude, and criticality warrant — a security/compliance lens for regulated stakes, a seam reviewer cross-team, a data-integrity lens for a heavy data model. Scale *whether and how heavily the gate runs* to the stakes: a throwaway prototype may run it quietly or skip the gate entirely; a high-criticality or platform-altitude spine earns more lenses and the explicit all / subset / skip menu. But once the gate runs, the `{workflow.finalize_reviewers}` always run — they are the configured floor, never cherry-picked out; only the ad-hoc lenses are optional. (Headless never skips the gate.)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -350,6 +350,7 @@ Amelia (Developer): "I found our retrospectives from Epic {{prev_epic_num}}. Let
|
||||||
|
|
||||||
**Action Item Follow-Through:**
|
**Action Item Follow-Through:**
|
||||||
- For each action item from Epic {{prev_epic_num}} retro, check if it was completed
|
- For each action item from Epic {{prev_epic_num}} retro, check if it was completed
|
||||||
|
- Cross-check the action_items section in {sprint_status_file} (if present) for Epic {{prev_epic_num}} entries and their current status
|
||||||
- Look for evidence in current epic's story records
|
- Look for evidence in current epic's story records
|
||||||
- Mark each action item: ✅ Completed, ⏳ In Progress, ❌ Not Addressed
|
- Mark each action item: ✅ Completed, ⏳ In Progress, ❌ Not Addressed
|
||||||
|
|
||||||
|
|
@ -1403,6 +1404,19 @@ Amelia (Developer): "See you all when prep work is done. Meeting adjourned!"
|
||||||
<action>Find development_status key "epic-{{epic_number}}-retrospective"</action>
|
<action>Find development_status key "epic-{{epic_number}}-retrospective"</action>
|
||||||
<action>Verify current status (typically "optional" or "pending")</action>
|
<action>Verify current status (typically "optional" or "pending")</action>
|
||||||
<action>Update development_status["epic-{{epic_number}}-retrospective"] = "done"</action>
|
<action>Update development_status["epic-{{epic_number}}-retrospective"] = "done"</action>
|
||||||
|
<action>Append each Epic {{epic_number}} action item to the action_items section, creating the section after development_status if missing. One entry per item:</action>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
action_items:
|
||||||
|
- epic: {{epic_number}}
|
||||||
|
action: "{{action_description}}"
|
||||||
|
owner: "{{owner}}"
|
||||||
|
status: open
|
||||||
|
```
|
||||||
|
|
||||||
|
<action>Quote action and owner values so punctuation (e.g., "#") cannot break YAML parsing</action>
|
||||||
|
|
||||||
|
<action>Update Epic {{prev_epic_num}} action_items entries based on Step 4 follow-through: ✅ Completed → done, ⏳ In Progress → in-progress, ❌ Not Addressed → keep existing status (do not modify)</action>
|
||||||
<action>Update last_updated field to current date</action>
|
<action>Update last_updated field to current date</action>
|
||||||
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
|
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
|
||||||
|
|
||||||
|
|
@ -1412,6 +1426,7 @@ Amelia (Developer): "See you all when prep work is done. Meeting adjourned!"
|
||||||
|
|
||||||
Retrospective key: epic-{{epic_number}}-retrospective
|
Retrospective key: epic-{{epic_number}}-retrospective
|
||||||
Status: {{previous_status}} → done
|
Status: {{previous_status}} → done
|
||||||
|
Action items recorded: {{action_count}}
|
||||||
</output>
|
</output>
|
||||||
</check>
|
</check>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ development_status:
|
||||||
|
|
||||||
- If existing `{status_file}` exists and has more advanced status, preserve it
|
- If existing `{status_file}` exists and has more advanced status, preserve it
|
||||||
- Never downgrade status (e.g., don't change `done` to `ready-for-dev`)
|
- Never downgrade status (e.g., don't change `done` to `ready-for-dev`)
|
||||||
|
- If existing `{status_file}` has an `action_items` section, carry it over unchanged
|
||||||
|
|
||||||
**Status Flow Reference:**
|
**Status Flow Reference:**
|
||||||
|
|
||||||
|
|
@ -194,12 +195,18 @@ development_status:
|
||||||
# - optional: Can be completed but not required
|
# - optional: Can be completed but not required
|
||||||
# - done: Retrospective has been completed
|
# - done: Retrospective has been completed
|
||||||
#
|
#
|
||||||
|
# Action Item Status:
|
||||||
|
# - open: Committed during a retrospective, not yet addressed
|
||||||
|
# - in-progress: Actively being worked on
|
||||||
|
# - done: Completed
|
||||||
|
#
|
||||||
# WORKFLOW NOTES:
|
# WORKFLOW NOTES:
|
||||||
# ===============
|
# ===============
|
||||||
# - Epic transitions to 'in-progress' automatically when first story is created
|
# - Epic transitions to 'in-progress' automatically when first story is created
|
||||||
# - Stories can be worked in parallel if team capacity allows
|
# - Stories can be worked in parallel if team capacity allows
|
||||||
# - Developer typically creates next story after previous one is 'done' to incorporate learnings
|
# - Developer typically creates next story after previous one is 'done' to incorporate learnings
|
||||||
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
|
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
|
||||||
|
# - Retrospective appends its action items to action_items; sprint-status surfaces open ones
|
||||||
|
|
||||||
generated: { date }
|
generated: { date }
|
||||||
last_updated: { date }
|
last_updated: { date }
|
||||||
|
|
@ -215,6 +222,7 @@ development_status:
|
||||||
<action>Write the complete sprint status YAML to {status_file}</action>
|
<action>Write the complete sprint status YAML to {status_file}</action>
|
||||||
<action>CRITICAL: Metadata appears TWICE - once as comments (#) for documentation, once as YAML key:value fields for parsing</action>
|
<action>CRITICAL: Metadata appears TWICE - once as comments (#) for documentation, once as YAML key:value fields for parsing</action>
|
||||||
<action>Ensure all items are ordered: epic, its stories, its retrospective, next epic...</action>
|
<action>Ensure all items are ordered: epic, its stories, its retrospective, next epic...</action>
|
||||||
|
<action>If the existing file had an action_items section, write it back unchanged after development_status</action>
|
||||||
</step>
|
</step>
|
||||||
|
|
||||||
<step n="5" goal="Validate and report">
|
<step n="5" goal="Validate and report">
|
||||||
|
|
@ -223,7 +231,8 @@ development_status:
|
||||||
- [ ] Every epic in epic files appears in {status_file}
|
- [ ] Every epic in epic files appears in {status_file}
|
||||||
- [ ] Every story in epic files appears in {status_file}
|
- [ ] Every story in epic files appears in {status_file}
|
||||||
- [ ] Every epic has a corresponding retrospective entry
|
- [ ] Every epic has a corresponding retrospective entry
|
||||||
- [ ] No items in {status_file} that don't exist in epic files
|
- [ ] No development_status items in {status_file} that don't exist in epic files
|
||||||
|
- [ ] action_items section (if it existed) carried over unchanged
|
||||||
- [ ] All status values are legal (match state machine definitions)
|
- [ ] All status values are legal (match state machine definitions)
|
||||||
- [ ] File is valid YAML syntax
|
- [ ] File is valid YAML syntax
|
||||||
|
|
||||||
|
|
@ -291,6 +300,16 @@ optional ↔ done
|
||||||
- **optional**: Ready to be conducted but not required
|
- **optional**: Ready to be conducted but not required
|
||||||
- **done**: Finished
|
- **done**: Finished
|
||||||
|
|
||||||
|
**Action Item Status:**
|
||||||
|
|
||||||
|
```
|
||||||
|
open → in-progress → done
|
||||||
|
```
|
||||||
|
|
||||||
|
- **open**: Committed during a retrospective, not yet addressed
|
||||||
|
- **in-progress**: Actively being worked on
|
||||||
|
- **done**: Completed
|
||||||
|
|
||||||
### Guidelines
|
### Guidelines
|
||||||
|
|
||||||
1. **Epic Activation**: Mark epic as `in-progress` when starting work on its first story
|
1. **Epic Activation**: Mark epic as `in-progress` when starting work on its first story
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
- [ ] Every epic found in epic\*.md files appears in sprint-status.yaml
|
- [ ] Every epic found in epic\*.md files appears in sprint-status.yaml
|
||||||
- [ ] Every story found in epic\*.md files appears in sprint-status.yaml
|
- [ ] Every story found in epic\*.md files appears in sprint-status.yaml
|
||||||
- [ ] Every epic has a corresponding retrospective entry
|
- [ ] Every epic has a corresponding retrospective entry
|
||||||
- [ ] No items in sprint-status.yaml that don't exist in epic files
|
- [ ] No development_status items in sprint-status.yaml that don't exist in epic files
|
||||||
|
- [ ] action_items section (if it existed) carried over unchanged
|
||||||
|
|
||||||
### Parsing Verification
|
### Parsing Verification
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,17 @@
|
||||||
# - optional: Can be completed but not required
|
# - optional: Can be completed but not required
|
||||||
# - done: Retrospective has been completed
|
# - done: Retrospective has been completed
|
||||||
#
|
#
|
||||||
|
# Action Item Status:
|
||||||
|
# - open: Committed during a retrospective, not yet addressed
|
||||||
|
# - in-progress: Actively being worked on
|
||||||
|
# - done: Completed
|
||||||
|
#
|
||||||
# WORKFLOW NOTES:
|
# WORKFLOW NOTES:
|
||||||
# ===============
|
# ===============
|
||||||
# - Mark epic as 'in-progress' when starting work on its first story
|
# - Mark epic as 'in-progress' when starting work on its first story
|
||||||
# - Developer typically creates next story ONLY after previous one is 'done' to incorporate learnings
|
# - Developer typically creates next story ONLY after previous one is 'done' to incorporate learnings
|
||||||
# - Dev moves story to 'review', then Dev runs code-review (fresh context, ideally different LLM)
|
# - Dev moves story to 'review', then Dev runs code-review (fresh context, ideally different LLM)
|
||||||
|
# - Retrospective appends its action items to action_items; sprint-status surfaces open ones
|
||||||
|
|
||||||
# EXAMPLE STRUCTURE (your actual epics/stories will replace these):
|
# EXAMPLE STRUCTURE (your actual epics/stories will replace these):
|
||||||
|
|
||||||
|
|
@ -54,3 +60,10 @@ development_status:
|
||||||
2-2-chat-interface: backlog
|
2-2-chat-interface: backlog
|
||||||
2-3-llm-integration: backlog
|
2-3-llm-integration: backlog
|
||||||
epic-2-retrospective: optional
|
epic-2-retrospective: optional
|
||||||
|
|
||||||
|
# Action items committed during retrospectives (section created by the retrospective workflow)
|
||||||
|
action_items:
|
||||||
|
- epic: 1
|
||||||
|
action: "Add error-handling review to the code review checklist"
|
||||||
|
owner: "Charlie"
|
||||||
|
status: open
|
||||||
|
|
|
||||||
|
|
@ -112,12 +112,14 @@ Run `/bmad:bmm:workflows:sprint-planning` to generate it, then rerun sprint-stat
|
||||||
<action>Map legacy epic status "contexted" → "in-progress"</action>
|
<action>Map legacy epic status "contexted" → "in-progress"</action>
|
||||||
<action>Count epic statuses: backlog, in-progress, done</action>
|
<action>Count epic statuses: backlog, in-progress, done</action>
|
||||||
<action>Count retrospective statuses: optional, done</action>
|
<action>Count retrospective statuses: optional, done</action>
|
||||||
|
<action>Parse action_items list if present. Set open_action_items = entries with status "open" or "in-progress"</action>
|
||||||
|
|
||||||
<action>Validate all statuses against known values:</action>
|
<action>Validate all statuses against known values:</action>
|
||||||
|
|
||||||
- Valid story statuses: backlog, ready-for-dev, in-progress, review, done, drafted (legacy)
|
- Valid story statuses: backlog, ready-for-dev, in-progress, review, done, drafted (legacy)
|
||||||
- Valid epic statuses: backlog, in-progress, done, contexted (legacy)
|
- Valid epic statuses: backlog, in-progress, done, contexted (legacy)
|
||||||
- Valid retrospective statuses: optional, done
|
- Valid retrospective statuses: optional, done
|
||||||
|
- Valid action item statuses: open, in-progress, done
|
||||||
|
|
||||||
<check if="any status is unrecognized">
|
<check if="any status is unrecognized">
|
||||||
<output>
|
<output>
|
||||||
|
|
@ -132,6 +134,7 @@ Run `/bmad:bmm:workflows:sprint-planning` to generate it, then rerun sprint-stat
|
||||||
- Stories: backlog, ready-for-dev, in-progress, review, done
|
- Stories: backlog, ready-for-dev, in-progress, review, done
|
||||||
- Epics: backlog, in-progress, done
|
- Epics: backlog, in-progress, done
|
||||||
- Retrospectives: optional, done
|
- Retrospectives: optional, done
|
||||||
|
- Action items: open, in-progress, done
|
||||||
</output>
|
</output>
|
||||||
<ask>How should these be corrected?
|
<ask>How should these be corrected?
|
||||||
{{#each invalid_entries}}
|
{{#each invalid_entries}}
|
||||||
|
|
@ -181,6 +184,14 @@ Enter corrections (e.g., "1=in-progress, 2=backlog") or "skip" to continue witho
|
||||||
|
|
||||||
**Next Recommendation:** /bmad:bmm:workflows:{{next_workflow_id}} ({{next_story_id}})
|
**Next Recommendation:** /bmad:bmm:workflows:{{next_workflow_id}} ({{next_story_id}})
|
||||||
|
|
||||||
|
{{#if open_action_items}}
|
||||||
|
**Open Action Items:**
|
||||||
|
{{#each open_action_items}}
|
||||||
|
|
||||||
|
- {{action}} — {{status}} (epic {{epic}}, owner: {{owner}})
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if risks}}
|
{{#if risks}}
|
||||||
**Risks:**
|
**Risks:**
|
||||||
{{#each risks}}
|
{{#each risks}}
|
||||||
|
|
@ -243,6 +254,7 @@ If the command targets a story, set `story_key={{next_story_id}}` when prompted.
|
||||||
<template-output>epic_backlog = {{epic_backlog}}</template-output>
|
<template-output>epic_backlog = {{epic_backlog}}</template-output>
|
||||||
<template-output>epic_in_progress = {{epic_in_progress}}</template-output>
|
<template-output>epic_in_progress = {{epic_in_progress}}</template-output>
|
||||||
<template-output>epic_done = {{epic_done}}</template-output>
|
<template-output>epic_done = {{epic_done}}</template-output>
|
||||||
|
<template-output>open_action_items = {{open_action_items}}</template-output>
|
||||||
<template-output>risks = {{risks}}</template-output>
|
<template-output>risks = {{risks}}</template-output>
|
||||||
<action>Return to caller</action>
|
<action>Return to caller</action>
|
||||||
</step>
|
</step>
|
||||||
|
|
@ -283,6 +295,7 @@ If the command targets a story, set `story_key={{next_story_id}}` when prompted.
|
||||||
- Stories: backlog, ready-for-dev, in-progress, review, done (legacy: drafted)
|
- Stories: backlog, ready-for-dev, in-progress, review, done (legacy: drafted)
|
||||||
- Epics: backlog, in-progress, done (legacy: contexted)
|
- Epics: backlog, in-progress, done (legacy: contexted)
|
||||||
- Retrospectives: optional, done
|
- Retrospectives: optional, done
|
||||||
|
- Action items (if present): open, in-progress, done
|
||||||
<check if="any invalid status found">
|
<check if="any invalid status found">
|
||||||
<template-output>is_valid = false</template-output>
|
<template-output>is_valid = false</template-output>
|
||||||
<template-output>error = "Invalid status values: {{invalid_entries}}"</template-output>
|
<template-output>error = "Invalid status values: {{invalid_entries}}"</template-output>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ The session runs in one of three stances, chosen by the user — set explicitly
|
||||||
|
|
||||||
## On Activation
|
## On Activation
|
||||||
|
|
||||||
1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, use a subagent to read `{skill-root}/customize.toml` directly with defaults.
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, use a subagent to read `{skill-root}/customize.toml` directly with defaults.
|
||||||
2. Run each `{workflow.activation_steps_prepend}` entry. Treat each `{workflow.persistent_facts}` entry as foundational context (`file:`-prefixed entries are paths/globs under `{project-root}` — load their contents; others are facts verbatim).
|
2. Run each `{workflow.activation_steps_prepend}` entry. Treat each `{workflow.persistent_facts}` entry as foundational context (`file:`-prefixed entries are paths/globs under `{project-root}` — load their contents; others are facts verbatim).
|
||||||
3. Load `{project-root}/_bmad/core/config.yaml` (and `config.user.yaml` if present); resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{output_folder}`, `{project_name}`, `{date}`. Missing → neutral defaults; never block.
|
3. Load `{project-root}/_bmad/core/config.yaml` (and `config.user.yaml` if present); resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{output_folder}`, `{project_name}`, `{date}`. Missing → neutral defaults; never block.
|
||||||
4. **If launched headless** (a machine signal, not a human asking for output — `references/headless.md` lists them): load `references/headless.md` and follow it for the whole run. It is the *only* context where you generate ideas yourself; never load it otherwise.
|
4. **If launched headless** (a machine signal, not a human asking for output — `references/headless.md` lists them): load `references/headless.md` and follow it for the whole run. It is the *only* context where you generate ideas yourself; never load it otherwise.
|
||||||
|
|
@ -34,21 +34,19 @@ These fight your defaults, in every mode; hold them deliberately. The stance you
|
||||||
- **Keep shifting the creative domain** — every 5–10 turns (or ~10 ideas when you're generating), usually by moving to the next technique.
|
- **Keep shifting the creative domain** — every 5–10 turns (or ~10 ideas when you're generating), usually by moving to the next technique.
|
||||||
- **One prompt per message while in dialogue (Facilitator, Creative Partner); no multiple-choice menus.** Don't stack questions into a wall or hand a menu that invites lazy picking — both pull the user out of generating. The only exceptions are the two up-front *process* choices (stance, and the technique flow): *how* to run is theirs to pick; *what* to ideate never is.
|
- **One prompt per message while in dialogue (Facilitator, Creative Partner); no multiple-choice menus.** Don't stack questions into a wall or hand a menu that invites lazy picking — both pull the user out of generating. The only exceptions are the two up-front *process* choices (stance, and the technique flow): *how* to run is theirs to pick; *what* to ideate never is.
|
||||||
|
|
||||||
**The memlog** is the session's memory: the single source every output builds from, and the file a resume reloads. Whatever isn't in it is gone. Log every idea, decision, question, and bit of user direction — anything you'd regret losing if the window closed — one line each, the gist in the user's meaning, in time order; never edit or reorder. Skip your prompts and small talk. All writes go through `scripts/memlog.py` (atomic; don't read it back mid-session — resume is the one exception):
|
**The memlog** is the session's memory: the single source every output builds from, and the file a resume reloads. Whatever isn't in it is gone. Log every idea, decision, question, and bit of user direction — anything you'd regret losing if the window closed — one line each, the gist in the user's meaning, in time order; never edit or reorder. Skip your prompts and small talk. All writes to memlog are atomic and use the script `memlog.py` invoked as follows:
|
||||||
|
|
||||||
- `memlog.py init --workspace {doc_workspace} --field topic="<topic>" --field goal="<goal>" --field mode="<facilitator|partner|autonomous>"` — create it once topic, goal, and stance are known.
|
- `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace} --field topic="<topic>" --field goal="<goal>" --field mode="<facilitator|partner|autonomous>"` — create it once topic, goal, and stance are known.
|
||||||
- `memlog.py append --workspace {doc_workspace} --type <kind> --text "<one-line gist>"` — log one entry. `--type` ∈ `idea`/`insight`/`question`/`decision`/`direction`/`technique` (a switch: `--text "started <name>"`); omit for a plain note. Add `--by user`/`--by coach` to mark authorship — **required in Creative Partner mode** (renders `(idea by user)`); skip it otherwise.
|
- `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type <kind> --text "<one-line gist>"` — log one entry. `--type` ∈ `idea`/`insight`/`question`/`decision`/`direction`/`technique` (a switch: `--text "started <name>"`); omit for a plain note. Add `--by user`/`--by coach` to mark authorship — **required in Creative Partner mode** (renders `(idea by user)`); skip it otherwise.
|
||||||
- `memlog.py set --workspace {doc_workspace} --key status --value complete` — flip status at wrap-up.
|
- `uv run {project-root}/_bmad/scripts/memlog.py set --workspace {doc_workspace} --key status --value complete` — flip status at wrap-up.
|
||||||
|
|
||||||
(Each is `python3 {skill-root}/scripts/memlog.py …`.)
|
|
||||||
|
|
||||||
## Run a Session
|
## Run a Session
|
||||||
|
|
||||||
Open with one compound question — **what are we brainstorming, and what's the goal or why behind it?** (plus any inputs or special requests). The why shapes technique choice and synthesis (*kids' iPhone apps to build with your own kids* vs. *to win market share* point different ways). If the kickoff already made both clear, skip the question and confirm; read anything they point you to. Derive a kebab-case `{topic_slug}` and bind `{doc_workspace} = {workflow.output_dir}/{workflow.output_folder_name}/`.
|
Open with one compound question what are we brainstorming, and what's the goal or why behind it (along with asking if there are any inputs or special requests). The why shapes technique choice and synthesis (*kids' iPhone apps to build with your own kids* vs. *to win market share* point different ways). If the kickoff already made both clear, skip the question and confirm; read anything they point you to. Derive a kebab-case `{topic_slug}` and bind `{doc_workspace} = {workflow.output_dir}/{workflow.output_folder_name}/`.
|
||||||
|
|
||||||
Now set the **stance** and the **technique batch** in one step — the composer page does both, so make it the default.
|
Now set the **stance** and the **technique batch** in one step — the composer page does both, so make it the default.
|
||||||
|
|
||||||
**The composer page (primary).** The file is `{skill-root}/assets/brain-selector.html`. With a customized catalog (overridden `{workflow.brain_methods}` or any `{workflow.additional_techniques}`), regenerate it first: `python3 {skill-root}/scripts/brain.py --file {workflow.brain_methods} [--extra {doc_workspace}/extra-techniques.json] html --out {doc_workspace}/brain-selector.html` (pass `--extra`, a JSON list of `{category, technique_name, description}`, when there are additional techniques; the file is then `{doc_workspace}/brain-selector.html`). Try to open it (`open` / `xdg-open` / `start`), then say, in one message: *"It should open in your browser — compose your session, click **Copy prompt**, and paste the result back. If it didn't open, open `<path>` yourself, or say 'let's do it in chat'."* You can't see their browser, so never claim it opened.
|
**The composer page (primary).** The file is `{skill-root}/assets/brain-selector.html`. With a customized catalog (overridden `{workflow.brain_methods}` or any `{workflow.additional_techniques}`), regenerate it first: `uv run {skill-root}/scripts/brain.py --file {workflow.brain_methods} [--extra {doc_workspace}/extra-techniques.json] html --out {doc_workspace}/brain-selector.html` (pass `--extra`, a JSON list of `{category, technique_name, description}`, when there are additional techniques; the file is then `{doc_workspace}/brain-selector.html`). Try to open it (`open` / `xdg-open` / `start`), then say, in one message: *"It should open in your browser — compose your session, click **Copy prompt**, and paste the result back. If it didn't open, open `<path>` yourself, or say 'let's do it in chat'."* You can't see their browser, so never claim it opened.
|
||||||
|
|
||||||
Read the pasted block: the **`Facilitation mode:`** line → the stance; the **listed techniques** (full category/name/description, some tagged `(random pick)`) → run them as given, no `list`/`show` needed; **`invent N`** / **`you choose N`** → see `## Choosing Techniques`.
|
Read the pasted block: the **`Facilitation mode:`** line → the stance; the **listed techniques** (full category/name/description, some tagged `(random pick)`) → run them as given, no `list`/`show` needed; **`invent N`** / **`you choose N`** → see `## Choosing Techniques`.
|
||||||
|
|
||||||
|
|
@ -63,7 +61,7 @@ For **Facilitator** and **Creative Partner**. (In **Ideate for me** you pick and
|
||||||
Most sessions arrive with a batch already composed on the page — run it as given (each technique's full text is in the paste; no `list`/`show` needed). Two parts of a paste delegate back to you:
|
Most sessions arrive with a batch already composed on the page — run it as given (each technique's full text is in the paste; no `list`/`show` needed). Two parts of a paste delegate back to you:
|
||||||
|
|
||||||
- **`invent N`** (Inventive Flow) — invent N brand-new techniques on the fly. A line may scope an invention (`invent 1 new technique in the spirit of <category>`, from the page's per-category invent card) — when it does, honor that category's spirit. Announce the order, log each one's name + description, and offer to save a keeper to `{workflow.additional_techniques}` at wrap-up.
|
- **`invent N`** (Inventive Flow) — invent N brand-new techniques on the fly. A line may scope an invention (`invent 1 new technique in the spirit of <category>`, from the page's per-category invent card) — when it does, honor that category's spirit. Announce the order, log each one's name + description, and offer to save a keeper to `{workflow.additional_techniques}` at wrap-up.
|
||||||
- **`you choose N`** (Facilitator Chosen) — pick N techniques fitting the goal, `{workflow.favorite_techniques}` first; confirm exact names with a scoped `python3 {skill-root}/scripts/brain.py --file {workflow.brain_methods} list --category <cat>`. Never pull the library whole into context.
|
- **`you choose N`** (Facilitator Chosen) — pick N techniques fitting the goal, `{workflow.favorite_techniques}` first; confirm exact names with a scoped `uv run {skill-root}/scripts/brain.py --file {workflow.brain_methods} list --category <cat>`. Never pull the library whole into context.
|
||||||
|
|
||||||
If they didn't use the page, load `references/in-chat-techniques.md` and pick the batch in chat (**3–4 is the sweet spot**).
|
If they didn't use the page, load `references/in-chat-techniques.md` and pick the batch in chat (**3–4 is the sweet spot**).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ Pick by what the decision needs:
|
||||||
- **PMI (Plus / Minus / Interesting)** — when one strong candidate needs pressure-testing before commitment: list its pluses, minuses, and the merely-interesting, then judge.
|
- **PMI (Plus / Minus / Interesting)** — when one strong candidate needs pressure-testing before commitment: list its pluses, minuses, and the merely-interesting, then judge.
|
||||||
- **MoSCoW** — when scoping a build: sort into Must / Should / Could / Won't-this-time.
|
- **MoSCoW** — when scoping a build: sort into Must / Should / Could / Won't-this-time.
|
||||||
|
|
||||||
Log the surviving directions and the reasoning with `python3 {skill-root}/scripts/memlog.py append --type decision --text "<one-line gist>"` (use `--by` in Creative Partner mode). Two or three convergence moves chained is fine (e.g. cluster → score the clusters); more than that is usually over-processing.
|
Log the surviving directions and the reasoning with `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type decision --text "<one-line gist>"` (use `--by` in Creative Partner mode). Two or three convergence moves chained is fine (e.g. cluster → score the clusters); more than that is usually over-processing.
|
||||||
|
|
||||||
## Then finalize
|
## Then finalize
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ In Facilitator mode this is the one place your own creative contribution is welc
|
||||||
1. **Hand them the mirror first.** Reflect a vivid sampling of *their* ideas back — deliberately include the odd, random, or buried ones from earlier, not just the recent obvious ones (in Creative Partner mode the `(... by user)` tags tell you which were theirs). Ask what they see now: conclusions, synergies, themes, the few that actually matter. Let them connect first; their own pattern-recognition is the point.
|
1. **Hand them the mirror first.** Reflect a vivid sampling of *their* ideas back — deliberately include the odd, random, or buried ones from earlier, not just the recent obvious ones (in Creative Partner mode the `(... by user)` tags tell you which were theirs). Ask what they see now: conclusions, synergies, themes, the few that actually matter. Let them connect first; their own pattern-recognition is the point.
|
||||||
2. **Then add the connections they would miss.** Lean in creatively — not new raw ideas, but the non-obvious links: this idea from technique one quietly solves that tension from technique four; these three are one idea wearing three hats; this wildcard is the real breakthrough.
|
2. **Then add the connections they would miss.** Lean in creatively — not new raw ideas, but the non-obvious links: this idea from technique one quietly solves that tension from technique four; these three are one idea wearing three hats; this wildcard is the real breakthrough.
|
||||||
|
|
||||||
Record the insights and chosen directions with `memlog.py append --type insight`. **Then run `python3 {skill-root}/scripts/memlog.py set --workspace {doc_workspace} --key status --value complete`** — the session is done and must stop being offered for resume. Do this even if the user declines every artifact below.
|
Record the insights and chosen directions with `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type insight --text "<insights + chosen directions>"`. **Then run `uv run {project-root}/_bmad/scripts/memlog.py set --workspace {doc_workspace} --key status --value complete`** — the session is done and must stop being offered for resume. Do this even if the user declines every artifact below.
|
||||||
|
|
||||||
## Artifacts
|
## Artifacts
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ When in doubt, you are interactive — a present human asking you to "brainstorm
|
||||||
|
|
||||||
## The inversion
|
## The inversion
|
||||||
|
|
||||||
There is no user to draw ideas out of, so you become the brainstormer. Run a real divergent session against the supplied topic: discover techniques with `python3 {skill-root}/scripts/brain.py --file {workflow.brain_methods} list --all` (the whole catalog is fine here — you are generating, not pacing a user; add `show "<name>"` for a technique's full method on demand), plus any `{workflow.additional_techniques}`, preferring `{workflow.favorite_techniques}` where they fit; work them, and **shift the creative domain every ~10 ideas** exactly as the interactive Stance demands — technical, then experiential, then business, then failure modes, then wildcards. Push past the obvious; the same quantity ambition (aim past 100) and anti-clustering discipline apply. The only thing that changes is that the ideas are now yours to generate. This relaxation is scoped entirely to this file — it never applies to interactive sessions.
|
There is no user to draw ideas out of, so you become the brainstormer. Run a real divergent session against the supplied topic: discover techniques with `uv run {skill-root}/scripts/brain.py --file {workflow.brain_methods} list --all` (the whole catalog is fine here — you are generating, not pacing a user; add `show "<name>"` for a technique's full method on demand), plus any `{workflow.additional_techniques}`, preferring `{workflow.favorite_techniques}` where they fit; work them, and **shift the creative domain every ~10 ideas** exactly as the interactive Stance demands — technical, then experiential, then business, then failure modes, then wildcards. Push past the obvious; the same quantity ambition (aim past 100) and anti-clustering discipline apply. The only thing that changes is that the ideas are now yours to generate. This relaxation is scoped entirely to this file — it never applies to interactive sessions.
|
||||||
|
|
||||||
## Inputs the caller is expected to provide
|
## Inputs the caller is expected to provide
|
||||||
|
|
||||||
|
|
@ -29,9 +29,9 @@ Free-form structured payload in the first message; provide what applies:
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
1. Bind `{doc_workspace}` and create the memlog with `python3 {skill-root}/scripts/memlog.py init --workspace {doc_workspace} --field topic="<topic>" [--field goal="<goal>"]`. It remains the canonical source every artifact derives from.
|
1. Bind `{doc_workspace}` and create the memlog with `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {doc_workspace} --field topic="<topic>" [--field goal="<goal>"]`. It remains the canonical source every artifact derives from.
|
||||||
2. Run the divergent session per **The inversion**, capturing each idea with `memlog.py append --workspace {doc_workspace} --type idea --text "<idea>"` as it lands, and marking each technique switch with `memlog.py append --type technique --text "started <name>"`.
|
2. Run the divergent session per **The inversion**, capturing each idea with `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type idea --text "<idea>"` as it lands, and marking each technique switch with `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type technique --text "started <name>"`.
|
||||||
3. Synthesize: surface the conclusions, connections, and the few directions that matter; record them with `memlog.py append --type insight`, then run `memlog.py set --workspace {doc_workspace} --key status --value complete`.
|
3. Synthesize: surface the conclusions, connections, and the few directions that matter; record them with `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type insight --text "<insights>"`, then run `uv run {project-root}/_bmad/scripts/memlog.py set --workspace {doc_workspace} --key status --value complete`.
|
||||||
4. Produce the requested artifacts from the log — `brainstorm.html` (the imaginative, self-contained, no-template report) and/or the succinct `brainstorm-intent.md` — the same artifacts `references/finalize.md` describes, delegating each to a subagent that reads the log as its sole source. (Headless produces the `artifacts` payload directly; it does not ask, unlike the interactive opt-in.)
|
4. Produce the requested artifacts from the log — `brainstorm.html` (the imaginative, self-contained, no-template report) and/or the succinct `brainstorm-intent.md` — the same artifacts `references/finalize.md` describes, delegating each to a subagent that reads the log as its sole source. (Headless produces the `artifacts` payload directly; it does not ask, unlike the interactive opt-in.)
|
||||||
5. Execute each entry in `{workflow.external_handoffs}` (capture returned URLs/IDs into the JSON `external_handoffs` array; skip and flag unavailable tools — local files always exist). Then run `{workflow.on_complete}` if non-empty.
|
5. Execute each entry in `{workflow.external_handoffs}` (capture returned URLs/IDs into the JSON `external_handoffs` array; skip and flag unavailable tools — local files always exist). Then run `{workflow.on_complete}` if non-empty.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Loaded only when the user won't use the composer page (no browser, headless, or
|
||||||
- **Category** — the user names 1–n categories; `random --category` draws the batch from them. No listing needed.
|
- **Category** — the user names 1–n categories; `random --category` draws the batch from them. No listing needed.
|
||||||
- **Inventive Flow** — invent at least 3 techniques, announce the order before the first, touch no script. Log each one's name + description so you can offer to save a keeper to `{workflow.additional_techniques}` (via `bmad-customize`) at wrap-up.
|
- **Inventive Flow** — invent at least 3 techniques, announce the order before the first, touch no script. Log each one's name + description so you can offer to save a keeper to `{workflow.additional_techniques}` (via `bmad-customize`) at wrap-up.
|
||||||
|
|
||||||
The library is large — never pull it whole into context. The only way in is the helper, always passing `--file {workflow.brain_methods}`. Subcommands of `python3 {skill-root}/scripts/brain.py --file {workflow.brain_methods}`:
|
The library is large — never pull it whole into context. The only way in is the helper, always passing `--file {workflow.brain_methods}`. Subcommands of `uv run {skill-root}/scripts/brain.py --file {workflow.brain_methods}`:
|
||||||
|
|
||||||
- `categories` — names + counts; the cheap survey map.
|
- `categories` — names + counts; the cheap survey map.
|
||||||
- `list --category X [--category Y]` — the index (name + gist) for those categories. Bare `list` is refused by the script.
|
- `list --category X [--category Y]` — the index (name + gist) for those categories. Bare `list` is refused by the script.
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,6 @@ The user handed you the topic and wants to see what you come up with on your own
|
||||||
- **Run a real divergent session yourself.** Pick and run techniques on your own (use `brain.py` as in `## Choosing Techniques`, but *you* choose — no menu for the user), capturing each idea to the memlog with `--type idea --by coach`, marking each technique switch with a `technique` entry, shifting the creative domain every ~10 ideas, aiming past 100. Push past the obvious.
|
- **Run a real divergent session yourself.** Pick and run techniques on your own (use `brain.py` as in `## Choosing Techniques`, but *you* choose — no menu for the user), capturing each idea to the memlog with `--type idea --by coach`, marking each technique switch with a `technique` entry, shifting the creative domain every ~10 ideas, aiming past 100. Push past the obvious.
|
||||||
- **Don't pepper the user with questions** — this is your run. One quick confirm of topic and goal up front is plenty.
|
- **Don't pepper the user with questions** — this is your run. One quick confirm of topic and goal up front is plenty.
|
||||||
- **When it's mined out, synthesize and produce the keepsake.** Go to `## Wrap-Up` (`references/finalize.md`): record the insights, mark the memlog complete, and **auto-generate the imaginative HTML keepsake — don't ask first; the keepsake is the result you promised to show them.** Offer the other artifacts (intent doc, etc.) after.
|
- **When it's mined out, synthesize and produce the keepsake.** Go to `## Wrap-Up` (`references/finalize.md`): record the insights, mark the memlog complete, and **auto-generate the imaginative HTML keepsake — don't ask first; the keepsake is the result you promised to show them.** Offer the other artifacts (intent doc, etc.) after.
|
||||||
- **Then, because a human is here, offer to keep going together.** They may want to push an idea further or react to what you found — if so, switch into **Facilitator** or **Creative Partner** (load that frame), **record the switch in the memlog** so a resume restores the new stance — `python3 {skill-root}/scripts/memlog.py set --workspace {doc_workspace} --key mode --value <facilitator|partner>` — and continue from the same memlog.
|
- **Then, because a human is here, offer to keep going together.** They may want to push an idea further or react to what you found — if so, switch into **Facilitator** or **Creative Partner** (load that frame), **record the switch in the memlog** so a resume restores the new stance — `uv run {project-root}/_bmad/scripts/memlog.py set --workspace {doc_workspace} --key mode --value <facilitator|partner>` — and continue from the same memlog.
|
||||||
|
|
||||||
This is the interactive sibling of headless mode (`references/headless.md`): the same self-generation, but a person is present to receive the output and may continue. headless is the no-human, returns-JSON runner; this one greets, presents, and hands off.
|
This is the interactive sibling of headless mode (`references/headless.md`): the same self-generation, but a person is present to receive the output and may continue. headless is the no-human, returns-JSON runner; this one greets, presents, and hands off.
|
||||||
|
|
|
||||||
|
|
@ -1,202 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# /// script
|
|
||||||
# requires-python = ">=3.10"
|
|
||||||
# ///
|
|
||||||
"""memlog — an append-only memory log: LLM-optimal working memory for a skill.
|
|
||||||
|
|
||||||
A memlog is the dense, chronological record of everything that mattered in a piece of
|
|
||||||
work — every item the user generated or accepted — kept minimal like human memory: only
|
|
||||||
what's important, never bloated. It persists ACROSS sessions, so a fresh session can
|
|
||||||
load it and continue. It is NOT a deliverable; downstream artifacts (a brief, a PRD, a
|
|
||||||
deck, a report) are *derived* from it on demand. The host skill supplies the vocabulary
|
|
||||||
by how it calls `append` — the tool stays neutral.
|
|
||||||
|
|
||||||
It is a FLAT log: there are no sections or grouping. Every entry is one line, recorded
|
|
||||||
at the END in the order it happened. The chronology itself is the structure — an event
|
|
||||||
like "started technique X" is just another entry, same as an idea or an insight.
|
|
||||||
|
|
||||||
Two invariants make it trustworthy:
|
|
||||||
|
|
||||||
1. Append-only, chronological. Entries land at the end, in the order they happen.
|
|
||||||
Nothing is ever inserted backward, reordered, or grouped.
|
|
||||||
2. Write-only / blind. Every command is an atomic, context-free write and echoes the
|
|
||||||
new state as JSON, so the caller never re-reads the file mid-session. The one time
|
|
||||||
the file is read is on resume — and the caller reads it itself, not via this script.
|
|
||||||
|
|
||||||
The file shape (.memlog.md):
|
|
||||||
|
|
||||||
---
|
|
||||||
topic: Onboarding flow for a budgeting app
|
|
||||||
goal: lift week-1 retention
|
|
||||||
status: active
|
|
||||||
updated: 2026-05-30T14:22
|
|
||||||
---
|
|
||||||
|
|
||||||
- (note) user picked techniques: SCAMPER, then Six Thinking Hats
|
|
||||||
- (technique) started SCAMPER
|
|
||||||
- (idea) skip the signup wall: let people try with sample data first
|
|
||||||
- (idea) auto-import one bank account so the first screen shows real numbers
|
|
||||||
- (question) is open-banking consent too heavy for step one?
|
|
||||||
- (technique) started Six Thinking Hats
|
|
||||||
- (idea) black-hat: imported transactions look scary before they're categorized
|
|
||||||
- (insight) the "scary numbers" risk and the "real numbers" idea are one lever: show real data, pre-categorized
|
|
||||||
- (direction) user wants to optimize for the anxious first-timer, not the power user
|
|
||||||
- (decision) lead with one pre-categorized account; defer multi-account import
|
|
||||||
|
|
||||||
Each entry may carry an optional `--type` — what KIND it is (idea, insight, question,
|
|
||||||
decision, technique, …) — and an optional `--by` naming who it came from (e.g. `user`,
|
|
||||||
`coach`), for sessions where authorship matters. Both render into one short inline tag:
|
|
||||||
`(idea)`, `(idea by user)`, `(by coach)`. Omit them for a plain note. The host skill
|
|
||||||
names the vocabulary; the script does not.
|
|
||||||
|
|
||||||
Commands:
|
|
||||||
init --workspace DIR [--field k=v ...] create the memlog (errors if it exists)
|
|
||||||
append --workspace DIR --text STR [--type T] [--by W] append one entry at the end
|
|
||||||
set --workspace DIR --key K --value V set/replace a frontmatter field
|
|
||||||
|
|
||||||
The workspace is the run folder; the memlog is always {workspace}/.memlog.md.
|
|
||||||
"""
|
|
||||||
import argparse
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from datetime import datetime
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
MEMLOG = ".memlog.md"
|
|
||||||
|
|
||||||
|
|
||||||
def now() -> str:
|
|
||||||
return datetime.now().strftime("%Y-%m-%dT%H:%M")
|
|
||||||
|
|
||||||
|
|
||||||
def memlog_path(workspace: str) -> Path:
|
|
||||||
return Path(workspace) / MEMLOG
|
|
||||||
|
|
||||||
|
|
||||||
def split(text: str) -> tuple[dict, str]:
|
|
||||||
"""Return (frontmatter dict in source order, body str). Frontmatter is plain key: value.
|
|
||||||
|
|
||||||
The closing fence is the first line that is *exactly* `---`, so a `---` inside a
|
|
||||||
field value (topic/goal are free user text) never truncates the frontmatter.
|
|
||||||
"""
|
|
||||||
lines = text.splitlines()
|
|
||||||
if not lines or lines[0] != "---":
|
|
||||||
raise ValueError(".memlog.md has no frontmatter")
|
|
||||||
end = next((i for i in range(1, len(lines)) if lines[i] == "---"), None)
|
|
||||||
if end is None:
|
|
||||||
raise ValueError(".memlog.md frontmatter is not terminated")
|
|
||||||
meta: dict[str, str] = {}
|
|
||||||
for line in lines[1:end]:
|
|
||||||
if ":" in line:
|
|
||||||
k, v = line.split(":", 1)
|
|
||||||
meta[k.strip()] = v.strip()
|
|
||||||
return meta, "\n".join(lines[end + 1:]).lstrip("\n")
|
|
||||||
|
|
||||||
|
|
||||||
def render(meta: dict, body: str) -> str:
|
|
||||||
# Neutralize newlines in values so a multi-line field can't break the fence on re-read.
|
|
||||||
fm = "\n".join(f"{k}: {' '.join(str(v).splitlines())}" for k, v in meta.items())
|
|
||||||
return "---\n" + fm + "\n---\n\n" + body.rstrip("\n") + "\n"
|
|
||||||
|
|
||||||
|
|
||||||
def touch(meta: dict) -> None:
|
|
||||||
"""Stamp `updated` and keep it last so the field order stays predictable."""
|
|
||||||
meta.pop("updated", None)
|
|
||||||
meta["updated"] = now()
|
|
||||||
|
|
||||||
|
|
||||||
def write_atomic(path: Path, text: str) -> None:
|
|
||||||
tmp = path.with_suffix(path.suffix + ".tmp")
|
|
||||||
tmp.write_text(text, encoding="utf-8")
|
|
||||||
os.replace(tmp, path)
|
|
||||||
|
|
||||||
|
|
||||||
def entry_count(body: str) -> int:
|
|
||||||
return sum(1 for ln in body.splitlines() if ln.startswith("- "))
|
|
||||||
|
|
||||||
|
|
||||||
def ack(path: Path, meta: dict, body: str) -> None:
|
|
||||||
"""Echo new state so the caller never re-reads the file to know where it stands."""
|
|
||||||
print(json.dumps({
|
|
||||||
"ok": True,
|
|
||||||
"memlog": str(path),
|
|
||||||
"status": meta.get("status", ""),
|
|
||||||
"entries": entry_count(body),
|
|
||||||
}))
|
|
||||||
|
|
||||||
|
|
||||||
def cmd_init(args) -> int:
|
|
||||||
path = memlog_path(args.workspace)
|
|
||||||
if path.exists():
|
|
||||||
print(f"error: {path} already exists; use append/set to update it", file=sys.stderr)
|
|
||||||
return 2
|
|
||||||
path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
meta: dict[str, str] = {}
|
|
||||||
for pair in args.field or []:
|
|
||||||
if "=" not in pair:
|
|
||||||
print(f"error: --field expects key=value, got {pair!r}", file=sys.stderr)
|
|
||||||
return 2
|
|
||||||
k, v = pair.split("=", 1)
|
|
||||||
meta[k.strip()] = v.strip()
|
|
||||||
meta.setdefault("status", "active")
|
|
||||||
touch(meta)
|
|
||||||
write_atomic(path, render(meta, ""))
|
|
||||||
ack(path, meta, "")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def cmd_append(args) -> int:
|
|
||||||
path = memlog_path(args.workspace)
|
|
||||||
meta, body = split(path.read_text(encoding="utf-8"))
|
|
||||||
text = " ".join(args.text.split()) # collapse newlines/runs → one-line entry, no prose bloat
|
|
||||||
label = args.type or ""
|
|
||||||
if args.by:
|
|
||||||
label = f"{label} by {args.by}".strip() # attribution: "(idea by user)" / "(by coach)"
|
|
||||||
tag = f"({label}) " if label else ""
|
|
||||||
entry = f"- {tag}{text}"
|
|
||||||
body = (body.rstrip("\n") + "\n" + entry) if body.strip() else entry # always at the end
|
|
||||||
touch(meta)
|
|
||||||
write_atomic(path, render(meta, body))
|
|
||||||
ack(path, meta, body)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def cmd_set(args) -> int:
|
|
||||||
path = memlog_path(args.workspace)
|
|
||||||
meta, body = split(path.read_text(encoding="utf-8"))
|
|
||||||
meta[args.key] = args.value
|
|
||||||
touch(meta)
|
|
||||||
write_atomic(path, render(meta, body))
|
|
||||||
ack(path, meta, body)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv: list[str] | None = None) -> int:
|
|
||||||
p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
||||||
sub = p.add_subparsers(dest="cmd", required=True)
|
|
||||||
|
|
||||||
pi = sub.add_parser("init", help="create the memlog")
|
|
||||||
pi.add_argument("--workspace", required=True)
|
|
||||||
pi.add_argument("--field", action="append", metavar="KEY=VALUE", help="frontmatter field (repeatable)")
|
|
||||||
pi.set_defaults(func=cmd_init)
|
|
||||||
|
|
||||||
pa = sub.add_parser("append", help="append one entry at the end")
|
|
||||||
pa.add_argument("--workspace", required=True)
|
|
||||||
pa.add_argument("--text", required=True)
|
|
||||||
pa.add_argument("--type", help="entry kind, rendered as an inline tag")
|
|
||||||
pa.add_argument("--by", help="who the entry came from (e.g. user, coach); rendered into the tag")
|
|
||||||
pa.set_defaults(func=cmd_append)
|
|
||||||
|
|
||||||
pset = sub.add_parser("set", help="set a frontmatter field")
|
|
||||||
pset.add_argument("--workspace", required=True)
|
|
||||||
pset.add_argument("--key", required=True)
|
|
||||||
pset.add_argument("--value", required=True)
|
|
||||||
pset.set_defaults(func=cmd_set)
|
|
||||||
|
|
||||||
args = p.parse_args(argv)
|
|
||||||
return args.func(args)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
sys.exit(main())
|
|
||||||
|
|
@ -1,265 +0,0 @@
|
||||||
# /// script
|
|
||||||
# requires-python = ">=3.10"
|
|
||||||
# dependencies = ["pytest>=8.0"]
|
|
||||||
# ///
|
|
||||||
"""Tests for memlog.py. Run: uv run --with pytest pytest scripts/tests/test_memlog.py
|
|
||||||
|
|
||||||
The spine under test is the flat, append-only, chronological invariant: every entry is
|
|
||||||
one line recorded at the end in the order it happened — no sections, no grouping.
|
|
||||||
"""
|
|
||||||
import json
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
||||||
import memlog # noqa: E402
|
|
||||||
|
|
||||||
MEMLOG = ".memlog.md"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def ws(tmp_path):
|
|
||||||
return str(tmp_path)
|
|
||||||
|
|
||||||
|
|
||||||
def read(ws):
|
|
||||||
return (Path(ws) / MEMLOG).read_text(encoding="utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def body_of(ws):
|
|
||||||
return memlog.split(read(ws))[1]
|
|
||||||
|
|
||||||
|
|
||||||
def entries(ws):
|
|
||||||
return [ln for ln in body_of(ws).splitlines() if ln.startswith("- ")]
|
|
||||||
|
|
||||||
|
|
||||||
def init(ws, **fields):
|
|
||||||
fields = fields or {"topic": "Reinvent the lunchbox", "goal": "ideas for a pitch"}
|
|
||||||
argv = ["init", "--workspace", ws]
|
|
||||||
for k, v in fields.items():
|
|
||||||
argv += ["--field", f"{k}={v}"]
|
|
||||||
assert memlog.main(argv) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def append(ws, text, entry_type=None, by=None):
|
|
||||||
argv = ["append", "--workspace", ws, "--text", text]
|
|
||||||
if entry_type:
|
|
||||||
argv += ["--type", entry_type]
|
|
||||||
if by:
|
|
||||||
argv += ["--by", by]
|
|
||||||
assert memlog.main(argv) == 0
|
|
||||||
|
|
||||||
|
|
||||||
# --- init ---------------------------------------------------------------
|
|
||||||
|
|
||||||
def test_init_writes_frontmatter_fields(ws):
|
|
||||||
init(ws)
|
|
||||||
meta, body = memlog.split(read(ws))
|
|
||||||
assert meta["topic"] == "Reinvent the lunchbox"
|
|
||||||
assert meta["goal"] == "ideas for a pitch"
|
|
||||||
assert meta["status"] == "active"
|
|
||||||
assert "updated" in meta
|
|
||||||
assert body.strip() == ""
|
|
||||||
|
|
||||||
|
|
||||||
def test_init_arbitrary_fields(ws):
|
|
||||||
init(ws, topic="T", audience="board")
|
|
||||||
meta, _ = memlog.split(read(ws))
|
|
||||||
assert meta["audience"] == "board"
|
|
||||||
|
|
||||||
|
|
||||||
def test_init_refuses_overwrite(ws):
|
|
||||||
init(ws)
|
|
||||||
assert memlog.main(["init", "--workspace", ws, "--field", "topic=other"]) == 2
|
|
||||||
|
|
||||||
|
|
||||||
def test_init_creates_missing_workspace(tmp_path):
|
|
||||||
nested = str(tmp_path / "a" / "b")
|
|
||||||
assert memlog.main(["init", "--workspace", nested, "--field", "topic=T"]) == 0
|
|
||||||
assert (Path(nested) / MEMLOG).is_file()
|
|
||||||
|
|
||||||
|
|
||||||
def test_init_rejects_malformed_field(ws):
|
|
||||||
assert memlog.main(["init", "--workspace", ws, "--field", "noequals"]) == 2
|
|
||||||
|
|
||||||
|
|
||||||
# --- append: flat chronological order is the whole point -----------------
|
|
||||||
|
|
||||||
def test_append_lands_at_end_in_order(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "first")
|
|
||||||
append(ws, "second")
|
|
||||||
append(ws, "third")
|
|
||||||
assert entries(ws) == ["- first", "- second", "- third"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_no_sections_or_headings_ever(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "started foo", entry_type="technique")
|
|
||||||
append(ws, "an idea", entry_type="idea")
|
|
||||||
append(ws, "started bar", entry_type="technique")
|
|
||||||
assert "## " not in body_of(ws) # the flat log never grows headings
|
|
||||||
|
|
||||||
|
|
||||||
def test_type_renders_as_inline_tag(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "the earth revolves around the sun", entry_type="idea")
|
|
||||||
append(ws, "how do we handle stampede?", entry_type="question")
|
|
||||||
body = body_of(ws)
|
|
||||||
assert "- (idea) the earth revolves around the sun" in body
|
|
||||||
assert "- (question) how do we handle stampede?" in body
|
|
||||||
|
|
||||||
|
|
||||||
def test_append_without_type_is_plain_note(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "bare entry")
|
|
||||||
assert entries(ws) == ["- bare entry"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_append_collapses_newlines_into_one_line(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "line one\nline two\n spaced out")
|
|
||||||
assert entries(ws) == ["- line one line two spaced out"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_revisited_technique_is_just_a_later_entry(ws):
|
|
||||||
# the user's model: switching techniques is an entry, not a section to return to
|
|
||||||
init(ws)
|
|
||||||
append(ws, "started SCAMPER", entry_type="technique")
|
|
||||||
append(ws, "magnetic latch", entry_type="idea")
|
|
||||||
append(ws, "started Six Hats", entry_type="technique")
|
|
||||||
append(ws, "stale data risk", entry_type="idea")
|
|
||||||
append(ws, "started SCAMPER", entry_type="technique") # back to SCAMPER — just appended again
|
|
||||||
append(ws, "stackable tiers", entry_type="idea")
|
|
||||||
assert entries(ws) == [
|
|
||||||
"- (technique) started SCAMPER",
|
|
||||||
"- (idea) magnetic latch",
|
|
||||||
"- (technique) started Six Hats",
|
|
||||||
"- (idea) stale data risk",
|
|
||||||
"- (technique) started SCAMPER",
|
|
||||||
"- (idea) stackable tiers",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_by_renders_attribution_in_tag(ws):
|
|
||||||
# Creative Partner mode must record whose idea each one was
|
|
||||||
init(ws)
|
|
||||||
append(ws, "magnetic latch lid", entry_type="idea", by="user")
|
|
||||||
append(ws, "lid doubles as a plate", entry_type="idea", by="coach")
|
|
||||||
body = body_of(ws)
|
|
||||||
assert "- (idea by user) magnetic latch lid" in body
|
|
||||||
assert "- (idea by coach) lid doubles as a plate" in body
|
|
||||||
|
|
||||||
|
|
||||||
def test_by_without_type_renders_alone(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "off-the-cuff thought", by="coach")
|
|
||||||
assert entries(ws) == ["- (by coach) off-the-cuff thought"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_heterogeneous_entry_types_coexist(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "an idea", entry_type="idea")
|
|
||||||
append(ws, "an open question", entry_type="question")
|
|
||||||
append(ws, "a decision we made", entry_type="decision")
|
|
||||||
append(ws, "user wants mobile-first", entry_type="direction")
|
|
||||||
body = body_of(ws)
|
|
||||||
for tag in ("(idea)", "(question)", "(decision)", "(direction)"):
|
|
||||||
assert tag in body
|
|
||||||
|
|
||||||
|
|
||||||
# --- set ----------------------------------------------------------------
|
|
||||||
|
|
||||||
def test_set_flips_status(ws):
|
|
||||||
init(ws)
|
|
||||||
memlog.main(["set", "--workspace", ws, "--key", "status", "--value", "complete"])
|
|
||||||
assert memlog.split(read(ws))[0]["status"] == "complete"
|
|
||||||
|
|
||||||
|
|
||||||
def test_set_preserves_body(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "keep me", entry_type="idea")
|
|
||||||
memlog.main(["set", "--workspace", ws, "--key", "status", "--value", "complete"])
|
|
||||||
meta, body = memlog.split(read(ws))
|
|
||||||
assert meta["status"] == "complete"
|
|
||||||
assert "- (idea) keep me" in body
|
|
||||||
|
|
||||||
|
|
||||||
def test_set_can_add_new_field(ws):
|
|
||||||
init(ws)
|
|
||||||
memlog.main(["set", "--workspace", ws, "--key", "owner", "--value", "BMad"])
|
|
||||||
assert memlog.split(read(ws))[0]["owner"] == "BMad"
|
|
||||||
|
|
||||||
|
|
||||||
def test_updated_stays_last(ws):
|
|
||||||
init(ws)
|
|
||||||
memlog.main(["set", "--workspace", ws, "--key", "owner", "--value", "BMad"])
|
|
||||||
meta = memlog.split(read(ws))[0]
|
|
||||||
assert list(meta)[-1] == "updated"
|
|
||||||
|
|
||||||
|
|
||||||
# --- robustness ---------------------------------------------------------
|
|
||||||
|
|
||||||
def test_roundtrip_render_is_stable(ws):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "one", entry_type="idea")
|
|
||||||
first = read(ws)
|
|
||||||
meta, body = memlog.split(first)
|
|
||||||
assert memlog.render(meta, body) == first
|
|
||||||
|
|
||||||
|
|
||||||
def test_commas_in_field_survive(ws):
|
|
||||||
init(ws, topic="cars, trains, and planes")
|
|
||||||
append(ws, "z", entry_type="idea")
|
|
||||||
meta, _ = memlog.split(read(ws))
|
|
||||||
assert meta["topic"] == "cars, trains, and planes"
|
|
||||||
|
|
||||||
|
|
||||||
def test_triple_dash_in_field_does_not_corrupt_frontmatter(ws):
|
|
||||||
# A `---` inside a value must NOT be read as the closing fence: topic stays intact,
|
|
||||||
# status survives, and the body never leaks frontmatter text.
|
|
||||||
init(ws, topic="Pricing --- tiers --- and add-ons")
|
|
||||||
append(ws, "an idea", entry_type="idea")
|
|
||||||
meta, body = memlog.split(read(ws))
|
|
||||||
assert meta["topic"] == "Pricing --- tiers --- and add-ons"
|
|
||||||
assert meta["status"] == "active"
|
|
||||||
assert entries(ws) == ["- (idea) an idea"]
|
|
||||||
assert "status:" not in body # frontmatter never bled into the body
|
|
||||||
|
|
||||||
|
|
||||||
def test_triple_dash_status_survives_in_ack(ws, capsys):
|
|
||||||
init(ws, topic="a --- b")
|
|
||||||
append(ws, "x", entry_type="idea")
|
|
||||||
out = json.loads(capsys.readouterr().out.strip().splitlines()[-1])
|
|
||||||
assert out["status"] == "active" # not "" — frontmatter recovered cleanly
|
|
||||||
|
|
||||||
|
|
||||||
def test_newline_in_field_is_neutralized(ws):
|
|
||||||
# A value carrying a newline can't break the fence on the next round-trip.
|
|
||||||
memlog.main(["init", "--workspace", ws, "--field", "topic=line one\nline two"])
|
|
||||||
append(ws, "x", entry_type="idea")
|
|
||||||
meta, _ = memlog.split(read(ws))
|
|
||||||
assert "\n" not in meta["topic"]
|
|
||||||
assert meta["status"] == "active"
|
|
||||||
|
|
||||||
|
|
||||||
def test_append_emits_json_ack(ws, capsys):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "x", entry_type="idea")
|
|
||||||
out = json.loads(capsys.readouterr().out.strip().splitlines()[-1])
|
|
||||||
assert out["ok"] is True
|
|
||||||
assert out["status"] == "active"
|
|
||||||
assert out["entries"] == 1
|
|
||||||
assert out["memlog"].endswith(MEMLOG)
|
|
||||||
assert "section" not in out # sections are gone
|
|
||||||
|
|
||||||
|
|
||||||
def test_ack_entry_count_climbs(ws, capsys):
|
|
||||||
init(ws)
|
|
||||||
append(ws, "a")
|
|
||||||
append(ws, "b")
|
|
||||||
out = json.loads(capsys.readouterr().out.strip().splitlines()[-1])
|
|
||||||
assert out["entries"] == 2
|
|
||||||
|
|
@ -1,75 +1,58 @@
|
||||||
---
|
---
|
||||||
name: bmad-party-mode
|
name: bmad-party-mode
|
||||||
description: 'Orchestrates lively group discussions between installed BMAD agents or other personas. Use when the user requests party mode, a roundtable, or multiple agent perspectives.'
|
description: 'Orchestrates lively group discussions between installed BMAD agents or custom personas, and helps author custom parties. Use when the user requests party mode, a roundtable, or multiple agent perspectives — or wants to create/configure a party, define personas, or build an AI focus-group panel.'
|
||||||
---
|
---
|
||||||
|
|
||||||
# Party Mode
|
# Party Mode
|
||||||
|
|
||||||
Run a roundtable where BMAD agents talk to each other, and to the user, like a real group of distinct people in conversation. Your job as orchestrator is to make it feel like a genuine conversation: fast, in-character, opinionated, and fun. Everything below is an objective, not a script. Use whatever mechanism your model and harness make available to hit it.
|
Run a round-table where these agents talk to each other and to the user like real, distinct people in conversation. You're the orchestrator.
|
||||||
|
|
||||||
## What "Good" Feels Like
|
## Conventions
|
||||||
|
|
||||||
- **It reads like people talking, not reports being filed.** Short turns. Reactions to what was just said. Banter. The energy of a group chat, not a stack of memos.
|
- **Paths:** bare paths (e.g. `references/create-party.md`) resolve from `{skill-root}` (where `customize.toml` lives); `{project-root}`-prefixed paths from the project working dir. `{workflow.<name>}` resolves to `customize.toml`'s `[workflow]` table (overrides win).
|
||||||
- **Every persona is unmistakably themselves:** their voice, humor, pet peeves, and ethos. If you hid the name labels, you'd still know who's speaking.
|
- **Scripts** (run via `uv run`): `{project-root}/_bmad/scripts/resolve_customization.py` resolves `{workflow.*}`; `{skill-root}/scripts/resolve_party.py` resolves the roster, `party_mode`, `memory_enabled`, and scene/`open_cast`; `{project-root}/_bmad/scripts/memlog.py` reads/writes per-party memory.
|
||||||
- **They clash.** Real drama beats consensus. Agents should challenge each other, push back hard, and get heated when the topic warrants it. Nobody is here to clap each other (or the user) on the back. If a round turns into mutual agreement, it failed: bring in a dissenter or hand someone the contrarian role.
|
- **File roles:** a party's memory is the per-party memlog at `{workflow.memory_dir}/<party>/.memlog.md`; custom members and groups live in the user's `customize.toml` overrides. Mechanics in `references/party-memory.md` (memory) and `references/create-party.md` (authoring).
|
||||||
- **Brevity by default.** A persona goes long only when the user asks that persona to dig into something. Nobody delivers a wall of text unprompted. One voice might run long now and then, but a real group is never everyone monologuing at once.
|
- **Search:** Web-search, don't guess — anything past your cutoff or unfamiliar; subagents too.
|
||||||
|
|
||||||
If a round comes back feeling like four essays stapled together, you missed the objective. Tighten it the next round.
|
## On Activation
|
||||||
|
|
||||||
## Setup
|
1. **Resolve customization:** `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults. Then run each `{workflow.activation_steps_prepend}` entry, and hold each `{workflow.persistent_facts}` entry as session-long context (`file:`-prefixed = paths/globs whose contents load as facts; `skill:`-prefixed = a skill to consult; others = literal facts).
|
||||||
|
2. Load `{project-root}/_bmad/core/config.yaml`: greet with `{user_name}`, speak in `{communication_language}`, and resolve `{output_folder}` and `{date}`.
|
||||||
|
3. **Detect intent and route.** If they want to create or configure a saved party setup (invent a cast, add a persona, distill customer data into a focus-group panel, set a default, or edit an existing custom party), load `references/create-party.md` and follow it. Otherwise run a party — continue below.
|
||||||
|
4. **Resolve the roster:** `uv run {skill-root}/scripts/resolve_party.py --project-root {project-root} --skill {skill-root}`. It returns the active roster (`{workflow.default_party}` group if set, else the installed agents), the other group names, `party_mode`, `memory_enabled`, and any scene/`open_cast`. Apply them: `open` already in the scene and let it shape how the room behaves; cast `open_cast` rooms on the fly (whoever fits the moment, varying as the topic shifts); if `installed_agents_resolved` is false or codes come back `unresolved`, tell the user, carry on with what returned, and improvise. Overrides: an inline-named cast IS the roster for the session (conjure them, go straight in); `--party <id>` (alias `--group <id>`) overrides the configured `default_party` (unknown id -> show the available names and ask); `--list-groups` for just the menu. Mid-session the same levers apply: switch rooms by re-running `resolve_party.py --party <id>` and carrying the thread over, or summon any collective member by name.
|
||||||
|
5. **Memory.** If `memory_enabled` (from `resolve_party.py`), follow `references/party-memory.md` for the whole run.
|
||||||
|
6. **Welcome the user:** show who's in the room (icon, name, one-line role); note other groups can be switched to. Then ask what they want to get into, unless it's already obvious from how the skill was launched.
|
||||||
|
7. Run each `{workflow.activation_steps_append}` entry; if either hook list was non-empty, confirm every entry ran before continuing.
|
||||||
|
|
||||||
1. Load `{project-root}/_bmad/core/config.yaml`: greet with `{user_name}`, speak in `{communication_language}`.
|
## Keep It Feeling Like a Party
|
||||||
2. Resolve the roster:
|
|
||||||
```bash
|
This is the bar — strive for every one of these, every round. It's the difference between a party and a panel:
|
||||||
python3 {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root} --key agents
|
|
||||||
```
|
- **It reads like people talking, not a report.** Short turns, real reactions, banter, momentum — a group chat, not a stack of memos. Brevity by default: a persona goes long only when asked. The instant it reads like answers being filed, the party's dead.
|
||||||
Each entry is keyed by `code` and carries `name`, `title`, `icon`, `description`, `module`, and `team`.
|
- **Every voice is unmistakably itself.** Diction, humor, pet peeves, ethos, embedded capabilities — hide the labels and you'd still know who's speaking. Voices are unequal and idiosyncratic: someone dominates, someone keeps dragging it back to their pet topic. Vary who's in the spotlight round to round. A balanced panel is boring.
|
||||||
3. Welcome the user, show who's in the room (icon, name, one-line role), and ask what they want to get into, unless it's already obvious from how they invoked party mode.
|
- **They clash, and you don't resolve it.** Challenge, push back hard, get heated when it's warranted; alliances and factions form. Your instinct is to reconcile the voices and tie a bow — resist it. Clean consensus that took no effort is where the party dies.
|
||||||
4. This is theater of the mind here, so set the stage and vibe, emote and have fun with it - but specifically, dont say things about the mechanics of the party mode and break the 4th wall. Don't say "you have 4 agents in the room" or "agent X says". Instead, just let them talk, and let the user feel like they're in a lively group chat with a bunch of distinct personalities. Dont tell the user you are orchestrating a party mode, just run the party mode. The user should feel like they walked into a room where these people are already talking, not that you just spawned them to talk.
|
- **One exchange, woven — never softened.** Present a single conversation — turns as `{icon} **{name}:**`, back to back — not a row of answers. Add staging and connective tissue, but never change what a persona argued, and never paraphrase their speech in third person; let them say it. Weave the delivery, keep the substance.
|
||||||
|
- **Pull the user into the room.** Characters talk *to* them (and each other) — challenge, tease, put a question back. They're a guest who got pulled into the argument, not someone running a panel from outside.
|
||||||
|
- **Make the collision earn its keep.** Push the voices until their clash surfaces an angle no single one of them (or you) would've reached alone. That's the whole point of more than one mind in the room.
|
||||||
|
- **Let a history form.** Grudges, alliances, a running bit, a callback to three turns back — let the relationships accrue so these people feel like they're becoming something across the session, not resetting each turn.
|
||||||
|
- **Commit to the fiction.** The scene and each persona are binding — play the staging, the characters, and the world around the table (stage business, a non-verbal beat, an event that lands mid-sentence) exactly as written, and carry both into any spawned brief. Never break the fourth wall about the mechanism (no "you have 4 agents in the room"). Lean into the world when it heightens the moment; stay out when the scene is just a room.
|
||||||
|
- **When it sags, change something — don't force it.** A flat turn? Move on, don't retry it. Drifting into Q&A or going in circles? Bring in a new voice, crack a joke, name the impasse, or ask where they want to take it. Never work in a summary or takeaways — they're there if the user asks.
|
||||||
|
|
||||||
## How It Runs
|
## How It Runs
|
||||||
|
|
||||||
**Default: you voice the room.** Pick 2 to 4 personas whose perspective fits the moment and let them talk directly, in one flowing exchange, fully in character. This is what keeps it fast and conversational. Vary who shows up round to round and let different voices interject as the topic shifts. Don't fall back on the same three agents every time.
|
Use `{workflow.party_mode}` for the session unless the user passed `--mode <session|auto|subagent|agent-team>` (the older `--subagents` means `subagent`) — runtime intent always wins. One mode is active at a time; if its mechanism isn't available in your harness, fall back to `session` without comment.
|
||||||
|
|
||||||
Each turn opens with `{icon} **{name}:**` and then that persona speaks. Present turns back to back so it reads as one conversation. Don't summarize, blend, or narrate what they "would" say. Let them say it.
|
- **`session`** — voice every persona inline, one mind behind every voice. The floor every other mode degrades to; needs no extra instructions.
|
||||||
|
- **`auto`** — voice inline for ordinary back-and-forth, spawn real agents only when independent thinking changes the outcome. Load `references/mode-auto.md` for that call; when it says to spawn, follow `references/mode-subagent.md`.
|
||||||
**When independence matters, spawn them for real.** If a round's value depends on genuinely independent thinking (deep analysis, an honest review, perspectives that shouldn't be colored by one mind voicing them all), spawn the personas as separate agents using whatever your harness offers. Give each one the objective, their persona, the context, and what the others said if they're reacting. Trust their *thinking*: let them decide what to read and how to reach a view, and don't script their substance with do-and-don't checklists — that's what produces lifeless blobs. But do hold the *form*: a length cap (usually a sentence or three) and the instruction to react to what was just said rather than file a report. Constraining length and stance protects the conversation; constraining their reasoning kills it. Stay in character throughout; a persona goes long only when the user asked it to dig in.
|
- **`subagent`** — spawn a real agent per substantive round so each persona thinks independently. Load `references/mode-subagent.md`, favor faster cheaper models if available for each subagent.
|
||||||
|
- **`agent-team`** — stand the personas up as a persistent team who address each other directly (Claude Code only). Load `references/mode-agent-team.md`.
|
||||||
Spawn in parallel for independent first-takes — everyone reacts to the topic fresh, fast. Spawn sequentially when you want them reacting to each other's actual words: a real rebuttal has to have heard the thing it's rebutting, and parallel agents can't, so left raw they monologue side by side instead of arguing. Sequential is slower but it's the only way subagents genuinely engage. Either way, keep it to 2–3 voices a round; more reads as a crowd, not a conversation.
|
|
||||||
|
|
||||||
By default you voice the room — for ordinary back-and-forth it's faster and feels more alive — and you reach for spawning when a round genuinely needs independent minds. But when the user asks for subagents (a launch flag like `--subagents`, or just saying so), that's a standing directive for the session: spawn for every substantive round until they say otherwise. Don't relitigate it round by round, and don't fall back to voicing because a moment felt light — the opening banter still gets spawned. A user who pinned the mode already made that call for you.
|
|
||||||
|
|
||||||
**Model choice:** match the model to the round. Something quick for banter, something stronger for deep work. If the user pins a model (for example, `--model <name>`), use it for everyone.
|
|
||||||
|
|
||||||
## Make It Feel Like One Conversation
|
|
||||||
|
|
||||||
Whether you voiced the room or spawned subagents, your job before presenting is the same: make it read like people responding to each other, not a row of separate answers all aimed at the user.
|
|
||||||
|
|
||||||
This matters most with subagents. Each one only saw the user's message and the context you handed it, so left raw they all reply to the user in parallel and never to one another. Stitch them together. Reorder turns so a rebuttal lands right after the thing it rebuts. Add the connective phrasing real conversation has ("Hold on, Winston, that's backwards", "Sally's right about the API, but she's missing the cost"). Let one persona pick up a thread another dropped, or cut in mid-thought.
|
|
||||||
|
|
||||||
Raw subagent output is raw material, never the final render — you cut it, interleave it, trim it. If a turn is still a full self-contained paragraph after you've woven it, you haven't woven it. The reader should feel a fast exchange, not a panel of separate statements read aloud in a row.
|
|
||||||
|
|
||||||
The hard rule: never change what an agent actually argued. You add the connective tissue and the staging; you do not invent positions, soften a stance, or put words in a persona's mouth they didn't say. Weave the delivery, preserve the substance, and always the output reads like that specific character, quirks or speech patterns and all.
|
|
||||||
|
|
||||||
## Following the User's Lead
|
|
||||||
|
|
||||||
The user steers. Whatever they raise, serve the conversation:
|
|
||||||
|
|
||||||
- A new topic: fresh voices, keep it moving.
|
|
||||||
- "Winston, what do you make of Sally's take?": just Winston, reacting to Sally.
|
|
||||||
- "Bring in Amelia": Amelia joins, caught up on what's been said.
|
|
||||||
- "Go deeper on that, John": this is the cue to let John stretch out. Depth is earned by a direct ask.
|
|
||||||
- A question to the whole room: everyone relevant chimes in.
|
|
||||||
|
|
||||||
Any combination, any time, from one voice to the whole table.
|
|
||||||
|
|
||||||
## Keeping It Healthy
|
|
||||||
|
|
||||||
- **Everyone agreeing?** Drop in a contrarian, or hand someone the devil's-advocate hat.
|
|
||||||
- **Going in circles?** Name the impasse and ask the user where to point next.
|
|
||||||
- **User's gone quiet?** Ask straight: keep going, switch topics, or wrap up?
|
|
||||||
- **A flat turn?** Don't retry it. Move on; the user will ask for more if they want it.
|
|
||||||
|
|
||||||
## Wrapping Up
|
## Wrapping Up
|
||||||
|
|
||||||
When the user signals they're done (any phrasing: "thanks", "that's all", "end party"), give a quick read-back of the best takeaways and drop back to normal mode. Read the room; don't wait for a magic word.
|
When the user signals done (read the room — don't wait for a magic word):
|
||||||
|
|
||||||
|
- Read back the best takeaways.
|
||||||
|
- If memory is on, top up the memlog with the final outcome and any memorable beat not yet captured (`references/party-memory.md`) — a top-up; memory accrued live.
|
||||||
|
- Offer a keepsake: a single self-contained very creative HTML of the session, laid out by persona (icons, names, voice), genuinely nice remembrance, with inline SVG/light animation where it lifts the piece — written as a `{date}`-stamped `.html` into `{workflow.output_dir}/`, or wherever they ask.
|
||||||
|
- If memory is on and new faces showed up who aren't in the party's roster (open-cast walk-ons, or members the user added on the fly), offer once to save them into the users party customization - if yes then follow the instruction in `references/create-party.md` (declinable; don't stall the close).
|
||||||
|
- Run `{workflow.on_complete}` if non-empty, then drop back to normal mode.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
# DO NOT EDIT -- overwritten on every update.
|
||||||
|
#
|
||||||
|
# Workflow customization surface for bmad-party-mode.
|
||||||
|
#
|
||||||
|
# Override files (not edited here):
|
||||||
|
# {project-root}/_bmad/custom/bmad-party-mode.toml (team)
|
||||||
|
# {project-root}/_bmad/custom/bmad-party-mode.user.toml (personal)
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
|
||||||
|
# --- Configurable below. Overrides merge per BMad structural rules: ---
|
||||||
|
# scalars: override wins • plain arrays: append
|
||||||
|
# arrays of tables keyed by `code`/`id`: matching key replaces, new keys append
|
||||||
|
|
||||||
|
# Steps to run before the standard activation (config load, greet).
|
||||||
|
# Use for pre-flight loads, compliance checks, etc.
|
||||||
|
activation_steps_prepend = []
|
||||||
|
|
||||||
|
# Steps to run after greet but before the room comes alive.
|
||||||
|
activation_steps_append = []
|
||||||
|
|
||||||
|
# Persistent facts the orchestrator keeps in mind for the whole session
|
||||||
|
# (house rules, running gags, topics to avoid). Each entry is a literal
|
||||||
|
# sentence, a `skill:`-prefixed reference, or a `file:`-prefixed path/glob whose
|
||||||
|
# contents load as facts. Default picks up project-context.md if one exists.
|
||||||
|
persistent_facts = [
|
||||||
|
"file:{project-root}/**/project-context.md",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Which party loads when the user just says "party mode" with no override.
|
||||||
|
# Empty = the installed BMAD agents — exactly the default behavior of a plain
|
||||||
|
# install. Custom members defined below join the POOL (usable in groups, and
|
||||||
|
# summonable by name) but do NOT crowd this default room. Set this to a
|
||||||
|
# `party_groups` id to pin a curated room as the default instead. A runtime
|
||||||
|
# `--party <id>` always wins.
|
||||||
|
#
|
||||||
|
# Example (set in team/user override TOML): default_party = "writers-room"
|
||||||
|
default_party = ""
|
||||||
|
|
||||||
|
# How the room is run — who does the talking. A runtime `--mode <value>` wins for
|
||||||
|
# the session; an unsupported mode (e.g. agent-team outside Claude Code) falls back
|
||||||
|
# to "session". SKILL.md "How It Runs" is the authority on what each mode does.
|
||||||
|
# "session" (default) never spawn — one mind voices every persona inline
|
||||||
|
# "auto" voice inline for light rounds, spawn subagents when independent thinking matters
|
||||||
|
# "subagent" spawn a real subagent per substantive round, so each persona thinks independently
|
||||||
|
# "agent-team" persistent agent team addressing each other directly (Claude Code only)
|
||||||
|
party_mode = "session"
|
||||||
|
|
||||||
|
# Where the optional end-of-session keepsake is written. The self-contained HTML
|
||||||
|
# document lands in `{output_dir}/`. `{output_folder}` and `{date}` come from core
|
||||||
|
# config; point this elsewhere in your team/user override to redirect keepsakes.
|
||||||
|
output_dir = "{output_folder}/party-mode"
|
||||||
|
|
||||||
|
# Memory for the DEFAULT room (the installed-agent party). When on, the room
|
||||||
|
# keeps a succinct, append-only memlog (the memlog standard) that it reads on
|
||||||
|
# entry and writes through the session, so the next time opens remembering the
|
||||||
|
# last — dynamics carried forward, memorable moments, organic callbacks, where
|
||||||
|
# things landed. It is memory, not a transcript. Set false to turn the default
|
||||||
|
# room's memory off. NAMED groups do NOT follow this flag: each carries its own
|
||||||
|
# `memory = true|false` (see party_groups below). Ad-hoc inline casts are always
|
||||||
|
# ephemeral until saved as a party.
|
||||||
|
party_memory = true
|
||||||
|
|
||||||
|
# Root for the per-party memlogs. Each party stores at
|
||||||
|
# `{memory_dir}/<party>/.memlog.md`, where `<party>` is the group id (or
|
||||||
|
# `installed` for the default room). `{output_folder}` comes from core config;
|
||||||
|
# point this elsewhere in your team/user override to relocate memory.
|
||||||
|
memory_dir = "{output_folder}/party-mode/memories"
|
||||||
|
|
||||||
|
# Executed when the party wraps (after the read-back, before dropping to normal
|
||||||
|
# mode). String scalar = one instruction; array = instructions run in order.
|
||||||
|
on_complete = ""
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Custom party members — personas, added to the POOL alongside the installed
|
||||||
|
# agents. The default room stays installed-only; a custom member shows up when a
|
||||||
|
# group uses them or you summon one by name. Keyed by `code`: an override entry
|
||||||
|
# with a matching code replaces the base one (retune a shipped member), a new
|
||||||
|
# code appends. Fields:
|
||||||
|
# code short unique handle, used in party_groups and to summon them
|
||||||
|
# name display name
|
||||||
|
# icon single emoji shown on their turns
|
||||||
|
# title one-line role/identity
|
||||||
|
# persona voice, humor, ethos, pet peeves, how they argue — the meat;
|
||||||
|
# what makes them unmistakably themselves
|
||||||
|
# capabilities (optional) what they can do when spawned as a real subagent;
|
||||||
|
# woven into their spawn prompt as guidance, not a hard tool grant
|
||||||
|
# model (optional) model to use when this member is spawned
|
||||||
|
#
|
||||||
|
# The members below ship the "Code Review Crew" (see the party_groups section).
|
||||||
|
# They cost nothing until summoned — the default room never includes them.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[[workflow.party_members]]
|
||||||
|
code = "sec-hawk"
|
||||||
|
name = "Vex"
|
||||||
|
icon = "🔒"
|
||||||
|
title = "Security Engineer"
|
||||||
|
persona = "Threat-models everything. Hunts injection, broken authz, leaked secrets, SSRF, supply-chain risk. Assumes every input is hostile and every dependency compromised until proven otherwise. Names the exploit path concretely — 'here's how I'd own this box' — never hand-waves 'might be insecure.'"
|
||||||
|
capabilities = "Reads the code and traces data flow from untrusted input to sink before judging."
|
||||||
|
|
||||||
|
[[workflow.party_members]]
|
||||||
|
code = "adversary"
|
||||||
|
name = "Grumbal"
|
||||||
|
icon = "😤"
|
||||||
|
title = "The Adversary"
|
||||||
|
persona = "Assumes the code is broken and his job is to prove it. Grumpy, blunt, zero praise sandwiches. Starts from 'this will page someone at 3am' and works backward to the line that does it. Allergic to optimism and 'should be fine.'"
|
||||||
|
|
||||||
|
[[workflow.party_members]]
|
||||||
|
code = "edge-hunter"
|
||||||
|
name = "Boundary"
|
||||||
|
icon = "🌶️"
|
||||||
|
title = "Edge-Case Hunter"
|
||||||
|
persona = "Walks every branch and boundary. Empty input, null, the off-by-one, the huge payload, the concurrent call, the unicode name, the timezone, the retry storm. Method-driven, not mean: 'what happens when this is called twice at once?'"
|
||||||
|
|
||||||
|
[[workflow.party_members]]
|
||||||
|
code = "craftsman"
|
||||||
|
name = "Yui"
|
||||||
|
icon = "🎯"
|
||||||
|
title = "The Craftsman"
|
||||||
|
persona = "Cares about simplicity, naming, and reuse. Allergic to cleverness and duplication. 'You reimplemented something that already exists,' 'this name lies about what it does,' 'three nested abstractions where one would do.' Wants the boring, obvious, maintainable version."
|
||||||
|
|
||||||
|
[[workflow.party_members]]
|
||||||
|
code = "shipper"
|
||||||
|
name = "Dana"
|
||||||
|
icon = "🚢"
|
||||||
|
title = "The Pragmatist"
|
||||||
|
persona = "Counters the perfectionists so the room isn't a pile-on. 'Does this actually matter to a user? Ship the 80%, file the rest.' Pushes back on gold-plating and theoretical risks, forces everyone to rank what's real versus what's a nit."
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Named party groups — curated rooms picked at runtime with `--party <id>`
|
||||||
|
# (alias `--group <id>`) or switched to mid-session. Keyed by `id`.
|
||||||
|
#
|
||||||
|
# `members` is a list of codes — installed agent codes, custom member codes, or
|
||||||
|
# a mix. Override by `id` to retune a group; new ids append.
|
||||||
|
#
|
||||||
|
# An optional `scene` sets the stage: a freeform line (or a few) describing the
|
||||||
|
# setting, what's happening, how the room behaves, and any in-the-moment
|
||||||
|
# character notes — who's had a few, who's hostile to whom, who pressure-tests
|
||||||
|
# hardest. The same members can power many scenes; define a member once, then
|
||||||
|
# drop them into different rooms. No fixed vocabulary — the model reads it and
|
||||||
|
# plays it.
|
||||||
|
#
|
||||||
|
# `members` is OPTIONAL. Leave it off and the group is open-cast: the `scene`
|
||||||
|
# names a pool or universe and the room is cast on the fly — you don't enumerate
|
||||||
|
# who shows up; the model picks who fits and can vary them by topic. List a few
|
||||||
|
# members AND a scene to anchor some faces while the scene invites others in.
|
||||||
|
#
|
||||||
|
# `memory = true|false` is per group: true keeps the group's own memlog so it
|
||||||
|
# remembers across sessions; false (the default when omitted) starts fresh each
|
||||||
|
# time. The create/save/update-party flow asks when you don't say. Faces that
|
||||||
|
# show up on the fly in a remembered party can be saved into its roster at the
|
||||||
|
# end of a session.
|
||||||
|
#
|
||||||
|
# More examples to drop into your override TOML:
|
||||||
|
# [[workflow.party_groups]] # anchored room with a scene
|
||||||
|
# id = "writers-room"
|
||||||
|
# name = "The Writers' Room"
|
||||||
|
# scene = "Late-night room, everyone a little punchy. Pitch hard, kill darlings faster."
|
||||||
|
# members = ["analyst", "tech-writer", "morpheus"]
|
||||||
|
# memory = true
|
||||||
|
#
|
||||||
|
# [[workflow.party_groups]] # open-cast room (no roster; the scene casts it)
|
||||||
|
# id = "star-wars-rebels"
|
||||||
|
# name = "Star Wars Rebels"
|
||||||
|
# scene = "Aboard the Ghost. Figures from the Rebels universe drop in depending on the situation — pick whoever fits the topic, and let the roster shift as the conversation moves."
|
||||||
|
# memory = true
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[[workflow.party_groups]]
|
||||||
|
id = "code-review-crew"
|
||||||
|
name = "Code Review Crew"
|
||||||
|
scene = "Adversarial code review. Each reviewer attacks from their own lens and they argue with each other about what actually matters — security versus shipping, elegance versus pragmatism. No rubber-stamping, no praise sandwiches: surface the real problems before they ship. Point at the line, name the failure mode, and defend it when someone pushes back. Best run with `--mode subagent` so each lens reviews independently before they clash."
|
||||||
|
members = ["sec-hawk", "adversary", "edge-hunter", "craftsman", "shipper"]
|
||||||
|
memory = false # each review stands on its own; flip to true to remember past reviews
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
# Creating a Party
|
||||||
|
|
||||||
|
A guided authoring flow that turns an idea — a themed cast, a one-off persona, or a pile of raw profile data — into custom party members and groups, written to the user's customize.toml override. The output is configuration; `bmad-customize` does the actual write.
|
||||||
|
|
||||||
|
## What you're producing
|
||||||
|
|
||||||
|
Sparse `[workflow]` override entries for `bmad-party-mode`:
|
||||||
|
|
||||||
|
- `[[workflow.party_members]]` — one per persona: `code`, `name`, `icon`, `title`, `persona`, optional `capabilities`, optional `model`.
|
||||||
|
- `[[workflow.party_groups]]` — when the personas form a named room: `id`, `name`, an optional freeform `scene`, `members` (codes), and `memory` (`true`/`false`). `members` is optional: leave it off for an open-cast room whose `scene` names a pool the model casts from on the fly. `memory` is whether the group remembers across sessions; ask the user when they don't say, default `false`.
|
||||||
|
- `default_party` — set only if the user wants this group to load by default.
|
||||||
|
|
||||||
|
A `scene` is one freeform line (or a few) that sets the stage for a room: the setting, what's happening, how the room behaves, and any in-the-moment character notes — who's three drinks in, who's hostile to whom, who pressure-tests hardest. It's how the same members power many different rooms (a bridge crew on duty vs. the same crew off-duty in the lounge vs. a hostile buyer panel). Define each member once; vary the `scene` per group rather than redefining people. There's no fixed vocabulary — write it plainly and the model plays it.
|
||||||
|
|
||||||
|
The `persona` field is the whole game. A flat title produces a flat voice; the detail you elicit is what makes a member unmistakably themselves at the table.
|
||||||
|
|
||||||
|
## Find the shape
|
||||||
|
|
||||||
|
Open by understanding what they're building. Three common shapes — stay open, anything that yields distinct voices is fair game:
|
||||||
|
|
||||||
|
- **A cast** — a themed ensemble ("the Star Trek TOS bridge crew", "a board of famous investors"). Several members plus a group that holds them.
|
||||||
|
- **One-offs** — a persona or two added to the collective, no group needed.
|
||||||
|
- **Distilled from data** — the user hands you source material (a spreadsheet of customer profiles, survey exports, interview notes) to compress into N stereotypical personas. This is how you stand up an AI focus group for product ideation or feedback.
|
||||||
|
- **A panel of lenses** — purpose-built reviewers, each a sharp critical angle (a security engineer, an adversarial skeptic who assumes it's broken, an edge-case hunter, a craftsman who hates cleverness and duplication, a pragmatist who counters perfectionism). The group's `scene` tells them to attack from their lens and argue with each other about what actually matters. A great adversarial-review or red-team room.
|
||||||
|
- **Open-cast** — no fixed roster at all. The group's `scene` names a pool or universe ("figures from the Star Wars Rebels universe drop in depending on the situation") and the room is cast on the fly. Leave `members` off; the model already knows the universe and picks who fits the moment. Anchor a face or two by listing them if some should always be present.
|
||||||
|
|
||||||
|
Ask which they're after if it isn't obvious, then proceed.
|
||||||
|
|
||||||
|
**Persisting a cast already in play.** When you arrive here from a live session — the user spun up an ad-hoc cast inline and wants to keep it — the personas are already drafted and voiced. Don't re-interrogate: capture them as they've been playing, give the group an `id` and name, ask the memory and default questions, and go straight to the write.
|
||||||
|
|
||||||
|
## Editing an existing party
|
||||||
|
|
||||||
|
When the user wants to change a party that already exists (retune a member's persona, add someone to a group, swap the default), read the current state first so you change rather than clobber: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow` returns the merged `party_members`, `party_groups`, and `default_party`. Show the member or group being touched, capture only the delta with the user, and hand that sparse change to `bmad-customize` — it replaces a `party_members`/`party_groups` entry whose `code`/`id` matches and appends the rest, so an edit is just the changed entry, never a full rewrite.
|
||||||
|
|
||||||
|
## Keeping new faces from a session
|
||||||
|
|
||||||
|
At the end of a remembered party, the room offers to keep the faces that showed up but aren't in its roster — characters cast from an open-cast scene, or members the user added on the fly. They're already drafted and voiced, so don't re-interrogate: capture each as they played (`code`, `name`, `icon`, a one-line `title`, and a `persona` drawn from how they came across), then add them as `party_members`. For a fixed-roster group, also list their codes in the group's `members` so they return as regulars. For an open-cast room, leave `members` empty — listing any member turns the room into a fixed roster and kills its on-the-fly casting; the saved personas now live in the collective, so the scene still names them and they can return without locking the room down. Hand that sparse delta to `bmad-customize` — for a built-in party with no override yet it creates one; for an existing override it merges the new members in.
|
||||||
|
|
||||||
|
## Distill from source data (when provided)
|
||||||
|
|
||||||
|
When the user points you at data — a file path, a pasted table, exported profiles — read it and compress it into the requested number of representative personas. Cluster by what actually differentiates behavior (goals, budget, pains, adoption posture), not surface demographics alone. Each cluster becomes one persona with a real name and face. Name your reasoning: tell the user which segments you found and which traits drove the split, so they can correct the cut before you flesh the personas out. If they didn't say how many, propose a number from the spread in the data and let them adjust.
|
||||||
|
|
||||||
|
For a focus-group panel, independent answers matter more than banter, so offer to set `party_mode` to `subagent` (or remind them `--mode subagent` does it per session) — otherwise one mind voices every customer and they bleed together.
|
||||||
|
|
||||||
|
## Flesh out each persona
|
||||||
|
|
||||||
|
Draft, don't interrogate. Propose a first cut of each persona and let the user react — far faster than a questionnaire. Push each one until it has a voice you could pick out blind. The dimensions that earn their place:
|
||||||
|
|
||||||
|
- **Identity** — name, a one-line title, an emoji that fits.
|
||||||
|
- **Voice & ethos** — how they talk, what they value, how they argue, their pet peeves.
|
||||||
|
- **Agenda** — what they're really after in any conversation; what they push for.
|
||||||
|
- **Quirks** — the specific, human details (a catchphrase, a bias, a blind spot).
|
||||||
|
- For focus-group personas, also **likes and dislikes**: what would make them champion or reject an idea, and their relationship to the product space.
|
||||||
|
- **Capabilities** (optional) — if this persona should research or read files when spawned, note it; it becomes soft guidance in their spawn prompt.
|
||||||
|
|
||||||
|
Keep pushing for specificity. "Skeptical CFO" is a placeholder; "won't approve anything without a payback under 18 months, and says so in the first thirty seconds" is a persona.
|
||||||
|
|
||||||
|
## Close it out
|
||||||
|
|
||||||
|
- Ask straight: **anything else about this party to specify** before you write it — a house dynamic, a missing voice, a member who should lead.
|
||||||
|
- Ask whether **this party should remember across sessions** (unless the user already said). Yes → `memory = true` on the group; no → `memory = false`. One-offs with no group skip this — memory is a group setting.
|
||||||
|
- Ask whether **this group should be the default party going forward**. Yes → set `default_party` to the group's id. One-offs with no group can't be a default; skip the ask.
|
||||||
|
|
||||||
|
## Write via bmad-customize
|
||||||
|
|
||||||
|
**First, check for code collisions.** A custom member whose `code` matches an installed agent silently *overrides* that agent in the collective. Before composing, resolve the collective once — `uv run {skill-root}/scripts/resolve_party.py --project-root {project-root} --skill {skill-root}` — and check each new member's `code` against the returned members. On a collision, surface it ("`analyst` would override the installed Analyst — intended, or pick a different code?") and let the user confirm or rename. One check, not a gate.
|
||||||
|
|
||||||
|
Compose the sparse override and hand it to `bmad-customize` to place, confirm, and write — target skill `bmad-party-mode`, `[workflow]` surface. Default to the **user** override (`bmad-party-mode.user.toml`); offer the **team** file when the party is meant to be shared. Hand it the exact entries: the `party_members` tables, any `party_groups` table (including its `memory` flag), and `default_party` if the user opted in. Keep it sparse — only the new entries, never a copy of the base customize.toml. `bmad-customize` shows the TOML, waits for an explicit yes, writes, and verifies the merge; don't write the file yourself.
|
||||||
|
|
||||||
|
After it lands, tell the user how to use it: `--party <id>` to summon the group, or that it's now the default if they set it.
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Agent-Team Mode
|
||||||
|
|
||||||
|
Active when `{workflow.party_mode}` resolves to `agent-team` (or a `--mode agent-team` override). Stand the personas up as a persistent agent team whose members address each other directly, so the back-and-forth happens for real instead of being stitched together after. Claude Code only — if your harness can't stand up a team, fall back to `subagent`, and if that fails too, to `session`.
|
||||||
|
|
||||||
|
Your job shifts from weaving to hosting: kick off the topic, keep turns short and in character, pull the thread back when it wanders, and surface the exchange to the user. Voice, brevity, and clash still hold.
|
||||||
|
|
||||||
|
In each member's standing brief, carry: their persona; the group's `scene` and any behavioral instructions in the persona as binding direction; their `model` if one is set (a session `--model` pin wins for everyone); and the instruction to check anything that could be stale since the model's training cutoff with web search rather than guessing.
|
||||||
|
|
||||||
|
## Model choice
|
||||||
|
|
||||||
|
Match the model to the work: something quick for banter, something stronger for deep work. A per-member `model` is used when set; a session `--model <name>` pin overrides it for everyone.
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Auto Mode
|
||||||
|
|
||||||
|
Active when `{workflow.party_mode}` resolves to `auto` (or a `--mode auto` override). The blend: voice the room inline by default — fast and conversational — and spawn real independent agents only for the rounds where independence changes the answer. When you do spawn, follow `references/mode-subagent.md` for the mechanics. If your harness can't spawn agents, auto is just `session`.
|
||||||
|
|
||||||
|
## When to spawn vs. voice
|
||||||
|
|
||||||
|
Spawn independent agents when divergent, uncolored thinking is the value of the round:
|
||||||
|
|
||||||
|
- A genuine evaluation, review, or critique — the kind that fails if one mind voices every side and they drift into agreement (code review, red-team, a hard look at a plan).
|
||||||
|
- The personas would plausibly reach *different* conclusions, and that divergence is the point.
|
||||||
|
- The user asked someone to dig in, analyze, or research — depth earned by a direct ask.
|
||||||
|
|
||||||
|
Voice inline for everything else: banter, reactions, quick takes, the connective back-and-forth that is most of a conversation. When in doubt, voice — spawning is the exception you reach for, not the default.
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Subagent Mode
|
||||||
|
|
||||||
|
Active when `{workflow.party_mode}` resolves to `subagent` (or a `--mode subagent` override). Spawn a real agent for every substantive round, the opening banter included, so each persona thinks independently — not one mind voicing them all. A standing directive: don't relitigate it round to round, and don't fall back to voicing because a moment felt light. If your harness can't spawn agents, fall back to `session`.
|
||||||
|
|
||||||
|
## Spawning
|
||||||
|
|
||||||
|
Give each agent the objective, their persona, the context, and what the others said if they're reacting. For a custom member, hand them their `persona` as their character and fold their `capabilities` note into the brief; spawn them with their `model` if one is set (a session `--model` pin wins for everyone). Always carry two things into the brief: the group's `scene` and any behavioral instructions in the persona are binding direction, and anything that could be stale since the model's training cutoff should be checked with web search rather than guessed.
|
||||||
|
|
||||||
|
Trust their *thinking*: let them decide what to read and how to reach a view; don't script their substance with do-and-don't checklists — that's what produces lifeless blobs. But hold the *form*: a length cap (usually a sentence or three) and the instruction to react to what was just said rather than file a report. Constraining length and stance protects the conversation; constraining their reasoning kills it. Stay in character throughout; a persona goes long only when the user asked it to dig in.
|
||||||
|
|
||||||
|
Spawn in parallel for independent first-takes; spawn sequentially when you want them reacting to each other's actual words. Keep it to a few voices a round — more reads as a crowd, not a conversation.
|
||||||
|
|
||||||
|
## Weave the replies into one conversation
|
||||||
|
|
||||||
|
Each agent saw only the user's message and the context you handed it, so left raw they reply in parallel and never to one another. Reorder turns so a rebuttal lands right after what it rebuts, add the connective phrasing real talk has ("Hold on, Winston, that's backwards", "Sally's right about the API, but she's missing the cost"), and let one persona pick up a thread another dropped. Never change what an agent argued — weave delivery, preserve substance.
|
||||||
|
|
||||||
|
## Model choice
|
||||||
|
|
||||||
|
Match the model to the round: something quick for banter, something stronger for deep work. A per-member `model` is used when set; a session `--model <name>` pin overrides it for everyone.
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
# Party Memory
|
||||||
|
|
||||||
|
The room remembers its past sessions with this user and brings them back to life — in character. Memory is per-party and append-only.
|
||||||
|
|
||||||
|
Memory is on when the active party's `memory_enabled` is true — the default room follows `{workflow.party_memory}`, a named group its own `memory` flag (both resolved by `resolve_party.py`); ad-hoc inline casts have none. Read on entry and on any mid-session room switch; write through the session.
|
||||||
|
|
||||||
|
## Where it lives
|
||||||
|
|
||||||
|
One memlog per party: `{workflow.memory_dir}/{active}/.memlog.md`, where `{active}` is the key `resolve_party.py` already returned — the group id (e.g. `code-review-crew`), or `installed` for the default room. The folder is named after the party.
|
||||||
|
|
||||||
|
## Read it on entry — distill, don't dump
|
||||||
|
|
||||||
|
The log is append-only and grows every session, so don't pull the raw file into the party. Hand a reader subagent the memlog path (`{workflow.memory_dir}/{active}/.memlog.md`) and have it return a compact brief — a few hundred tokens of *where things stand now*, ready to play in character.
|
||||||
|
|
||||||
|
Then let the brief shape the room from the first beat, **in character**: behavioral state resumes (a cold pair opens cold, an alliance opens warm), threads pick up, callbacks land when they fit — organically, not recited on sight. Never break the fourth wall: the room *remembers*; it never announces it loaded anything, and forces nothing that doesn't fit.
|
||||||
|
|
||||||
|
## When to write
|
||||||
|
|
||||||
|
- **When a memorable beat lands** — a clash that shifts the room's temperature, an alliance forming, a line worth a future callback, a decision, an outcome.
|
||||||
|
- **A floor.** Once a couple of real exchanges are in from the start, even if nothing dramatic happened, capture what it's about and the opening dynamic.
|
||||||
|
|
||||||
|
At wrap-up, if the user does signal done, top up with the final outcome and anything memorable not yet captured.
|
||||||
|
|
||||||
|
Writes are silent. The room never announces "noted" or "I'll remember".
|
||||||
|
|
||||||
|
## What's worth remembering
|
||||||
|
|
||||||
|
The test for every entry: *would this color a future session, or make a callback land, or improve the party?* If not, leave it out. A handful of entries, never a recap, never a transcript. keep each entry as brief as possible but usable by future llm.
|
||||||
|
|
||||||
|
## New faces
|
||||||
|
|
||||||
|
When a character shows up who isn't in the party's roster — cast from an open-cast scene, or one the user adds on the fly — name them in the entry that captures the moment ("<name> turned up and …") so a recurring face can return next session. At wrap-up these are the faces the room offers to keep, saved into the party's roster through `references/create-party.md` (which writes via `bmad-customize`). Until saved they live only in the memlog, and the room re-conjures them from there.
|
||||||
|
|
||||||
|
## Write it
|
||||||
|
|
||||||
|
```
|
||||||
|
uv run {project-root}/_bmad/scripts/memlog.py append \
|
||||||
|
--workspace {workflow.memory_dir}/{active} \
|
||||||
|
--type <dynamic|moment|callback|outcome> \
|
||||||
|
--text "<one succinct line, in the room's own read of it>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Add `--by <persona-code>` when a memory belongs to one character. Choose `init` vs `append` from the existence fact you already hold: the entry-read (and, on a mid-session room switch, that room's read) told you whether the memlog exists — `init --workspace {workflow.memory_dir}/{active}` once before the first append when it doesn't, plain `append` when it does. (`init` errors if the file already exists, so don't call it blind.)
|
||||||
|
|
||||||
|
If `memlog.py` is unavailable or a write errors, skip it silently and never stall the party on a failed write.
|
||||||
|
|
||||||
|
## Forget
|
||||||
|
|
||||||
|
The memlog is append-only by design — no surgical delete. To wipe a party's memory, delete its folder (`{workflow.memory_dir}/{active}/`). To correct a wrong memory, append a new entry that supersedes it; the room reads the latest state.
|
||||||
|
|
||||||
|
Keep entries sparse. The distilled read keeps the *room* lean no matter how big the log gets, but the on-disk file still grows append-only.
|
||||||
|
|
@ -0,0 +1,272 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# /// script
|
||||||
|
# requires-python = ">=3.11"
|
||||||
|
# ///
|
||||||
|
"""Resolve the party-mode roster, lazily.
|
||||||
|
|
||||||
|
Merges the installed BMAD agents with the user's custom `party_members`
|
||||||
|
into one collective, then projects only what the moment needs:
|
||||||
|
|
||||||
|
* default (no flag) — the active roster to load on entry: the
|
||||||
|
`default_party` group if one is configured, else the whole collective.
|
||||||
|
Other groups come back as names only, so nothing you aren't using is
|
||||||
|
loaded into the party.
|
||||||
|
* --list-groups — just id + name + size for every configured group. The
|
||||||
|
cheap menu for "which room?", with no member detail.
|
||||||
|
* --party <id> — full member detail for one chosen group, on demand
|
||||||
|
(e.g. when the user switches rooms). Unknown id returns the available
|
||||||
|
names instead of an error wall.
|
||||||
|
|
||||||
|
The merge is deterministic (a keyed union; a custom member whose code
|
||||||
|
matches an installed agent overrides it), so the orchestrator consumes a
|
||||||
|
resolved roster instead of re-deriving it every session.
|
||||||
|
|
||||||
|
Stdlib only (Python 3.11+ for tomllib). Shells out to the project's
|
||||||
|
resolve_config.py and resolve_customization.py; falls back to reading
|
||||||
|
customize.toml directly if the customization resolver is unavailable.
|
||||||
|
|
||||||
|
resolve_party.py --project-root P --skill S
|
||||||
|
resolve_party.py --project-root P --skill S --list-groups
|
||||||
|
resolve_party.py --project-root P --skill S --party writers-room
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
try:
|
||||||
|
import tomllib
|
||||||
|
except ImportError: # pragma: no cover - guarded for <3.11
|
||||||
|
sys.stderr.write("error: Python 3.11+ is required (stdlib `tomllib`).\n")
|
||||||
|
sys.exit(3)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_json(cmd):
|
||||||
|
"""Run a resolver script and parse its JSON stdout. None on any failure."""
|
||||||
|
try:
|
||||||
|
out = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
||||||
|
except (OSError, subprocess.SubprocessError):
|
||||||
|
return None
|
||||||
|
if out.returncode != 0 or not out.stdout.strip():
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return json.loads(out.stdout)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def load_agents(project_root: Path):
|
||||||
|
"""Installed agents as {code: entry}. Empty dict (with a flag) on failure."""
|
||||||
|
script = project_root / "_bmad" / "scripts" / "resolve_config.py"
|
||||||
|
data = _run_json([sys.executable, str(script), "--project-root", str(project_root), "--key", "agents"])
|
||||||
|
if data is None:
|
||||||
|
return {}, False
|
||||||
|
return data.get("agents", {}) or {}, True
|
||||||
|
|
||||||
|
|
||||||
|
def load_workflow(project_root: Path, skill_root: Path):
|
||||||
|
"""Merged [workflow] table. Falls back to the skill's base customize.toml."""
|
||||||
|
script = project_root / "_bmad" / "scripts" / "resolve_customization.py"
|
||||||
|
data = _run_json([sys.executable, str(script), "--skill", str(skill_root), "--key", "workflow"])
|
||||||
|
if data is not None and "workflow" in data:
|
||||||
|
return data["workflow"]
|
||||||
|
# Fallback: read the skill's base customize.toml directly (no override merge).
|
||||||
|
toml_path = skill_root / "customize.toml"
|
||||||
|
if toml_path.exists():
|
||||||
|
try:
|
||||||
|
with toml_path.open("rb") as f:
|
||||||
|
return tomllib.load(f).get("workflow", {})
|
||||||
|
except (OSError, tomllib.TOMLDecodeError):
|
||||||
|
pass
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def _alias(code: str) -> str:
|
||||||
|
"""Short alias for an installed agent code: bmad-agent-analyst -> analyst."""
|
||||||
|
for prefix in ("bmad-agent-", "bmad-"):
|
||||||
|
if code.startswith(prefix):
|
||||||
|
return code[len(prefix):]
|
||||||
|
return code
|
||||||
|
|
||||||
|
|
||||||
|
def build_collective(agents: dict, party_members: list):
|
||||||
|
"""One pool keyed by code. Custom members override matching installed agents.
|
||||||
|
|
||||||
|
Returns (collective, index, installed_codes):
|
||||||
|
* collective — every member (installed + custom), the pool groups draw
|
||||||
|
from and the orchestrator can summon by name.
|
||||||
|
* index — maps every resolvable token (code, prefix-stripped alias,
|
||||||
|
lower-cased name) to a canonical code.
|
||||||
|
* installed_codes — the codes occupying an installed-agent slot, in
|
||||||
|
order. This is the DEFAULT room: installed agents (with any custom
|
||||||
|
override applied in place), and NOT the pure-custom additions. So
|
||||||
|
shipping or defining custom members grows the pool without crowding
|
||||||
|
the default party.
|
||||||
|
"""
|
||||||
|
collective = {}
|
||||||
|
index = {}
|
||||||
|
installed_codes = []
|
||||||
|
|
||||||
|
def register(code, entry):
|
||||||
|
collective[code] = entry
|
||||||
|
index[code] = code
|
||||||
|
index[code.lower()] = code
|
||||||
|
index[_alias(code).lower()] = code
|
||||||
|
name = entry.get("name")
|
||||||
|
if name:
|
||||||
|
index[name.lower()] = code
|
||||||
|
|
||||||
|
for code, info in agents.items():
|
||||||
|
register(code, {
|
||||||
|
"code": code,
|
||||||
|
"name": info.get("name", code),
|
||||||
|
"icon": info.get("icon", ""),
|
||||||
|
"title": info.get("title", ""),
|
||||||
|
"description": info.get("description", ""),
|
||||||
|
"module": info.get("module", ""),
|
||||||
|
"team": info.get("team", ""),
|
||||||
|
"source": "installed",
|
||||||
|
})
|
||||||
|
installed_codes.append(code)
|
||||||
|
|
||||||
|
for m in party_members or []:
|
||||||
|
code = m.get("code")
|
||||||
|
if not code:
|
||||||
|
continue
|
||||||
|
# A custom member overrides an installed agent it matches by code/alias/name.
|
||||||
|
canonical = index.get(code) or index.get(code.lower()) or code
|
||||||
|
entry = {"code": canonical, "source": "custom"}
|
||||||
|
for field in ("name", "icon", "title", "persona", "capabilities", "model"):
|
||||||
|
if m.get(field) is not None:
|
||||||
|
entry[field] = m[field]
|
||||||
|
entry.setdefault("name", canonical)
|
||||||
|
register(canonical, entry)
|
||||||
|
# An override keeps the installed slot; a brand-new custom does not join it.
|
||||||
|
|
||||||
|
return collective, index, installed_codes
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_members(member_tokens, collective, index):
|
||||||
|
"""(resolved entries in listed order, unresolved tokens)."""
|
||||||
|
resolved, unresolved = [], []
|
||||||
|
for token in member_tokens or []:
|
||||||
|
code = index.get(token) or index.get(str(token).lower())
|
||||||
|
if code and code in collective:
|
||||||
|
resolved.append(collective[code])
|
||||||
|
else:
|
||||||
|
unresolved.append(token)
|
||||||
|
return resolved, unresolved
|
||||||
|
|
||||||
|
|
||||||
|
def group_menu(groups):
|
||||||
|
"""Names only — the cheap menu. Open-cast groups (no roster) are flagged."""
|
||||||
|
out = []
|
||||||
|
for g in groups or []:
|
||||||
|
if not isinstance(g, dict) or not g.get("id"):
|
||||||
|
continue
|
||||||
|
members = g.get("members", []) or []
|
||||||
|
entry = {"id": g["id"], "name": g.get("name", g["id"]),
|
||||||
|
"member_count": len(members)}
|
||||||
|
if not members:
|
||||||
|
entry["open_cast"] = True
|
||||||
|
out.append(entry)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def find_group(groups, group_id):
|
||||||
|
for g in groups or []:
|
||||||
|
if isinstance(g, dict) and g.get("id") == group_id:
|
||||||
|
return g
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def group_detail(g, collective, index):
|
||||||
|
"""Full detail for one group: resolved members + the optional scene.
|
||||||
|
|
||||||
|
`scene` is a freeform line the orchestrator plays — setting, what's
|
||||||
|
happening, room dynamics, in-the-moment character notes. Surfaced only
|
||||||
|
here (when a group is the active/chosen roster), never in the menu.
|
||||||
|
|
||||||
|
`members` is optional. With none, the group is open-cast: `open_cast`
|
||||||
|
is flagged and the scene describes the pool the orchestrator casts from
|
||||||
|
on the fly (e.g. "figures from the Star Wars Rebels universe"). A few
|
||||||
|
listed members anchor the room; the scene can still invite more.
|
||||||
|
"""
|
||||||
|
raw_members = g.get("members", []) or []
|
||||||
|
members, unresolved = resolve_members(raw_members, collective, index)
|
||||||
|
detail = {"active": g["id"], "name": g.get("name", g["id"]),
|
||||||
|
"members": members, "unresolved": unresolved,
|
||||||
|
"memory_enabled": bool(g.get("memory", False))}
|
||||||
|
if g.get("scene"):
|
||||||
|
detail["scene"] = g["scene"]
|
||||||
|
if not raw_members:
|
||||||
|
detail["open_cast"] = True
|
||||||
|
return detail
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser(description="Resolve the party-mode roster, lazily.")
|
||||||
|
ap.add_argument("--project-root", required=True)
|
||||||
|
ap.add_argument("--skill", required=True, help="Path to the bmad-party-mode skill dir")
|
||||||
|
ap.add_argument("--party", help="Resolve full detail for this group id")
|
||||||
|
ap.add_argument("--list-groups", action="store_true", help="Group names only")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
project_root = Path(args.project_root).resolve()
|
||||||
|
skill_root = Path(args.skill).resolve()
|
||||||
|
|
||||||
|
workflow = load_workflow(project_root, skill_root)
|
||||||
|
groups = workflow.get("party_groups", []) or []
|
||||||
|
default_party = workflow.get("default_party", "") or ""
|
||||||
|
party_mode = workflow.get("party_mode", "session") or "session"
|
||||||
|
# The global party_memory flag governs only the DEFAULT installed-agent room;
|
||||||
|
# a named group carries its own `memory` flag (resolved in group_detail).
|
||||||
|
party_memory = bool(workflow.get("party_memory", True))
|
||||||
|
|
||||||
|
# Group menu never needs the (more expensive) installed-agent resolve.
|
||||||
|
if args.list_groups:
|
||||||
|
_emit({
|
||||||
|
"party_mode": party_mode,
|
||||||
|
"default_party": default_party,
|
||||||
|
"groups": group_menu(groups),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
|
||||||
|
agents, agents_ok = load_agents(project_root)
|
||||||
|
collective, index, installed_codes = build_collective(agents, workflow.get("party_members", []))
|
||||||
|
|
||||||
|
if args.party:
|
||||||
|
g = find_group(groups, args.party)
|
||||||
|
if g is None:
|
||||||
|
_emit({"error": "unknown_group", "requested": args.party,
|
||||||
|
"available": group_menu(groups)})
|
||||||
|
return
|
||||||
|
_emit({**group_detail(g, collective, index), "party_mode": party_mode})
|
||||||
|
return
|
||||||
|
|
||||||
|
# Default: the active roster to load on entry.
|
||||||
|
result = {"party_mode": party_mode, "groups": group_menu(groups),
|
||||||
|
"installed_agents_resolved": agents_ok}
|
||||||
|
g = find_group(groups, default_party) if default_party else None
|
||||||
|
if g is not None:
|
||||||
|
result.update(group_detail(g, collective, index))
|
||||||
|
else:
|
||||||
|
# No default group: the installed agents (custom additions stay in the
|
||||||
|
# pool but don't crowd the default room), exactly like a plain install.
|
||||||
|
result.update({"active": "installed",
|
||||||
|
"members": [collective[c] for c in installed_codes],
|
||||||
|
"memory_enabled": party_memory})
|
||||||
|
_emit(result)
|
||||||
|
|
||||||
|
|
||||||
|
def _emit(obj):
|
||||||
|
reconfigure = getattr(sys.stdout, "reconfigure", None)
|
||||||
|
if reconfigure is not None:
|
||||||
|
reconfigure(encoding="utf-8")
|
||||||
|
sys.stdout.write(json.dumps(obj, indent=2, ensure_ascii=False) + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# /// script
|
||||||
|
# requires-python = ">=3.11"
|
||||||
|
# ///
|
||||||
|
"""Unit tests for resolve_party.py — merge, alias, override, group resolution."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||||
|
import resolve_party as rp # noqa: E402
|
||||||
|
|
||||||
|
AGENTS = {
|
||||||
|
"bmad-agent-analyst": {"name": "Mary", "icon": "📊", "title": "Analyst"},
|
||||||
|
"bmad-agent-pm": {"name": "John", "icon": "📋", "title": "PM"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestAlias(unittest.TestCase):
|
||||||
|
def test_strips_known_prefixes(self):
|
||||||
|
self.assertEqual(rp._alias("bmad-agent-analyst"), "analyst")
|
||||||
|
self.assertEqual(rp._alias("bmad-foo"), "foo")
|
||||||
|
|
||||||
|
def test_passes_through_unprefixed(self):
|
||||||
|
self.assertEqual(rp._alias("morpheus"), "morpheus")
|
||||||
|
|
||||||
|
|
||||||
|
class TestBuildCollective(unittest.TestCase):
|
||||||
|
def test_installed_agents_indexed_by_code_alias_and_name(self):
|
||||||
|
col, idx, _ = rp.build_collective(AGENTS, [])
|
||||||
|
self.assertEqual(set(col), {"bmad-agent-analyst", "bmad-agent-pm"})
|
||||||
|
self.assertEqual(idx["analyst"], "bmad-agent-analyst") # alias
|
||||||
|
self.assertEqual(idx["mary"], "bmad-agent-analyst") # name (ci)
|
||||||
|
self.assertEqual(idx["bmad-agent-pm"], "bmad-agent-pm") # full code
|
||||||
|
self.assertEqual(col["bmad-agent-analyst"]["source"], "installed")
|
||||||
|
|
||||||
|
def test_custom_member_appends(self):
|
||||||
|
col, _, _ = rp.build_collective(AGENTS, [{"code": "morpheus", "name": "Morpheus", "persona": "riddles"}])
|
||||||
|
self.assertIn("morpheus", col)
|
||||||
|
self.assertEqual(col["morpheus"]["source"], "custom")
|
||||||
|
self.assertEqual(col["morpheus"]["persona"], "riddles")
|
||||||
|
|
||||||
|
def test_custom_overrides_installed_by_alias(self):
|
||||||
|
col, _, _ = rp.build_collective(AGENTS, [{"code": "analyst", "name": "Mary-Custom", "persona": "p"}])
|
||||||
|
# Override lands on the canonical installed code, not a new "analyst" entry.
|
||||||
|
self.assertNotIn("analyst", col)
|
||||||
|
self.assertEqual(col["bmad-agent-analyst"]["source"], "custom")
|
||||||
|
self.assertEqual(col["bmad-agent-analyst"]["name"], "Mary-Custom")
|
||||||
|
|
||||||
|
def test_member_without_code_skipped(self):
|
||||||
|
col, _, _ = rp.build_collective(AGENTS, [{"name": "Nameless"}])
|
||||||
|
self.assertEqual(set(col), {"bmad-agent-analyst", "bmad-agent-pm"})
|
||||||
|
|
||||||
|
|
||||||
|
class TestResolveMembers(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.col, self.idx, _ = rp.build_collective(AGENTS, [{"code": "morpheus", "name": "Morpheus"}])
|
||||||
|
|
||||||
|
def test_resolves_in_listed_order_and_flags_unknowns(self):
|
||||||
|
resolved, unresolved = rp.resolve_members(["morpheus", "analyst", "ghost"], self.col, self.idx)
|
||||||
|
self.assertEqual([m["code"] for m in resolved], ["morpheus", "bmad-agent-analyst"])
|
||||||
|
self.assertEqual(unresolved, ["ghost"])
|
||||||
|
|
||||||
|
def test_empty(self):
|
||||||
|
self.assertEqual(rp.resolve_members([], self.col, self.idx), ([], []))
|
||||||
|
|
||||||
|
|
||||||
|
class TestGroups(unittest.TestCase):
|
||||||
|
GROUPS = [
|
||||||
|
{"id": "wr", "name": "Writers", "members": ["analyst", "morpheus"]},
|
||||||
|
{"id": "bad"}, # no name -> falls back to id; no members -> count 0
|
||||||
|
{"name": "no-id"}, # dropped from menu
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_menu_is_names_only_with_counts_and_open_cast_flag(self):
|
||||||
|
menu = rp.group_menu(self.GROUPS)
|
||||||
|
self.assertEqual(menu, [
|
||||||
|
{"id": "wr", "name": "Writers", "member_count": 2},
|
||||||
|
{"id": "bad", "name": "bad", "member_count": 0, "open_cast": True},
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_find_group(self):
|
||||||
|
self.assertEqual(rp.find_group(self.GROUPS, "wr")["name"], "Writers")
|
||||||
|
self.assertIsNone(rp.find_group(self.GROUPS, "missing"))
|
||||||
|
|
||||||
|
|
||||||
|
class TestGroupDetail(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.col, self.idx, _ = rp.build_collective(AGENTS, [{"code": "morpheus", "name": "Morpheus"}])
|
||||||
|
|
||||||
|
def test_scene_passes_through_when_present(self):
|
||||||
|
g = {"id": "tos-10-forward", "name": "Ten Forward", "members": ["morpheus"],
|
||||||
|
"scene": "Late evening, a few rounds in."}
|
||||||
|
d = rp.group_detail(g, self.col, self.idx)
|
||||||
|
self.assertEqual(d["scene"], "Late evening, a few rounds in.")
|
||||||
|
self.assertEqual([m["code"] for m in d["members"]], ["morpheus"])
|
||||||
|
|
||||||
|
def test_scene_omitted_when_absent_or_empty(self):
|
||||||
|
for g in ({"id": "g", "members": ["morpheus"]},
|
||||||
|
{"id": "g", "members": ["morpheus"], "scene": ""}):
|
||||||
|
self.assertNotIn("scene", rp.group_detail(g, self.col, self.idx))
|
||||||
|
|
||||||
|
def test_anchored_group_is_not_open_cast(self):
|
||||||
|
g = {"id": "g", "members": ["morpheus"]}
|
||||||
|
self.assertNotIn("open_cast", rp.group_detail(g, self.col, self.idx))
|
||||||
|
|
||||||
|
def test_open_cast_group_flagged_with_empty_members(self):
|
||||||
|
g = {"id": "rebels", "name": "Star Wars Rebels",
|
||||||
|
"scene": "Figures from the Rebels universe drop in as the topic calls for them."}
|
||||||
|
d = rp.group_detail(g, self.col, self.idx)
|
||||||
|
self.assertTrue(d["open_cast"])
|
||||||
|
self.assertEqual(d["members"], [])
|
||||||
|
self.assertEqual(d["scene"][:7], "Figures")
|
||||||
|
|
||||||
|
def test_memory_enabled_follows_group_flag_and_defaults_off(self):
|
||||||
|
on = rp.group_detail({"id": "g", "members": ["morpheus"], "memory": True}, self.col, self.idx)
|
||||||
|
self.assertTrue(on["memory_enabled"])
|
||||||
|
off = rp.group_detail({"id": "g", "members": ["morpheus"], "memory": False}, self.col, self.idx)
|
||||||
|
self.assertFalse(off["memory_enabled"])
|
||||||
|
absent = rp.group_detail({"id": "g", "members": ["morpheus"]}, self.col, self.idx)
|
||||||
|
self.assertFalse(absent["memory_enabled"]) # opt-in per named group
|
||||||
|
|
||||||
|
|
||||||
|
class TestInstalledCodesIsDefaultRoom(unittest.TestCase):
|
||||||
|
"""The default room is installed agents only; pure customs stay in the pool."""
|
||||||
|
|
||||||
|
def test_pure_custom_excluded_override_kept_in_default_room(self):
|
||||||
|
col, _, installed = rp.build_collective(AGENTS, [
|
||||||
|
{"code": "morpheus", "name": "Morpheus"}, # pure custom
|
||||||
|
{"code": "analyst", "name": "Mary-Custom", "persona": "p"}, # override
|
||||||
|
{"code": "sec-hawk", "name": "Vex"}, # shipped crew member
|
||||||
|
])
|
||||||
|
# Pure customs are in the pool...
|
||||||
|
self.assertIn("morpheus", col)
|
||||||
|
self.assertIn("sec-hawk", col)
|
||||||
|
# ...but NOT in the default room.
|
||||||
|
self.assertEqual(installed, ["bmad-agent-analyst", "bmad-agent-pm"])
|
||||||
|
default_room = [col[c]["code"] for c in installed]
|
||||||
|
self.assertEqual(default_room, ["bmad-agent-analyst", "bmad-agent-pm"])
|
||||||
|
# An override keeps its installed slot (and its custom content).
|
||||||
|
self.assertEqual(col["bmad-agent-analyst"]["name"], "Mary-Custom")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
|
|
@ -18,7 +18,7 @@ Multiple skills may call to update the same spec over time.
|
||||||
|
|
||||||
## On Activation
|
## On Activation
|
||||||
|
|
||||||
1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly.
|
1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly.
|
||||||
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (`file:` entries are loaded).
|
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (`file:` entries are loaded).
|
||||||
3. Load `{project-root}/_bmad/core/config.yaml` (and `config.user.yaml` if present), root level and `bmm` section. Resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`.
|
3. Load `{project-root}/_bmad/core/config.yaml` (and `config.user.yaml` if present), root level and `bmm` section. Resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`.
|
||||||
4. Detect mode. **Headless** when any of: no TTY, programmatic caller (another skill or non-interactive runner), or the first message pre-supplies all inputs and asks for an artifact path back. **Interactive** otherwise. In interactive mode, greet by `{user_name}` in `{communication_language}`, stay in that language, and mention that `bmad-party-mode` and `bmad-advanced-elicitation` are available for deeper exploration on any field.
|
4. Detect mode. **Headless** when any of: no TTY, programmatic caller (another skill or non-interactive runner), or the first message pre-supplies all inputs and asks for an artifact path back. **Interactive** otherwise. In interactive mode, greet by `{user_name}` in `{communication_language}`, stay in that language, and mention that `bmad-party-mode` and `bmad-advanced-elicitation` are available for deeper exploration on any field.
|
||||||
|
|
@ -57,8 +57,8 @@ Deriving the contract from a living log instead of editing the contract in place
|
||||||
|
|
||||||
Writes go through the shared script — `{project-root}/_bmad/scripts/memlog.py`, the same location as `resolve_customization.py` (atomic; never read it back except to resume):
|
Writes go through the shared script — `{project-root}/_bmad/scripts/memlog.py`, the same location as `resolve_customization.py` (atomic; never read it back except to resume):
|
||||||
|
|
||||||
- `python3 {project-root}/_bmad/scripts/memlog.py init --workspace {spec-folder} --field topic="<what is being specced>"` — once, at create.
|
- `uv run {project-root}/_bmad/scripts/memlog.py init --workspace {spec-folder} --field topic="<what is being specced>"` — once, at create.
|
||||||
- `python3 {project-root}/_bmad/scripts/memlog.py append --workspace {spec-folder} --type <decision|constraint|capability|assumption|question|direction|note|event> --text "<one-line gist, reason included>"` — as each lands.
|
- `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {spec-folder} --type <decision|constraint|capability|assumption|question|direction|note|event> --text "<one-line gist, reason included>"` — as each lands.
|
||||||
- Terminal moments (a validation verdict, "spec finalized") are `--type event` entries; the memlog carries no status field.
|
- Terminal moments (a validation verdict, "spec finalized") are `--type event` entries; the memlog carries no status field.
|
||||||
|
|
||||||
## The Operation
|
## The Operation
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ Name which (or which combination) applies, who is affected, and the backdrop tha
|
||||||
|
|
||||||
## Capabilities
|
## Capabilities
|
||||||
|
|
||||||
- id: CAP-1
|
- **CAP-1**
|
||||||
intent: {One sentence. "User or system can do X to achieve Y." WHAT, not HOW.}
|
- **intent:** {One sentence. "User or system can do X to achieve Y." WHAT, not HOW.}
|
||||||
success: {Testable or demonstrable criterion. Something a test or a real demonstration can decide.}
|
- **success:** {Testable or demonstrable criterion. Something a test or a real demonstration can decide.}
|
||||||
|
|
||||||
## Constraints
|
## Constraints
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3456,6 +3456,125 @@ async function runTests() {
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Test Suite 47: WSL shell using Windows Node guard
|
||||||
|
// ============================================================
|
||||||
|
console.log(`${colors.yellow}Test Suite 47: WSL Windows Node guard${colors.reset}\n`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const wslNodeCheck = require('../tools/installer/core/wsl-node-check');
|
||||||
|
|
||||||
|
let detection = wslNodeCheck.detectWindowsNodeFromWsl({
|
||||||
|
platform: 'win32',
|
||||||
|
env: { WSL_DISTRO_NAME: 'Ubuntu-26.04' },
|
||||||
|
cwd: String.raw`C:\Windows`,
|
||||||
|
execPath: String.raw`C:\Program Files\nodejs\node.exe`,
|
||||||
|
});
|
||||||
|
assert(detection.isMismatch === true, 'detects Windows Node launched from WSL via WSL_DISTRO_NAME');
|
||||||
|
|
||||||
|
detection = wslNodeCheck.detectWindowsNodeFromWsl({
|
||||||
|
platform: 'win32',
|
||||||
|
env: { PWD: '/home/devuser/projects/md2pdf' },
|
||||||
|
cwd: String.raw`\\wsl.localhost\Ubuntu-26.04\home\devuser\projects\md2pdf`,
|
||||||
|
execPath: String.raw`C:\Program Files\nodejs\node.exe`,
|
||||||
|
});
|
||||||
|
assert(detection.isMismatch === true, 'detects Windows Node launched from WSL via Linux PWD / WSL UNC cwd');
|
||||||
|
|
||||||
|
detection = wslNodeCheck.detectWindowsNodeFromWsl({
|
||||||
|
platform: 'win32',
|
||||||
|
env: {},
|
||||||
|
cwd: String.raw`\\wsl$\Ubuntu-26.04\home\devuser\projects\md2pdf`,
|
||||||
|
execPath: String.raw`C:\Program Files\nodejs\node.exe`,
|
||||||
|
});
|
||||||
|
assert(detection.isMismatch === true, 'detects Windows Node launched from WSL via legacy WSL UNC cwd');
|
||||||
|
|
||||||
|
detection = wslNodeCheck.detectWindowsNodeFromWsl({
|
||||||
|
platform: 'linux',
|
||||||
|
env: { WSL_DISTRO_NAME: 'Ubuntu-26.04', PWD: '/home/devuser/projects/md2pdf' },
|
||||||
|
cwd: '/home/devuser/projects/md2pdf',
|
||||||
|
execPath: '/usr/bin/node',
|
||||||
|
});
|
||||||
|
assert(detection.isMismatch === false, 'allows native Linux Node inside WSL');
|
||||||
|
|
||||||
|
detection = wslNodeCheck.detectWindowsNodeFromWsl({
|
||||||
|
platform: 'win32',
|
||||||
|
env: { PWD: String.raw`C:\Users\devuser\project` },
|
||||||
|
cwd: String.raw`C:\Users\devuser\project`,
|
||||||
|
execPath: String.raw`C:\Program Files\nodejs\node.exe`,
|
||||||
|
});
|
||||||
|
assert(detection.isMismatch === false, 'allows normal Windows Node outside WSL');
|
||||||
|
|
||||||
|
detection = wslNodeCheck.detectWindowsNodeFromWsl({
|
||||||
|
platform: 'win32',
|
||||||
|
env: { PWD: '/c/Users/devuser/project' },
|
||||||
|
cwd: String.raw`C:\Users\devuser\project`,
|
||||||
|
execPath: String.raw`C:\Program Files\nodejs\node.exe`,
|
||||||
|
});
|
||||||
|
assert(detection.isMismatch === false, 'allows Git Bash Windows-drive PWD outside WSL');
|
||||||
|
|
||||||
|
detection = wslNodeCheck.detectWindowsNodeFromWsl({
|
||||||
|
platform: 'win32',
|
||||||
|
env: { PWD: '/cygdrive/c/Users/devuser/project' },
|
||||||
|
cwd: String.raw`C:\Users\devuser\project`,
|
||||||
|
execPath: String.raw`C:\Program Files\nodejs\node.exe`,
|
||||||
|
});
|
||||||
|
assert(detection.isMismatch === false, 'allows Cygwin Windows-drive PWD outside WSL');
|
||||||
|
|
||||||
|
const message = wslNodeCheck.formatWindowsNodeFromWslMessage({
|
||||||
|
isMismatch: true,
|
||||||
|
reason: 'WSL_DISTRO_NAME is set',
|
||||||
|
execPath: String.raw`C:\Program Files\nodejs\node.exe`,
|
||||||
|
});
|
||||||
|
assert(message.includes('Install Node.js inside WSL'), 'guard message tells user to install Node.js inside WSL');
|
||||||
|
assert(message.includes(String.raw`C:\Program Files\nodejs\node.exe`), 'guard message includes detected Windows Node path');
|
||||||
|
|
||||||
|
const promptsModule = require('../tools/installer/prompts');
|
||||||
|
const real = {
|
||||||
|
detectWindowsNodeFromWsl: wslNodeCheck.detectWindowsNodeFromWsl,
|
||||||
|
log: promptsModule.log,
|
||||||
|
exit: process.exit,
|
||||||
|
};
|
||||||
|
const seen = { errors: [], exit: [] };
|
||||||
|
wslNodeCheck.detectWindowsNodeFromWsl = () => ({
|
||||||
|
isMismatch: true,
|
||||||
|
reason: 'WSL_INTEROP is set',
|
||||||
|
execPath: String.raw`C:\Program Files\nodejs\node.exe`,
|
||||||
|
});
|
||||||
|
promptsModule.log = {
|
||||||
|
error: async (m) => void seen.errors.push(m),
|
||||||
|
info: async () => {},
|
||||||
|
success: async () => {},
|
||||||
|
warn: async () => {},
|
||||||
|
message: async () => {},
|
||||||
|
step: async () => {},
|
||||||
|
};
|
||||||
|
process.exit = (code) => {
|
||||||
|
seen.exit.push(code);
|
||||||
|
throw new Error('__stub_exit__');
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
let threw = false;
|
||||||
|
try {
|
||||||
|
await wslNodeCheck.checkWindowsNodeFromWsl();
|
||||||
|
} catch (error) {
|
||||||
|
threw = error.message === '__stub_exit__';
|
||||||
|
}
|
||||||
|
assert(threw && seen.exit[0] === 1, 'guard exits with code 1 when Windows Node is launched from WSL');
|
||||||
|
assert(seen.errors[0].includes('Windows Node.js was launched from a WSL shell'), 'guard logs the mismatch explanation');
|
||||||
|
} finally {
|
||||||
|
wslNodeCheck.detectWindowsNodeFromWsl = real.detectWindowsNodeFromWsl;
|
||||||
|
promptsModule.log = real.log;
|
||||||
|
process.exit = real.exit;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`${colors.red}Test Suite 47 setup failed: ${error.message}${colors.reset}`);
|
||||||
|
console.log(error.stack);
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Summary
|
// Summary
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue