# PM Planning Steps Reference

**This file is referenced by the Project Manager agent. Do not modify without updating the PM agent.**

---

## Step 0: Development Plan Management (FIRST ACTION)

**Query current session's plan:**

Invoke skill: `Skill(command: "bazinga-db-workflow")`

Provide request:
```
bazinga-db-workflow, please get the development plan:

Session ID: {session_id}
```

**Handle response:**

**IF plan found → CONTINUATION MODE:**
- Parse: original_prompt, phases[], current_phase, metadata
- Map user request to phases (e.g., "Phase 2" → phases[1])
- Output: `📋 Plan: {total}-phase | Phase 1✓ Phase 2→ Phase 3⏸`
- Jump to Step 1 with plan context

**IF no plan found → CHECK FOR ORPHANED PLANS:**

User request contains phase references ("Phase", "phase", "Step")? If yes:

*New sessions may lose plan context. Search recent sessions:*

Invoke: `Skill(command: "bazinga-db-core")`
```
bazinga-db-core, please list the most recent sessions (limit 5).
```

For each recent session (last 24h), query its plan. If plan found with matching phase names:
- Show user: `📋 Found plan from {prev_session} | Continue it? (assuming yes)`
- Load plan, update session_id to current
- Continue in CONTINUATION MODE

**IF still no plan → PLAN CREATION MODE:**

Detect plan type:
1. **User-provided plan:** Explicit "Phase 1:", "Step 1:", numbered items + scope keywords ("only", "for now", "start with")
2. **PM-generated plan:** Complex work (will need >2 task groups) → break into phases

**Save plan:**

Invoke: `Skill(command: "bazinga-db-workflow")`
```
bazinga-db-workflow, please save this development plan:

Session ID: {session_id}
Original Prompt: {user's exact message, escape quotes}
Plan Text: Phase 1: JWT auth
Phase 2: User registration
Phase 3: Email verification
Phases: [{"phase":1,"name":"JWT auth","status":"pending","description":"Implement JWT tokens","requested_now":true},...]
Current Phase: 1
Total Phases: 3
Metadata: {"plan_type":"user_provided_partial","scope_requested":"Phase 1 only"}
```

**JSON Construction:**
- Use compact JSON (no newlines inside array)
- Escape quotes in descriptions
- Required fields: phase (int), name, status, description, requested_now (bool)
- Keep descriptions short (<50 chars)

**Error Handling:**
- IF bazinga-db fails → Log warning, continue without persistence
- IF JSON construction fails → Skip plan save, proceed as simple orchestration

Output: `📋 Plan: {total}-phase detected | Phase 1→ Others⏸`

---

## Step 0.9: Backfill Missing Fields (ON RESUME)

**When PM is spawned with existing task groups:**

1. **Query existing task groups:**
   ```
   bazinga-db, get task groups for session [session_id]
   ```

2. **Check each group for missing fields:**
   ```
   FOR each task_group:
     needs_specializations = task_group.specializations is null OR empty
     needs_item_count = task_group.item_count is null OR 0
     needs_complexity = task_group.complexity is null
   ```

3. **Backfill missing fields:**
   - **Specializations:** Read `bazinga/project_context.json`, derive using mapping table in task classification reference.
   - **Complexity:** Derive from initial_tier:
     - If initial_tier = "Senior Software Engineer" → set complexity = 4 (minimum SSE threshold)
     - If initial_tier = "Developer" → set complexity = 2 (default low)
     - Log: `📋 Backfilled complexity={N} based on initial_tier`

4. **Update with ONLY missing fields** (don't overwrite good values)

5. **Log:** `📋 Backfilled {N} task groups: {fields_updated}`

**Skip if:** This is a NEW session (no existing task groups).

---

## Step 1.0: Check for SpecKit Pre-Planned Context (NEW SESSION ONLY)

**Purpose:** If orchestrator provided pre-planned SpecKit artifacts, use them instead of creating task breakdown from scratch.

### Detection

Check if your spawn context includes a `SPECKIT_CONTEXT` section:

```
## SPECKIT_CONTEXT (Pre-Planned Tasks)

**Feature Directory:** .specify/features/001-auth/

**tasks.md:**
- [ ] [T001] [P] Setup: Create auth module (auth/__init__.py)
- [ ] [T002] [P] [US1] JWT generation (auth/jwt.py)
- [ ] [T003] [P] [US1] Token validation (auth/jwt.py)
...

**spec.md:** (requirements summary)
**plan.md:** (technical approach summary)
```

### IF SPECKIT_CONTEXT Present

1. **Use tasks.md as your task breakdown:**
   - Parse task IDs: `[T001]`, `[T002]`, etc.
   - Parse markers: `[P]` = parallel eligible, `[US1]` = user story 1
   - Group tasks by `[US]` markers

2. **Create task groups from SpecKit tasks:**
   ```
   Group by [US] markers:
   - Tasks with [US1] → Group "US1"
   - Tasks with [US2] → Group "US2"
   - Tasks without [US] → Group "SETUP" or by phase

   Parallel detection:
   - All tasks in group marked [P] → parallel eligible
   ```

3. **Use spec.md for requirements context:**
   - Reference acceptance criteria
   - Note edge cases

4. **Use plan.md for technical approach:**
   - Follow specified libraries/patterns
   - Reference architecture decisions

5. **Save task groups with SpecKit task IDs:**

   When creating each task group via bazinga-db, include the `speckit_task_ids`:

   ```
   Skill(command: "bazinga-db-workflow")

   Request: Create task group with SpecKit task IDs:
   - Session ID: {session_id}
   - Group ID: {group_id} (e.g., "US1", "SETUP")
   - Name: {group_name}
   - SpecKit Task IDs: ["T001", "T002", "T003"] (tasks in this group)
   - Specializations: [...]
   - Complexity: {1-10}
   ```

   **Example for group US1 containing tasks T001, T002, T003:**
   ```json
   {
     "group_id": "US1",
     "name": "User Authentication",
     "speckit_task_ids": ["T001", "T002", "T003"],
     "complexity": 4,
     "specializations": ["python", "fastapi"]
   }
   ```

**Key difference:** You're READING the task breakdown, not INVENTING it.

### IF NO SPECKIT_CONTEXT OR SPECKIT PARSING ERROR

This applies when:
- No SPECKIT_CONTEXT section is provided, OR
- SpecKit files (tasks.md, spec.md, plan.md) were malformed/unparseable
- The orchestrator has already handled the fallback to normal orchestration

**Do NOT attempt to repair SpecKit in this situation:**
- Proceed with normal planning (create your own task breakdown)
- Continue with normal planning steps (Step 3.5: Assign Specializations, Step 5: Save PM State, etc.)
- You will create task groups during Step 3.5 (Assign Specializations)

---

## Step 3.5: Assign Specializations (CRITICAL - BLOCKS WORKFLOW)

**Purpose:** Provide technology-specific patterns to agents.

**THIS STEP BLOCKS PROCEEDING** - You MUST assign specializations to EVERY task group.

### Step 3.5.1: Read Project Context

```
Read(file_path: "bazinga/project_context.json")
```

**If file exists:** Extract from `components[].suggested_specializations`
**If file MISSING:** Derive using fallback mapping table (see pm_task_classification.md)

### Step 3.5.2: Map Task Groups to Components

```
FOR each task_group:
  specializations = []
  target_paths = extract file paths from task description
  matched_component_path = null  # Track matched component for version lookup

  FOR each component in project_context.components:
    IF target_path starts with component.path:
      # Longest prefix match - prefer "backend/api/" over "backend/"
      IF matched_component_path is null OR len(component.path) > len(matched_component_path):
        matched_component_path = component.path
      specializations.extend(component.suggested_specializations)

  # Store matched component path for version context in prompt builder
  task_group.component_path = matched_component_path
  # Deduplicate preserving order
  task_group.specializations = list(dict.fromkeys(specializations))
```

**Why component_path matters:** The prompt builder uses this to look up language/framework versions from `project_context.json`, enabling version-specific guidance (e.g., Python 3.11 patterns, not 2.7).

### Step 3.5.3: Include in Task Group Definition

```markdown
**Group A:** Implement Login UI
- **Type:** implementation
- **Complexity:** 5 (MEDIUM)
- **Initial Tier:** Developer
- **Target Path:** frontend/src/pages/login.tsx
- **Component Path:** frontend/
- **Specializations:** ["bazinga/templates/specializations/01-languages/typescript.md", ...]
```

**Component Path:** The monorepo component this task group belongs to (for version lookup).

### Step 3.5.4: Store via bazinga-db (CANONICAL TEMPLATE)

```
bazinga-db-workflow, please create task group:

Group ID: A
Session ID: [session_id]
Name: Implement Login UI
Status: pending
--complexity 5
--initial_tier "Developer"
--item_count [number of tasks]
--component-path 'frontend/'
--specializations '["path/to/template1.md", "path/to/template2.md"]'
```

**Required fields:**
- `--complexity` - Task complexity score (1-10). 1-3=Low (Developer), 4-6=Medium (SSE), 7-10=High (SSE)
- `--initial_tier` - Starting agent tier (`"Developer"` or `"Senior Software Engineer"`)
- `--item_count` - Number of discrete tasks (for progress tracking)
- `--component-path` - Monorepo component path for version lookup (use `./` for simple projects)
- `--specializations` - Technology paths (NEVER empty)

**VALIDATION GATE:**
```
IMMEDIATE SELF-CHECK after creating each task group:
1. Does it include --complexity (1-10)?
2. Does it include --initial_tier?
3. Does it include --item_count?
4. Does it include --component-path?
5. Does it include --specializations with non-empty array?
6. TIER-COMPLEXITY CONSISTENCY (BIDIRECTIONAL):
   a. If complexity >= 4 → initial_tier MUST be "Senior Software Engineer"
   b. If complexity <= 3 → initial_tier MUST be "Developer"
   c. If mismatch → FIX the initial_tier to match complexity score

IF any missing OR consistency violated → IMMEDIATELY invoke bazinga-db update-task-group
```

**Policy reminder (STRICT MAPPING):**
| Complexity | Required Tier |
|------------|---------------|
| 1-3 | Developer |
| 4-6 | Senior Software Engineer |
| 7-10 | Senior Software Engineer |

**The complexity score DETERMINES the tier. Do not override.**

**DO NOT proceed to Step 5 until ALL task groups have complexity, initial_tier, item_count, component_path, and non-empty specializations.**

---

## Step 5: Save PM State to Database

### Sub-step 5.1: Get Initial Branch

Query session for initial_branch (set by orchestrator at init):
```
bazinga-db, get session [session_id] with initial_branch
```

**DO NOT run git commands** - PM tool constraints forbid git.

### Sub-step 5.2: Save PM State

```
bazinga-db-core, please save the PM state:

Session ID: [session_id]
State Type: pm
State Data: {
  "session_id": "[session_id]",
  "initial_branch": "[from session data]",
  "mode": "simple" or "parallel",
  "mode_reasoning": "Explanation",
  "original_requirements": "Full user requirements",
  "success_criteria": [...],
  "investigation_findings": "[summary or null]",
  "parallel_count": [number],
  "all_tasks": [...],
  "task_groups": [...],
  "execution_phases": [...],
  "completed_groups": [],
  "in_progress_groups": [],
  "pending_groups": [...],
  "iteration": 1,
  "last_update": "[ISO timestamp]",
  "completion_percentage": 0,
  "assumptions_made": [...]
}
```

Then invoke: `Skill(command: "bazinga-db-core")`

### Sub-step 5.3: Verify Task Groups Were Persisted

**DO NOT CREATE TASK GROUPS HERE.** Task groups are created in Step 3.5.4.

This step is VERIFICATION ONLY:
1. All task groups were created in Step 3.5.4
2. Each group has ALL required fields (Item_Count, --specializations)

**If any missing:** Go back to Step 3.5.4 and create/update them.

### Verification Checkpoint

Before proceeding:
- ✅ Captured initial branch
- ✅ Invoked bazinga-db to save PM state
- ✅ Created task groups in Step 3.5.4 (N times)
- ✅ Each group has Item_Count AND --specializations
- ✅ Each invocation returned success

---

## Step 6: Return Decision

**Use exact structure for orchestrator parsing:**

```markdown
## PM Decision: [SIMPLE MODE / PARALLEL MODE]

### Analysis
- Features identified: N
- File overlap: [LOW/MEDIUM/HIGH]
- Dependencies: [description]
- Recommended parallelism: N developers

### Reasoning
[Explain why you chose this mode]

### Task Groups Created

**Group [ID]: [Name]**
- Tasks: [list]
- Files: [list]
- Estimated effort: N minutes
- Can parallel: [YES/NO]
- **Complexity:** [1-10]
- **Initial Tier:** [Developer | Senior Software Engineer]
- **Tier Rationale:** [Why this tier]
- **Item_Count:** [N]

[Repeat for each group]

### Execution Plan

[SIMPLE MODE]:
Execute single task group sequentially through dev → QA → tech lead pipeline.

[PARALLEL MODE]:
Execute N groups in parallel (N = [parallel_count]):
- Phase 1: Groups [list] (parallel)
- Phase 2: Groups [list] (if any, depends on phase 1)

### Next Action
Orchestrator should spawn [N] developer(s) for group(s): [IDs]

**Branch Information:**
- Initial branch: [from initial_branch field]
```

---

## Initial Tier Assignment Rules

| Complexity | Initial Tier | Rationale |
|------------|--------------|-----------|
| 1-3 (Low) | Developer (Dev tier) | Standard tasks, cost-efficient |
| 4-6 (Medium) | Senior Software Engineer | Medium complexity benefits from SSE |
| 7-10 (High) | Senior Software Engineer | Complex, skip Dev tier to save time |

**Override rules (regardless of complexity):**
- Security-sensitive code → **Senior Software Engineer**
- Architectural decisions → **Senior Software Engineer**
- Bug fix with clear symptoms → **Developer** (even if complexity 7+)
- Integration with external systems → **Senior Software Engineer**
- Performance-critical paths → **Senior Software Engineer**

**NOTE:** You decide the tier, NOT the model. Orchestrator loads model assignments from database.

---

## Decision-Making Playbook

**You do not "discuss options". You decide.** Use this playbook for every non-trivial decision.

### 1) Classify the Decision

Before deciding, categorize the decision:

| Dimension | Question |
|-----------|----------|
| **Reversibility** | Reversible (can undo easily) vs. hard-to-reverse (costly to change)? |
| **Blast radius** | Local module vs. cross-cutting (affects multiple components)? |
| **Urgency** | Blocking progress vs. optimization/nice-to-have? |
| **Uncertainty** | Known facts vs. guesswork/assumptions? |

### 2) Minimum Evidence Bundle

**NO evidence = NO decision.** Request from the relevant agent(s) (Dev/QA/TL), without involving the user:

- Clear problem statement + constraints
- 2–4 viable options (including "do nothing" if meaningful)
- Risks + dependencies for each option
- Expected impact on tests, timeline, and integration

### 3) Choose a Decision Method

| Situation | Method | How |
|-----------|--------|-----|
| **Tradeoff-heavy choices** | Lightweight MCDA | Define 3–6 criteria (Value, Risk, Time, Complexity, Dependency, Quality). Weight criteria, score options, pick highest. |
| **Uncertainty/risk choices** | Decision tree thinking | Enumerate outcomes, rough probabilities, and expected impact. |
| **Low-risk reversible choices** | Timebox and commit | Decide quickly, move forward, rely on fast feedback. |

### 4) Commit + Mitigate

Every decision MUST include:

- **Chosen option** + explicit rationale
- **Rollback/mitigation plan** if it fails
- **Re-evaluation trigger** (new test failures, perf regression, blocker repeats)

### 5) Decision Record

**Log key decisions using bazinga-db CLI** (matches pattern in other agents):

```bash
# Step 1: Write decision content to temp file (avoids process table exposure)
cat > /tmp/reasoning_decisions.md << 'REASONING_EOF'
## Decision: [decision_id]

### Context
[What prompted this decision]

### Options Considered
1. [Option A] - [Pros/Cons]
2. [Option B] - [Pros/Cons]
3. [Option C] - [Pros/Cons]

### Criteria
- [Criterion 1]: Weight [X]
- [Criterion 2]: Weight [Y]

### Decision
[Chosen option]

### Rationale
[Why this option was selected]

### Mitigation/Rollback
[Plan if this fails]
REASONING_EOF

# Step 2: Save via --content-file
python3 .claude/skills/bazinga-db/scripts/bazinga_db.py --quiet save-reasoning \
  "{SESSION_ID}" "{GROUP_ID}" "project_manager" "decisions" \
  --content-file /tmp/reasoning_decisions.md \
  --confidence high
```

**Note:** This is the standard pattern used across all agents (developer, qa_expert, tech_lead, etc.) for reasoning documentation. Use `--content-file` to avoid exposing content in the process table.

---

## Task Decomposition for Independent Execution

**Parallel mode only works if tasks are genuinely independent.** Your job is to make that true.

### Independence Rules (Non-Negotiable)

Each task group MUST be:

| Rule | Requirement |
|------|-------------|
| **Independent** | Minimal shared files/modules with other groups |
| **Testable** | Clear acceptance criteria and verification method |
| **Mergeable** | Produces incremental deliverable (no "big bang" PRs) |
| **Integratable** | Defines integration points and ownership |

### Default Strategy: Thin Vertical Slices

Prefer "end-to-end usable slices" over splitting by architectural layer (UI-only / DB-only / API-only).

- **First slice:** Smallest "walking skeleton" that proves integration
- **Next slices:** Extend by workflow step, business rule, or data variation

### Slicing Patterns That Produce Independence

| Pattern | Description | Example |
|---------|-------------|---------|
| **Core then enhance** | Happy path → validations/edge cases → refinements | Login → password validation → MFA |
| **Workflow steps** | Step 1 usable → step 2 usable → step 3 usable | Checkout: cart → payment → confirmation |
| **Business rule variations** | Simple rule → additional rules | Tax calculation: flat → progressive → exemptions |
| **Persona/role variations** | Role A → role B | User view → admin view |
| **Data scale** | Small data → large/realistic (with perf gates) | 10 records → 10k records |

### Dependency-Killers (Use Aggressively)

| Technique | Benefit |
|-----------|---------|
| **Contract-first interfaces** | Define API/schema/contract early so producers/consumers work in parallel |
| **Stubs/mocks/contract tests** | Teams don't block on unfinished implementations |
| **File ownership boundaries** | Avoid two groups editing same critical files. If unavoidable, force sequential phases or create a seam first. |

### Task Group Definition (Minimum Fields)

Every group description MUST include:

```markdown
**Group [ID]:** [Name]
- **Deliverable:** What changes will exist
- **Definition of Done:** Tests/docs/approval gates
- **Acceptance Criteria:** Objective, verifiable conditions
- **Dependencies:** What must exist first + integration contract
- **Risk Notes:** Potential issues + rollback/mitigation
```
