LogoSkills

Phase Gates

BMAD phase gate definitions and verification rules

항ëŠĐë‚īėšĐ
Version1.0.0

Defines the required conditions and verification rules for passing each phase. All gates are mandatory, and the next phase cannot proceed on failure.

Gate Flow#

┌─────────────────────────────────────────────────────────────────┐
│  Mandatory Gate Flow                                                │
├─────────────────────────────────────────────────────────────────â”Ī
│                                                                 │
│  Analysis Gate ──┮─→ ✅ PASS → Planning Gate                   │
│                  └─→ ❌ FAIL → Feedback loop (fix and re-review)      │
│                                                                 │
│  Planning Gate ──┮─→ ✅ PASS → Solutioning Gate                │
│                  └─→ ❌ FAIL → Feedback loop (fix and re-review)      │
│                                                                 │
│  Solutioning Gate ──┮─→ ✅ PASS → Implementation               │
│                     └─→ ❌ FAIL → Feedback loop (fix and re-review)   │
│                                                                 │
│  Implementation Gate ──┮─→ ✅ PASS → Complete                       │
│                        └─→ ❌ FAIL → Feedback loop                 │
│                                                                 │
│  ⚠ïļ Cannot proceed to next phase on gate failure                        │
│  ⚠ïļ Re-review by corresponding persona required after applying feedback                     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Gate 1: Analysis Gate#

Verification Owner#

  • Analyst persona

Required Conditions#

ConditionVerification MethodOn Failure
Requirements clarity Specific and measurable? Requirements need redefinition
Scope appropriateness Appropriate size for single issue? Split or adjustment needed
AC BDD Gherkin format All AC in Given-When-Then format? Rewrite in Gherkin format
AC completeness At least 1 each of happy-path + error-handling? Add scenarios

Verification Logic#

interface AnalysisGateResult {
  pass: boolean;
  checks: {
    requirementClarity: CheckResult;
    scopeAppropriateness: CheckResult;
    acGherkinFormat: CheckResult;   // BDD Gherkin format required
    acCompleteness: CheckResult;    // happy-path + error-handling
  };
  acceptanceCriteria: GherkinFeature;  // Gherkin format AC
  feedback?: string;
}

interface GherkinFeature {
  feature: string;
  scenarios: GherkinScenario[];
}

interface GherkinScenario {
  tag:  ' @happy-path '   |  ' @error-handling '   |  ' @edge-case ' ;
  name: string;
  given: string[];
  when: string[];
  then: string[];
}

function validateAnalysisGate(analysis: AnalysisOutput): AnalysisGateResult {
  const checks = {
    requirementClarity: checkRequirementClarity(analysis),
    scopeAppropriateness: checkScopeAppropriateness(analysis),
    acGherkinFormat: checkACGherkinFormat(analysis),  // Given-When-Then format validation
    acCompleteness: checkACCompleteness(analysis),    // Validate scenarios exist per tag
  };

  const pass = Object.values(checks).every(c = >   c.status ===  " pass " );

  return {
    pass,
    checks,
    acceptanceCriteria: analysis.acceptanceCriteria,
    feedback: pass ? undefined : generateFeedback(checks),
  };
}

// BDD Gherkin format validation
function checkACGherkinFormat(analysis: AnalysisOutput): CheckResult {
  const scenarios = analysis.acceptanceCriteria.scenarios;
  const allValid = scenarios.every(s = > 
     s.given.length  >   0  & &   s.when.length  >   0  & &   s.then.length  >   0
  );
  return {
    status: allValid ?  ' pass '   :  ' fail ' ,
    message: allValid
      ?  ' All AC written in Given-When-Then format ' 
       :  ' AC not in Gherkin format. Rewrite in Given-When-Then required ' ,
  };
}

// AC completeness validation
function checkACCompleteness(analysis: AnalysisOutput): CheckResult {
  const scenarios = analysis.acceptanceCriteria.scenarios;
  const hasHappyPath = scenarios.some(s = >   s.tag ===  ' @happy-path ' );
  const hasErrorHandling = scenarios.some(s = >   s.tag ===  ' @error-handling ' );

  const pass = hasHappyPath  & &   hasErrorHandling;
  return {
    status: pass ?  ' pass '   :  ' fail ' ,
    message: pass
      ? `@happy-path: ${scenarios.filter(s = >   s.tag ===  ' @happy-path ' ).length}, @error-handling: ${scenarios.filter(s = >   s.tag ===  ' @error-handling ' ).length}`
      : `Required scenario missing: ${!hasHappyPath ?  ' @happy-path  '   :  ' ' }${!hasErrorHandling ?  ' @error-handling '   :  ' ' }`,
  };
}

Output Format#

╔════════════════════════════════════════════════════════════════╗
║  Analysis Gate: {PASS | FAIL}                                  ║
╠════════════════════════════════════════════════════════════════â•Ģ
║                                                                ║
║  ✅ Requirements clarity: PASS                                       ║
║     - 3 functional requirements identified                                    ║
║     - Success criteria clear                                           ║
║                                                                ║
║  ✅ Scope appropriateness: PASS                                         ║
║     - Expected complexity: Medium (3-5 SP)                               ║
║     - Appropriate for a single issue                                         ║
║                                                                ║
║  ✅ AC BDD Gherkin format: PASS                                  ║
║     - All AC written in Given-When-Then format                   ║
║                                                                ║
║  ✅ AC completeness: PASS                                        ║
║     - @happy-path: 2                                            ║
║     - @error-handling: 1                                        ║
║                                                                ║
╚════════════════════════════════════════════════════════════════╝

📋 Acceptance Criteria (BDD Gherkin):

Feature: Author list screen

  @happy-path
  Scenario: Author list pagination display
    Given I am on the author list screen
    When the screen loads
    Then 20 authors per page are displayed
    And pagination is displayed

  @happy-path
  Scenario: Search authors by name
    Given the author  " Kim Cheolsu "   is registered
    When I enter  " Kim Cheolsu "   in the search field
    Then the search results include  " Kim Cheolsu " 

   @error-handling
  Scenario: No search results
    Given the author list exists
    When I search for a non-existent name
    Then the message  " No search results "   is displayed

Plan Quality Scoring (Analysis Gate Extension)#

When the Analysis Gate is used within the pipeline (/project:plan), an additional Plan Quality Score is computed to ensure the plan document itself is implementation-ready.

Scoring Dimensions

DimensionWeightDescriptionPass Threshold
clarity 0.25 Can an implementer understand without ambiguity? â‰Ĩ 0.6
completeness 0.25 Are all Acceptance Criteria covered in the plan? â‰Ĩ 0.6
specificity 0.20 Does the plan reference specific files/classes/methods? â‰Ĩ 0.6
yagni_compliance 0.15 Are there unnecessary features or premature abstractions? â‰Ĩ 0.6
scope_appropriateness 0.15 Is the scope appropriate for a single PR? â‰Ĩ 0.6

Overall pass threshold: Weighted total â‰Ĩ 0.8

Verification Logic

interface PlanQualityScore {
  clarity: number;           // 0.0 - 1.0
  completeness: number;      // 0.0 - 1.0
  specificity: number;       // 0.0 - 1.0
  yagniCompliance: number;   // 0.0 - 1.0
  scopeAppropriateness: number; // 0.0 - 1.0
  weightedTotal: number;     // Weighted sum
  pass: boolean;             // weightedTotal â‰Ĩ 0.8  & &   all dimensions â‰Ĩ 0.6
}

function scorePlanQuality(plan: PlanDocument): PlanQualityScore {
  const weights = {
    clarity: 0.25,
    completeness: 0.25,
    specificity: 0.20,
    yagniCompliance: 0.15,
    scopeAppropriateness: 0.15,
  };

  const scores = {
    clarity: assessClarity(plan),
    completeness: assessCompleteness(plan),
    specificity: assessSpecificity(plan),
    yagniCompliance: assessYagni(plan),
    scopeAppropriateness: assessScope(plan),
  };

  const weightedTotal = Object.entries(weights).reduce(
    (sum, [key, weight]) = >   sum + scores[key] * weight, 0
  );

  const allAboveMin = Object.values(scores).every(s = >   s  > = 0.6);

  return { ...scores, weightedTotal, pass: weightedTotal  > = 0.8  & &   allAboveMin };
}

Scoring Guidelines

Clarity (0.25):

  • 1.0: Every requirement has unambiguous acceptance criteria with measurable outcomes
  • 0.7: Most requirements are clear, minor ambiguities remain
  • 0.4: Several requirements use vague language ("appropriate", "good performance")
  • 0.0: Requirements are mostly abstract or contradictory

Completeness (0.25):

  • 1.0: Every AC scenario has a corresponding implementation task in the plan
  • 0.7: Most scenarios covered, minor gaps in edge cases
  • 0.4: Happy path covered but error/edge cases missing
  • 0.0: Significant AC scenarios have no corresponding plan tasks

Specificity (0.20):

  • 1.0: References specific file paths, class names, method signatures
  • 0.7: References layers/modules but not exact files
  • 0.4: Generic descriptions ("update the service layer")
  • 0.0: No technical detail at all

YAGNI Compliance (0.15):

  • 1.0: Every planned feature directly maps to a current requirement
  • 0.7: Minor abstractions that may not be needed yet
  • 0.4: Includes "future-proofing" features or speculative interfaces
  • 0.0: Significant over-engineering or hypothetical features

Scope Appropriateness (0.15):

  • 1.0: Clearly a single PR, touches one logical area
  • 0.7: Single PR feasible but touches multiple areas
  • 0.4: Should probably be split into 2-3 PRs
  • 0.0: Far too large, needs significant decomposition

Output Format

╔════════════════════════════════════════════════════════════════╗
║  Plan Quality Score: {PASS | FAIL}  (Total: {score}/1.0)      ║
╠════════════════════════════════════════════════════════════════â•Ģ
║                                                                ║
║  Clarity:              {score} {✅|❌}  (weight: 0.25)         ║
║  Completeness:         {score} {✅|❌}  (weight: 0.25)         ║
║  Specificity:          {score} {✅|❌}  (weight: 0.20)         ║
║  YAGNI Compliance:     {score} {✅|❌}  (weight: 0.15)         ║
║  Scope Appropriateness:{score} {✅|❌}  (weight: 0.15)         ║
║                                                                ║
║  Weighted Total: {total}  (threshold: 0.8)                     ║
║                                                                ║
║  {feedback if failed}                                          ║
╚════════════════════════════════════════════════════════════════╝

Gate 2: Planning Gate#

Verification Owner#

  • Product Manager persona

Required Conditions#

ConditionVerification MethodOn Failure
Epic/Story structureAppropriate hierarchy?Structure redesign needed
Story PointWithin 1-8 SP range?Re-estimate or split needed
LabelingType, Scope labels present?Labels need to be added
DependenciesAre blockers resolvable?Dependencies need resolution

Verification Logic#

interface PlanningGateResult {
  pass: boolean;
  checks: {
    epicStoryStructure: CheckResult;
    storyPoint: CheckResult;
    labeling: CheckResult;
    dependencies: CheckResult;
  };
  issue: IssueInfo;
  feedback?: string;
}

function validatePlanningGate(planning: PlanningOutput): PlanningGateResult {
  const checks = {
    epicStoryStructure: checkEpicStoryStructure(planning),
    storyPoint: checkStoryPoint(planning),  // 1-8 range
    labeling: checkLabeling(planning),  // Type, Scope required
    dependencies: checkDependencies(planning),  // No blockers or resolvable
  };

  const pass = Object.values(checks).every(c = >   c.status ===  " pass " );

  return {
    pass,
    checks,
    issue: planning.issue,
    feedback: pass ? undefined : generateFeedback(checks),
  };
}

Story Point Rules#

PointConditionSplit Needed
1Single file, clear change❌
2-3Multiple files, includes tests❌
5Multiple layers, includes BDD❌
8Full feature + tests❌
13+Too large✅ Split needed

Gate 3: Solutioning Gate#

Verification Owner#

  • Architect + UX Designer (parallel)

Required Conditions#

Architect review

ConditionVerification MethodOn Failure
Clean ArchitectureLayer separation correct?Fix architecture
DI structureInjectable registration complete?Fix DI
API designNaming/error handling standard?Fix API
SecurityAuthentication/authorization appropriate?Fix security

UX Designer review

ConditionVerification MethodOn Failure
CoUI complianceStandard components used?Fix UI
LayoutConsistent spacing/alignment?Fix layout
InteractionLoading/error/empty state handling?Fix UX
AccessibilityWCAG 2.1 AA compliance?Improve accessibility (recommended)

Parallel Verification Logic#

interface SolutioningGateResult {
  pass: boolean;
  architectReview: ArchitectReviewResult;
  uxReview: UXReviewResult;
  feedback?: string;
}

async function validateSolutioningGate(
  solutioning: SolutioningOutput
): Promise < SolutioningGateResult >   {
  // Parallel execution
  const [architectReview, uxReview] = await Promise.all([
    validateArchitectReview(solutioning),
    validateUXReview(solutioning),
  ]);

  // All reviews must pass
  const pass = architectReview.pass  & &   uxReview.pass;

  return {
    pass,
    architectReview,
    uxReview,
    feedback: pass ? undefined : combineFeedback(architectReview, uxReview),
  };
}

Partial Failure Handling#

┌─────────────────────────────────────────────────────────────────┐
│  On Solutioning Gate partial failure                                  │
├─────────────────────────────────────────────────────────────────â”Ī
│                                                                 │
│  Case 1: Only Architect fails                                       │
│  → Keep UX review result, re-review after applying Architect feedback           │
│                                                                 │
│  Case 2: Only UX fails                                              │
│  → Keep Architect result, re-review after applying UX feedback                │
│                                                                 │
│  Case 3: Both fail                                             │
│  → Re-review both after applying all feedback                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Gate 4: Implementation Gate#

Verification Owner#

  • Flutter Developer + Backend Developer + Scrum Master

Required Conditions#

ConditionVerification MethodOn Failure
Branch rulesIs it a feature branch?Recreate branch
Code qualitydart/dcm analyze pass?Fix lint
TestsAll tests pass?Fix tests
Code reviewReview feedback applied?Apply feedback

Sub-Gates#

Step 4 Gate: Branch Verification

# Branch format verification
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ ! $BRANCH =~ ^(feature|fix|refactor|chore)/[0-9]+ ]]; then
  echo  " ❌ Branch format error " 
   exit 1
fi

# Direct commits to development/main prohibited
if [[ $BRANCH ==  " development "   || $BRANCH ==  " main "   ]]; then
  echo  " ❌ Direct commits to development/main prohibited " 
   exit 1
fi

Step 8.5 Gate: Pre-push Lint Verification

# Extract changed files (excluding generated files)
CHANGED_FILES=$(git diff --name-only origin/development...HEAD --  ' *.dart '   | \
  grep -v -E  ' \.(g|freezed|gr|config|module)\.dart$ ' )

# dart + dcm formatting
echo  " $CHANGED_FILES "   | xargs dart format
echo  " $CHANGED_FILES "   | xargs dcm format

# dart fix
dart fix --apply

# Analysis verification
echo  " $CHANGED_FILES "   | xargs dart analyze --no-fatal-infos
echo  " $CHANGED_FILES "   | xargs dcm analyze --no-fatal-style

Step 9 Gate: Pre-PR Creation Verification

interface PRCreationGate {
  branchFormat: boolean;    // feature/{number}-{description} format
  issueLinked: boolean;     // Issue number extractable
  commitsExist: boolean;    // At least 1 commit exists
  lintPassed: boolean;      // Step 8.5 passed
}

Emergency Handling#

Emergency Mode#

# Emergency hotfix (admin approval required)
/dev:run --bmad --emergency  " production outage emergency fix "

In Emergency mode:

  • Analysis, Planning, Solutioning gates streamlined
  • Code review converted to post-review
  • Normal review must follow after merge

Gate Bypass Prohibited#

⚠ïļ Warning: Gate bypass is only permitted in Emergency mode.

When attempting gate bypass in normal mode:
1. Warning message displayed
2. Progression blocked
3. Escalation to responsible persona

Feedback Loop#

Retry Limit ⚠ïļ#

Maximum retry count: 3 (prevents infinite loops)

┌─────────────────────────────────────────────────────────────────┐
│  Retry Limit Policy                                                │
├─────────────────────────────────────────────────────────────────â”Ī
│                                                                 │
│  Attempt 1 → Fail → Feedback provided → Fix                              │
│  Attempt 2 → Fail → Feedback provided → Fix                              │
│  Attempt 3 → Fail → ⛔ Escalation                                 │
│                                                                 │
│  On 3 failures:                                                    │
│  1. Escalate to Scrum Master                               │
│  2. Root cause analysis and resolution required                             │
│  3. Redefine requirements or split task if needed                       │
│                                                                 │
│  Config: bmad.json → feedback.maxRetries: 3                      │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Failure Handling Flow#

Gate failure (attempt N  <   3)
    ↓
Generate feedback
    ↓
Correction guidance
    ↓
User performs corrections
    ↓
Request re-review
    ↓
Re-review by corresponding persona
    ↓
Re-evaluate gate

Gate failure (attempt N = 3)
    ↓
⛔ Escalation
    ↓
Scrum Master intervention
    ↓
Root cause analysis → split or redefine task

Re-review Request#

# Specific persona re-review
/bmad:review --persona architect --retry

# Specific gate re-verification
/bmad:gate --phase solutioning --retry

Metrics Collection#

Gate Pass Rate#

interface GateMetrics {
  phase: string;
  totalAttempts: number;
  passedFirstTime: number;
  passedAfterRetry: number;
  averageRetries: number;
  commonFailureReasons: string[];
}

Monitoring Dashboard#

╔════════════════════════════════════════════════════════════════╗
║  Gate Metrics (Last 30 Days)                                      ║
╠════════════════════════════════════════════════════════════════â•Ģ
║                                                                ║
║  Analysis Gate:     92% first-attempt pass                           ║
║  Planning Gate:     88% first-attempt pass                           ║
║  Solutioning Gate:  75% first-attempt pass                           ║
║  Implementation:    85% first-attempt pass                           ║
║                                                                ║
║  Top failure reasons:                                               ║
║  1. Clean Architecture violation (25%)                              ║
║  2. Lint errors (20%)                                            ║
║  3. Unclear AC (15%)                                            ║
║                                                                ║
╚════════════════════════════════════════════════════════════════╝

  • .claude/orchestrators/bmad-orchestrator.md - Main orchestrator
  • .claude/personas/ - Review criteria for each persona
  • .claude/skills/dev/SKILL.md - Existing workflow integration