diff --git a/server/task/auto_assignment.go b/server/task/auto_assignment.go
new file mode 100644
index 0000000..4bd5632
--- /dev/null
+++ b/server/task/auto_assignment.go
@@ -0,0 +1,237 @@
+package task
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+
+	"github.com/iomodo/staff/config"
+	"github.com/iomodo/staff/tm"
+)
+
+// AutoAssigner handles intelligent task assignment to agents
+type AutoAssigner struct {
+	agents []config.AgentConfig
+}
+
+// NewAutoAssigner creates a new auto-assignment system
+func NewAutoAssigner(agents []config.AgentConfig) *AutoAssigner {
+	return &AutoAssigner{
+		agents: agents,
+	}
+}
+
+// AssignmentScore represents how well an agent matches a task
+type AssignmentScore struct {
+	AgentName string
+	Score     float64
+	Reasons   []string
+}
+
+// AssignTask automatically assigns a task to the best matching agent
+func (a *AutoAssigner) AssignTask(task *tm.Task) (string, error) {
+	if len(a.agents) == 0 {
+		return "", fmt.Errorf("no agents available for assignment")
+	}
+
+	scores := a.calculateScores(task)
+	if len(scores) == 0 {
+		return "", fmt.Errorf("no suitable agent found for task")
+	}
+
+	// Sort by score (highest first)
+	sort.Slice(scores, func(i, j int) bool {
+		return scores[i].Score > scores[j].Score
+	})
+
+	bestMatch := scores[0]
+	if bestMatch.Score == 0 {
+		// No good match, assign to CEO as fallback
+		return "ceo", nil
+	}
+
+	return bestMatch.AgentName, nil
+}
+
+// GetAssignmentRecommendations returns ranked recommendations for task assignment
+func (a *AutoAssigner) GetAssignmentRecommendations(task *tm.Task) []AssignmentScore {
+	scores := a.calculateScores(task)
+
+	// Sort by score (highest first)
+	sort.Slice(scores, func(i, j int) bool {
+		return scores[i].Score > scores[j].Score
+	})
+
+	return scores
+}
+
+// calculateScores calculates assignment scores for all agents
+func (a *AutoAssigner) calculateScores(task *tm.Task) []AssignmentScore {
+	scores := make([]AssignmentScore, 0, len(a.agents))
+
+	taskText := strings.ToLower(task.Title + " " + task.Description)
+	taskKeywords := extractKeywords(taskText)
+
+	for _, agent := range a.agents {
+		score := &AssignmentScore{
+			AgentName: agent.Name,
+			Score:     0,
+			Reasons:   make([]string, 0),
+		}
+
+		// Score based on task type keywords
+		score.Score += a.scoreTaskTypes(agent.TaskTypes, taskKeywords, score)
+
+		// Score based on capabilities
+		score.Score += a.scoreCapabilities(agent.Capabilities, taskKeywords, score)
+
+		// Score based on task priority and agent model
+		score.Score += a.scorePriorityModelMatch(task.Priority, agent.Model, score)
+
+		// Score based on explicit agent mention in task
+		score.Score += a.scoreExplicitMention(agent.Name, agent.Role, taskText, score)
+
+		scores = append(scores, *score)
+	}
+
+	return scores
+}
+
+// scoreTaskTypes scores based on task type matching
+func (a *AutoAssigner) scoreTaskTypes(agentTypes []string, taskKeywords []string, score *AssignmentScore) float64 {
+	typeScore := 0.0
+
+	for _, agentType := range agentTypes {
+		for _, keyword := range taskKeywords {
+			if strings.Contains(keyword, agentType) || strings.Contains(agentType, keyword) {
+				typeScore += 3.0
+				score.Reasons = append(score.Reasons, fmt.Sprintf("matches task type: %s", agentType))
+			}
+		}
+	}
+
+	return typeScore
+}
+
+// scoreCapabilities scores based on capability matching
+func (a *AutoAssigner) scoreCapabilities(capabilities []string, taskKeywords []string, score *AssignmentScore) float64 {
+	capScore := 0.0
+
+	for _, capability := range capabilities {
+		for _, keyword := range taskKeywords {
+			if strings.Contains(keyword, capability) || strings.Contains(capability, keyword) {
+				capScore += 2.0
+				score.Reasons = append(score.Reasons, fmt.Sprintf("has capability: %s", capability))
+			}
+		}
+	}
+
+	return capScore
+}
+
+// scorePriorityModelMatch scores based on priority and model sophistication
+func (a *AutoAssigner) scorePriorityModelMatch(priority tm.TaskPriority, model string, score *AssignmentScore) float64 {
+	priorityScore := 0.0
+
+	// High priority tasks prefer more capable models
+	if priority == tm.PriorityHigh && strings.Contains(model, "gpt-4") {
+		priorityScore += 1.0
+		score.Reasons = append(score.Reasons, "high priority task matches advanced model")
+	}
+
+	// Medium/low priority can use efficient models
+	if priority != tm.PriorityHigh && strings.Contains(model, "gpt-3.5") {
+		priorityScore += 0.5
+		score.Reasons = append(score.Reasons, "priority matches model efficiency")
+	}
+
+	return priorityScore
+}
+
+// scoreExplicitMention scores based on explicit agent/role mentions
+func (a *AutoAssigner) scoreExplicitMention(agentName, agentRole, taskText string, score *AssignmentScore) float64 {
+	mentionScore := 0.0
+
+	// Check for explicit agent name mention
+	if strings.Contains(taskText, agentName) {
+		mentionScore += 5.0
+		score.Reasons = append(score.Reasons, "explicitly mentioned by name")
+	}
+
+	// Check for role mention
+	roleLower := strings.ToLower(agentRole)
+	if strings.Contains(taskText, roleLower) {
+		mentionScore += 4.0
+		score.Reasons = append(score.Reasons, "role mentioned in task")
+	}
+
+	return mentionScore
+}
+
+// extractKeywords extracts relevant keywords from task text
+func extractKeywords(text string) []string {
+	// Simple keyword extraction - split by common delimiters
+	words := strings.FieldsFunc(text, func(c rune) bool {
+		return c == ' ' || c == ',' || c == '.' || c == ':' || c == ';' || c == '\n' || c == '\t'
+	})
+
+	// Filter out common stop words and short words
+	stopWords := map[string]bool{
+		"the": true, "a": true, "an": true, "and": true, "or": true, "but": true,
+		"in": true, "on": true, "at": true, "to": true, "for": true, "of": true,
+		"with": true, "by": true, "is": true, "are": true, "was": true, "were": true,
+		"be": true, "been": true, "have": true, "has": true, "had": true, "do": true,
+		"does": true, "did": true, "will": true, "would": true, "could": true, "should": true,
+	}
+
+	keywords := make([]string, 0)
+	for _, word := range words {
+		word = strings.ToLower(strings.TrimSpace(word))
+		if len(word) > 2 && !stopWords[word] {
+			keywords = append(keywords, word)
+		}
+	}
+
+	return keywords
+}
+
+// ValidateAssignment checks if an assignment is valid
+func (a *AutoAssigner) ValidateAssignment(agentName string, task *tm.Task) error {
+	// Check if agent exists
+	for _, agent := range a.agents {
+		if agent.Name == agentName {
+			return nil
+		}
+	}
+
+	return fmt.Errorf("agent '%s' not found", agentName)
+}
+
+// GetAgentCapabilities returns the capabilities of a specific agent
+func (a *AutoAssigner) GetAgentCapabilities(agentName string) ([]string, error) {
+	for _, agent := range a.agents {
+		if agent.Name == agentName {
+			return agent.Capabilities, nil
+		}
+	}
+
+	return nil, fmt.Errorf("agent '%s' not found", agentName)
+}
+
+// GetRecommendationExplanation returns a human-readable explanation for assignment
+func (a *AutoAssigner) GetRecommendationExplanation(task *tm.Task, agentName string) string {
+	recommendations := a.GetAssignmentRecommendations(task)
+
+	for _, rec := range recommendations {
+		if rec.AgentName == agentName {
+			if len(rec.Reasons) == 0 {
+				return fmt.Sprintf("Agent %s assigned (score: %.1f)", agentName, rec.Score)
+			}
+
+			reasons := strings.Join(rec.Reasons, ", ")
+			return fmt.Sprintf("Agent %s assigned (score: %.1f) because: %s", agentName, rec.Score, reasons)
+		}
+	}
+
+	return fmt.Sprintf("Agent %s assigned (manual override)", agentName)
+}
diff --git a/server/task/service.go b/server/task/service.go
new file mode 100644
index 0000000..ba6a4c4
--- /dev/null
+++ b/server/task/service.go
@@ -0,0 +1,850 @@
+package task
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"log/slog"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"time"
+
+	"github.com/iomodo/staff/git"
+	"github.com/iomodo/staff/llm"
+	"github.com/iomodo/staff/tm"
+	"golang.org/x/text/cases"
+	"golang.org/x/text/language"
+)
+
+// SubtaskService handles subtask generation and management
+type SubtaskService struct {
+	llmProvider  llm.LLMProvider
+	taskManager  tm.TaskManager
+	agentRoles   []string                // Available agent roles for assignment
+	prProvider   git.PullRequestProvider // GitHub PR provider
+	githubOwner  string
+	githubRepo   string
+	cloneManager *git.CloneManager
+	logger       *slog.Logger
+}
+
+// NewSubtaskService creates a new subtask service
+func NewSubtaskService(provider llm.LLMProvider, taskManager tm.TaskManager, agentRoles []string, prProvider git.PullRequestProvider, githubOwner, githubRepo string, cloneManager *git.CloneManager, logger *slog.Logger) *SubtaskService {
+	if logger == nil {
+		logger = slog.Default()
+	}
+	return &SubtaskService{
+		llmProvider:  provider,
+		taskManager:  taskManager,
+		agentRoles:   agentRoles,
+		prProvider:   prProvider,
+		githubOwner:  githubOwner,
+		githubRepo:   githubRepo,
+		cloneManager: cloneManager,
+		logger:       logger,
+	}
+}
+
+// ShouldGenerateSubtasks asks LLM whether a task needs subtasks based on existing agents
+func (s *SubtaskService) ShouldGenerateSubtasks(ctx context.Context, task *tm.Task) (*tm.SubtaskDecision, error) {
+	prompt := s.buildSubtaskDecisionPrompt(task)
+
+	req := llm.ChatCompletionRequest{
+		Model: "gpt-4",
+		Messages: []llm.Message{
+			{
+				Role:    llm.RoleSystem,
+				Content: s.getSubtaskDecisionSystemPrompt(),
+			},
+			{
+				Role:    llm.RoleUser,
+				Content: prompt,
+			},
+		},
+		MaxTokens:   &[]int{1000}[0],
+		Temperature: &[]float64{0.3}[0],
+	}
+
+	resp, err := s.llmProvider.ChatCompletion(ctx, req)
+	if err != nil {
+		return nil, fmt.Errorf("LLM decision failed: %w", err)
+	}
+
+	if len(resp.Choices) == 0 {
+		return nil, fmt.Errorf("no response from LLM")
+	}
+
+	// Parse the LLM response
+	decision, err := s.parseSubtaskDecision(resp.Choices[0].Message.Content)
+	if err != nil {
+		return nil, fmt.Errorf("failed to parse LLM decision: %w", err)
+	}
+
+	return decision, nil
+}
+
+// AnalyzeTaskForSubtasks uses LLM to analyze a task and propose subtasks
+func (s *SubtaskService) AnalyzeTaskForSubtasks(ctx context.Context, task *tm.Task) (*tm.SubtaskAnalysis, error) {
+	prompt := s.buildSubtaskAnalysisPrompt(task)
+
+	req := llm.ChatCompletionRequest{
+		Model: "gpt-4",
+		Messages: []llm.Message{
+			{
+				Role:    llm.RoleSystem,
+				Content: s.getSubtaskAnalysisSystemPrompt(),
+			},
+			{
+				Role:    llm.RoleUser,
+				Content: prompt,
+			},
+		},
+		MaxTokens:   &[]int{4000}[0],
+		Temperature: &[]float64{0.3}[0],
+	}
+
+	resp, err := s.llmProvider.ChatCompletion(ctx, req)
+	if err != nil {
+		return nil, fmt.Errorf("LLM analysis failed: %w", err)
+	}
+
+	if len(resp.Choices) == 0 {
+		return nil, fmt.Errorf("no response from LLM")
+	}
+
+	// Parse the LLM response
+	analysis, err := s.parseSubtaskAnalysis(resp.Choices[0].Message.Content, task.ID)
+	if err != nil {
+		return nil, fmt.Errorf("failed to parse LLM response: %w", err)
+	}
+
+	return analysis, nil
+}
+
+// getSubtaskDecisionSystemPrompt returns the system prompt for subtask decision
+func (s *SubtaskService) getSubtaskDecisionSystemPrompt() string {
+	availableRoles := strings.Join(s.agentRoles, ", ")
+
+	return fmt.Sprintf(`You are an expert project manager and task analyst. Your job is to determine whether a task needs to be broken down into subtasks.
+
+Currently available team roles and their capabilities: %s
+
+When evaluating a task, consider:
+1. Task complexity and scope
+2. Whether multiple specialized skills are needed
+3. If the task can be completed by a single agent with current capabilities
+4. Whether new agent roles might be needed for specialized skills
+
+Respond with a JSON object in this exact format:
+{
+  "needs_subtasks": true/false,
+  "reasoning": "Clear explanation of why subtasks are or aren't needed",
+  "complexity_score": 5,
+  "required_skills": ["skill1", "skill2", "skill3"]
+}
+
+Complexity score should be 1-10 where:
+- 1-3: Simple tasks that can be handled by one agent
+- 4-6: Moderate complexity, might benefit from subtasks
+- 7-10: Complex tasks that definitely need breaking down
+
+Required skills should list all technical/domain skills needed to complete the task.`, availableRoles)
+}
+
+// getSubtaskAnalysisSystemPrompt returns the system prompt for subtask analysis
+func (s *SubtaskService) getSubtaskAnalysisSystemPrompt() string {
+	availableRoles := strings.Join(s.agentRoles, ", ")
+
+	return fmt.Sprintf(`You are an expert project manager and technical architect. Your job is to analyze complex tasks and break them down into well-defined subtasks that can be assigned to specialized team members.
+
+Currently available team roles: %s
+
+When analyzing a task, you should:
+1. Understand the task requirements and scope
+2. Break it down into logical, manageable subtasks
+3. Assign each subtask to the most appropriate team role OR propose creating new agents
+4. Estimate effort and identify dependencies
+5. Provide a clear execution strategy
+
+If you need specialized skills not covered by existing roles, propose new agent creation.
+
+Respond with a JSON object in this exact format:
+{
+  "analysis_summary": "Brief analysis of the task and approach",
+  "subtasks": [
+    {
+      "title": "Subtask title",
+      "description": "Detailed description of what needs to be done",
+      "priority": "high|medium|low",
+      "assigned_to": "role_name",
+      "estimated_hours": 8,
+      "dependencies": ["subtask_index_1", "subtask_index_2"],
+      "required_skills": ["skill1", "skill2"]
+    }
+  ],
+  "agent_creations": [
+    {
+      "role": "new_role_name",
+      "skills": ["specialized_skill1", "specialized_skill2"],
+      "description": "Description of what this agent does",
+      "justification": "Why this new agent is needed"
+    }
+  ],
+  "recommended_approach": "High-level strategy for executing these subtasks",
+  "estimated_total_hours": 40,
+  "risk_assessment": "Potential risks and mitigation strategies"
+}
+
+For existing roles, use: %s
+For new agents, propose appropriate role names and skill sets.
+Dependencies should reference subtask indices (e.g., ["0", "1"] means depends on first and second subtasks).`, availableRoles, availableRoles)
+}
+
+// buildSubtaskDecisionPrompt creates the user prompt for subtask decision
+func (s *SubtaskService) buildSubtaskDecisionPrompt(task *tm.Task) string {
+	return fmt.Sprintf(`Please evaluate whether the following task needs to be broken down into subtasks:
+
+**Task Title:** %s
+
+**Description:** %s
+
+**Priority:** %s
+
+**Current Status:** %s
+
+Consider:
+- Can this be completed by a single agent with existing capabilities?
+- Does it require multiple specialized skills?
+- Is the scope too large for one person?
+- Are there logical components that could be parallelized?
+
+Provide your decision in the JSON format specified in the system prompt.`,
+		task.Title,
+		task.Description,
+		task.Priority,
+		task.Status)
+}
+
+// buildSubtaskAnalysisPrompt creates the user prompt for LLM analysis
+func (s *SubtaskService) buildSubtaskAnalysisPrompt(task *tm.Task) string {
+	return fmt.Sprintf(`Please analyze the following task and break it down into subtasks:
+
+**Task Title:** %s
+
+**Description:** %s
+
+**Priority:** %s
+
+**Current Status:** %s
+
+Please analyze this task and provide a detailed breakdown into subtasks. Consider:
+- Technical complexity and requirements
+- Logical task dependencies 
+- Appropriate skill sets needed for each subtask
+- Risk factors and potential blockers
+- Estimated effort for each component
+
+Provide the analysis in the JSON format specified in the system prompt.`,
+		task.Title,
+		task.Description,
+		task.Priority,
+		task.Status)
+}
+
+// parseSubtaskDecision parses the LLM response into a SubtaskDecision struct
+func (s *SubtaskService) parseSubtaskDecision(response string) (*tm.SubtaskDecision, error) {
+	// Try to extract JSON from the response
+	jsonStart := strings.Index(response, "{")
+	jsonEnd := strings.LastIndex(response, "}")
+
+	if jsonStart == -1 || jsonEnd == -1 {
+		return nil, fmt.Errorf("no JSON found in LLM response")
+	}
+
+	jsonStr := response[jsonStart : jsonEnd+1]
+
+	var decision tm.SubtaskDecision
+	if err := json.Unmarshal([]byte(jsonStr), &decision); err != nil {
+		return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
+	}
+
+	return &decision, nil
+}
+
+// parseSubtaskAnalysis parses the LLM response into a SubtaskAnalysis struct
+func (s *SubtaskService) parseSubtaskAnalysis(response string, parentTaskID string) (*tm.SubtaskAnalysis, error) {
+	// Try to extract JSON from the response (LLM might wrap it in markdown)
+	jsonStart := strings.Index(response, "{")
+	jsonEnd := strings.LastIndex(response, "}")
+
+	if jsonStart == -1 || jsonEnd == -1 {
+		return nil, fmt.Errorf("no JSON found in LLM response")
+	}
+
+	jsonStr := response[jsonStart : jsonEnd+1]
+
+	var rawAnalysis struct {
+		AnalysisSummary string `json:"analysis_summary"`
+		Subtasks        []struct {
+			Title          string   `json:"title"`
+			Description    string   `json:"description"`
+			Priority       string   `json:"priority"`
+			AssignedTo     string   `json:"assigned_to"`
+			EstimatedHours int      `json:"estimated_hours"`
+			Dependencies   []string `json:"dependencies"`
+			RequiredSkills []string `json:"required_skills"`
+		} `json:"subtasks"`
+		AgentCreations      []tm.AgentCreationProposal `json:"agent_creations"`
+		RecommendedApproach string                     `json:"recommended_approach"`
+		EstimatedTotalHours int                        `json:"estimated_total_hours"`
+		RiskAssessment      string                     `json:"risk_assessment"`
+	}
+
+	if err := json.Unmarshal([]byte(jsonStr), &rawAnalysis); err != nil {
+		return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
+	}
+
+	// Convert to our types
+	analysis := &tm.SubtaskAnalysis{
+		ParentTaskID:        parentTaskID,
+		AnalysisSummary:     rawAnalysis.AnalysisSummary,
+		AgentCreations:      rawAnalysis.AgentCreations,
+		RecommendedApproach: rawAnalysis.RecommendedApproach,
+		EstimatedTotalHours: rawAnalysis.EstimatedTotalHours,
+		RiskAssessment:      rawAnalysis.RiskAssessment,
+	}
+
+	// Convert subtasks
+	for _, st := range rawAnalysis.Subtasks {
+		priority := tm.PriorityMedium // default
+		switch strings.ToLower(st.Priority) {
+		case "high":
+			priority = tm.PriorityHigh
+		case "low":
+			priority = tm.PriorityLow
+		}
+
+		subtask := tm.SubtaskProposal{
+			Title:          st.Title,
+			Description:    st.Description,
+			Priority:       priority,
+			AssignedTo:     st.AssignedTo,
+			EstimatedHours: st.EstimatedHours,
+			Dependencies:   st.Dependencies,
+			RequiredSkills: st.RequiredSkills,
+		}
+
+		analysis.Subtasks = append(analysis.Subtasks, subtask)
+	}
+
+	// Validate agent assignments and handle new agent creation
+	if err := s.validateAndHandleAgentAssignments(analysis); err != nil {
+		s.logger.Warn("Warning during agent assignment handling", slog.String("error", err.Error()))
+	}
+
+	return analysis, nil
+}
+
+// validateAndHandleAgentAssignments validates assignments and creates agent creation subtasks if needed
+func (s *SubtaskService) validateAndHandleAgentAssignments(analysis *tm.SubtaskAnalysis) error {
+	// Collect all agent roles that will be available (existing + proposed new ones)
+	availableRoles := make(map[string]bool)
+	for _, role := range s.agentRoles {
+		availableRoles[role] = true
+	}
+
+	// Add proposed new agent roles
+	for _, agentCreation := range analysis.AgentCreations {
+		availableRoles[agentCreation.Role] = true
+
+		// Create a subtask for agent creation
+		agentCreationSubtask := tm.SubtaskProposal{
+			Title:          fmt.Sprintf("Create %s Agent", cases.Title(language.English).String(agentCreation.Role)),
+			Description:    fmt.Sprintf("Create and configure a new %s agent with skills: %s. %s", agentCreation.Role, strings.Join(agentCreation.Skills, ", "), agentCreation.Justification),
+			Priority:       tm.PriorityHigh, // Agent creation is high priority
+			AssignedTo:     "ceo",           // CEO creates new agents
+			EstimatedHours: 4,               // Estimated time to set up new agent
+			Dependencies:   []string{},      // No dependencies for agent creation
+			RequiredSkills: []string{"agent_configuration", "system_design"},
+		}
+
+		// Insert at the beginning so agent creation happens first
+		analysis.Subtasks = append([]tm.SubtaskProposal{agentCreationSubtask}, analysis.Subtasks...)
+
+		// Update dependencies to account for the new subtask at index 0
+		for i := 1; i < len(analysis.Subtasks); i++ {
+			for j, dep := range analysis.Subtasks[i].Dependencies {
+				// Convert dependency index and increment by 1
+				if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
+					analysis.Subtasks[i].Dependencies[j] = fmt.Sprintf("%d", depIndex+1)
+				}
+			}
+		}
+	}
+
+	// Now validate all assignments against available roles
+	defaultRole := "ceo" // fallback role
+	if len(s.agentRoles) > 0 {
+		defaultRole = s.agentRoles[0]
+	}
+
+	for i := range analysis.Subtasks {
+		if !availableRoles[analysis.Subtasks[i].AssignedTo] {
+			s.logger.Warn("Unknown agent role for subtask, using default",
+				slog.String("unknown_role", analysis.Subtasks[i].AssignedTo),
+				slog.String("subtask_title", analysis.Subtasks[i].Title),
+				slog.String("assigned_role", defaultRole))
+			analysis.Subtasks[i].AssignedTo = defaultRole
+		}
+	}
+
+	return nil
+}
+
+// parseDependencyIndex parses a dependency string to an integer index
+func (s *SubtaskService) parseDependencyIndex(dep string) int {
+	var idx int
+	if _, err := fmt.Sscanf(dep, "%d", &idx); err == nil {
+		return idx
+	}
+	return -1 // Invalid dependency format
+}
+
+// isValidAgentRole checks if a role is in the available agent roles
+func (s *SubtaskService) isValidAgentRole(role string) bool {
+	for _, availableRole := range s.agentRoles {
+		if availableRole == role {
+			return true
+		}
+	}
+	return false
+}
+
+// GenerateSubtaskPR creates a PR with the proposed subtasks
+func (s *SubtaskService) GenerateSubtaskPR(ctx context.Context, analysis *tm.SubtaskAnalysis) (string, error) {
+	if s.prProvider == nil {
+		return "", fmt.Errorf("PR provider not configured")
+	}
+
+	// Generate branch name for subtask proposal
+	branchName := fmt.Sprintf("subtasks/%s-proposal", analysis.ParentTaskID)
+	s.logger.Info("Creating subtask PR", slog.String("branch", branchName))
+
+	// Create Git branch and commit subtask proposal
+	if err := s.createSubtaskBranch(ctx, analysis, branchName); err != nil {
+		return "", fmt.Errorf("failed to create subtask branch: %w", err)
+	}
+
+	// Generate PR content
+	prContent := s.generateSubtaskPRContent(analysis)
+	title := fmt.Sprintf("Subtask Proposal: %s", analysis.ParentTaskID)
+
+	// Validate PR content
+	if title == "" {
+		return "", fmt.Errorf("PR title cannot be empty")
+	}
+	if prContent == "" {
+		return "", fmt.Errorf("PR description cannot be empty")
+	}
+
+	// Determine base branch (try main first, fallback to master)
+	baseBranch := s.determineBaseBranch(ctx)
+	s.logger.Info("Using base branch", slog.String("base_branch", baseBranch))
+
+	// Create the pull request
+	options := git.PullRequestOptions{
+		Title:       title,
+		Description: prContent,
+		HeadBranch:  branchName,
+		BaseBranch:  baseBranch,
+		Labels:      []string{"subtasks", "proposal", "ai-generated"},
+		Draft:       false,
+	}
+
+	s.logger.Info("Creating PR with options",
+		slog.String("title", options.Title),
+		slog.String("head_branch", options.HeadBranch),
+		slog.String("base_branch", options.BaseBranch))
+
+	pr, err := s.prProvider.CreatePullRequest(ctx, options)
+	if err != nil {
+		return "", fmt.Errorf("failed to create PR: %w", err)
+	}
+
+	prURL := fmt.Sprintf("https://github.com/%s/%s/pull/%d", s.githubOwner, s.githubRepo, pr.Number)
+	s.logger.Info("Generated subtask proposal PR", slog.String("pr_url", prURL))
+
+	return prURL, nil
+}
+
+// determineBaseBranch determines the correct base branch (main or master)
+func (s *SubtaskService) determineBaseBranch(ctx context.Context) string {
+	if s.cloneManager == nil {
+		return "main" // default fallback
+	}
+
+	// Get clone path to check branches
+	clonePath, err := s.cloneManager.GetAgentClonePath("subtask-service")
+	if err != nil {
+		s.logger.Warn("Failed to get clone path for base branch detection", slog.String("error", err.Error()))
+		return "main"
+	}
+
+	// Check if main branch exists
+	gitCmd := func(args ...string) *exec.Cmd {
+		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
+	}
+
+	// Try to checkout main branch
+	cmd := gitCmd("show-ref", "refs/remotes/origin/main")
+	if err := cmd.Run(); err == nil {
+		return "main"
+	}
+
+	// Try to checkout master branch
+	cmd = gitCmd("show-ref", "refs/remotes/origin/master")
+	if err := cmd.Run(); err == nil {
+		return "master"
+	}
+
+	// Default to main if neither can be detected
+	s.logger.Warn("Could not determine base branch, defaulting to 'main'")
+	return "main"
+}
+
+// generateSubtaskFile creates the content for an individual subtask file
+func (s *SubtaskService) generateSubtaskFile(subtask tm.SubtaskProposal, taskID, parentTaskID string) string {
+	var content strings.Builder
+
+	// Generate YAML frontmatter
+	content.WriteString("---\n")
+	content.WriteString(fmt.Sprintf("id: %s\n", taskID))
+	content.WriteString(fmt.Sprintf("title: %s\n", subtask.Title))
+	content.WriteString(fmt.Sprintf("description: %s\n", subtask.Description))
+	content.WriteString(fmt.Sprintf("assignee: %s\n", subtask.AssignedTo))
+	content.WriteString(fmt.Sprintf("owner_id: %s\n", subtask.AssignedTo))
+	content.WriteString(fmt.Sprintf("owner_name: %s\n", subtask.AssignedTo))
+	content.WriteString("status: todo\n")
+	content.WriteString(fmt.Sprintf("priority: %s\n", strings.ToLower(string(subtask.Priority))))
+	content.WriteString(fmt.Sprintf("parent_task_id: %s\n", parentTaskID))
+	content.WriteString(fmt.Sprintf("estimated_hours: %d\n", subtask.EstimatedHours))
+	content.WriteString(fmt.Sprintf("created_at: %s\n", time.Now().Format(time.RFC3339)))
+	content.WriteString(fmt.Sprintf("updated_at: %s\n", time.Now().Format(time.RFC3339)))
+	content.WriteString("completed_at: null\n")
+	content.WriteString("archived_at: null\n")
+
+	// Add dependencies if any
+	if len(subtask.Dependencies) > 0 {
+		content.WriteString("dependencies:\n")
+		for _, dep := range subtask.Dependencies {
+			// Convert dependency index to actual subtask ID
+			if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
+				depTaskID := fmt.Sprintf("%s-subtask-%d", parentTaskID, depIndex+1)
+				content.WriteString(fmt.Sprintf("  - %s\n", depTaskID))
+			}
+		}
+	}
+
+	// Add required skills if any
+	if len(subtask.RequiredSkills) > 0 {
+		content.WriteString("required_skills:\n")
+		for _, skill := range subtask.RequiredSkills {
+			content.WriteString(fmt.Sprintf("  - %s\n", skill))
+		}
+	}
+
+	content.WriteString("---\n\n")
+
+	// Add markdown content
+	content.WriteString("# Task Description\n\n")
+	content.WriteString(fmt.Sprintf("%s\n\n", subtask.Description))
+
+	if subtask.EstimatedHours > 0 {
+		content.WriteString("## Estimated Effort\n\n")
+		content.WriteString(fmt.Sprintf("**Estimated Hours:** %d\n\n", subtask.EstimatedHours))
+	}
+
+	if len(subtask.RequiredSkills) > 0 {
+		content.WriteString("## Required Skills\n\n")
+		for _, skill := range subtask.RequiredSkills {
+			content.WriteString(fmt.Sprintf("- %s\n", skill))
+		}
+		content.WriteString("\n")
+	}
+
+	if len(subtask.Dependencies) > 0 {
+		content.WriteString("## Dependencies\n\n")
+		content.WriteString("This task depends on the completion of:\n\n")
+		for _, dep := range subtask.Dependencies {
+			if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
+				depTaskID := fmt.Sprintf("%s-subtask-%d", parentTaskID, depIndex+1)
+				content.WriteString(fmt.Sprintf("- %s\n", depTaskID))
+			}
+		}
+		content.WriteString("\n")
+	}
+
+	content.WriteString("## Notes\n\n")
+	content.WriteString(fmt.Sprintf("This subtask was generated from parent task: %s\n", parentTaskID))
+	content.WriteString("Generated by Staff AI Agent System\n\n")
+
+	return content.String()
+}
+
+// updateParentTaskAsCompleted updates the parent task file to mark it as completed
+func (s *SubtaskService) updateParentTaskAsCompleted(taskFilePath string, analysis *tm.SubtaskAnalysis) error {
+	// Read the existing parent task file
+	content, err := os.ReadFile(taskFilePath)
+	if err != nil {
+		return fmt.Errorf("failed to read parent task file: %w", err)
+	}
+
+	taskContent := string(content)
+
+	// Find the YAML frontmatter boundaries
+	lines := strings.Split(taskContent, "\n")
+	var frontmatterStart, frontmatterEnd int = -1, -1
+
+	for i, line := range lines {
+		if line == "---" {
+			if frontmatterStart == -1 {
+				frontmatterStart = i
+			} else {
+				frontmatterEnd = i
+				break
+			}
+		}
+	}
+
+	if frontmatterStart == -1 || frontmatterEnd == -1 {
+		return fmt.Errorf("invalid task file format: missing YAML frontmatter")
+	}
+
+	// Update the frontmatter
+	now := time.Now().Format(time.RFC3339)
+	var updatedLines []string
+
+	// Add lines before frontmatter
+	updatedLines = append(updatedLines, lines[:frontmatterStart+1]...)
+
+	// Process frontmatter lines
+	for i := frontmatterStart + 1; i < frontmatterEnd; i++ {
+		line := lines[i]
+		if strings.HasPrefix(line, "status:") {
+			updatedLines = append(updatedLines, "status: completed")
+		} else if strings.HasPrefix(line, "updated_at:") {
+			updatedLines = append(updatedLines, fmt.Sprintf("updated_at: %s", now))
+		} else if strings.HasPrefix(line, "completed_at:") {
+			updatedLines = append(updatedLines, fmt.Sprintf("completed_at: %s", now))
+		} else {
+			updatedLines = append(updatedLines, line)
+		}
+	}
+
+	// Add closing frontmatter and rest of content
+	updatedLines = append(updatedLines, lines[frontmatterEnd:]...)
+
+	// Add subtask information to the task description
+	if frontmatterEnd+1 < len(lines) {
+		// Add subtask information
+		subtaskInfo := fmt.Sprintf("\n\n## Subtasks Created\n\nThis task has been broken down into %d subtasks:\n\n", len(analysis.Subtasks))
+		for i, subtask := range analysis.Subtasks {
+			subtaskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+			subtaskInfo += fmt.Sprintf("- **%s**: %s (assigned to %s)\n", subtaskID, subtask.Title, subtask.AssignedTo)
+		}
+		subtaskInfo += fmt.Sprintf("\n**Total Estimated Hours:** %d\n", analysis.EstimatedTotalHours)
+		subtaskInfo += fmt.Sprintf("**Completed:** %s - Task broken down into actionable subtasks\n", now)
+
+		// Insert subtask info before any existing body content
+		updatedContent := strings.Join(updatedLines[:], "\n") + subtaskInfo
+
+		// Write the updated content back to the file
+		if err := os.WriteFile(taskFilePath, []byte(updatedContent), 0644); err != nil {
+			return fmt.Errorf("failed to write updated parent task file: %w", err)
+		}
+	}
+
+	s.logger.Info("Updated parent task to completed status", slog.String("task_id", analysis.ParentTaskID))
+	return nil
+}
+
+// generateSubtaskPRContent creates markdown content for the subtask proposal PR
+func (s *SubtaskService) generateSubtaskPRContent(analysis *tm.SubtaskAnalysis) string {
+	var content strings.Builder
+
+	content.WriteString(fmt.Sprintf("# Subtasks Created for Task %s\n\n", analysis.ParentTaskID))
+	content.WriteString(fmt.Sprintf("This PR creates **%d individual task files** in `/operations/tasks/` ready for agent assignment.\n\n", len(analysis.Subtasks)))
+	content.WriteString(fmt.Sprintf("✅ **Parent task `%s` has been marked as completed** - the complex task has been successfully broken down into actionable subtasks.\n\n", analysis.ParentTaskID))
+	content.WriteString(fmt.Sprintf("## Analysis Summary\n%s\n\n", analysis.AnalysisSummary))
+	content.WriteString(fmt.Sprintf("## Recommended Approach\n%s\n\n", analysis.RecommendedApproach))
+	content.WriteString(fmt.Sprintf("**Estimated Total Hours:** %d\n\n", analysis.EstimatedTotalHours))
+
+	// List the created task files
+	content.WriteString("## Created Task Files\n\n")
+	for i, subtask := range analysis.Subtasks {
+		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+		content.WriteString(fmt.Sprintf("### %d. `%s.md`\n", i+1, taskID))
+		content.WriteString(fmt.Sprintf("- **Title:** %s\n", subtask.Title))
+		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
+		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
+		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
+		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
+	}
+
+	if analysis.RiskAssessment != "" {
+		content.WriteString(fmt.Sprintf("## Risk Assessment\n%s\n\n", analysis.RiskAssessment))
+	}
+
+	content.WriteString("## Proposed Subtasks\n\n")
+
+	for i, subtask := range analysis.Subtasks {
+		content.WriteString(fmt.Sprintf("### %d. %s\n", i+1, subtask.Title))
+		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
+		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
+		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
+
+		if len(subtask.Dependencies) > 0 {
+			deps := strings.Join(subtask.Dependencies, ", ")
+			content.WriteString(fmt.Sprintf("- **Dependencies:** %s\n", deps))
+		}
+
+		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
+	}
+
+	content.WriteString("---\n")
+	content.WriteString("*Generated by Staff AI Agent System*\n\n")
+	content.WriteString("**Instructions:**\n")
+	content.WriteString("- Review the proposed subtasks\n")
+	content.WriteString("- Approve or request changes\n")
+	content.WriteString("- When merged, the subtasks will be automatically created and assigned\n")
+
+	return content.String()
+}
+
+// createSubtaskBranch creates a Git branch with subtask proposal content
+func (s *SubtaskService) createSubtaskBranch(ctx context.Context, analysis *tm.SubtaskAnalysis, branchName string) error {
+	if s.cloneManager == nil {
+		return fmt.Errorf("clone manager not configured")
+	}
+
+	// Get a temporary clone for creating the subtask branch
+	clonePath, err := s.cloneManager.GetAgentClonePath("subtask-service")
+	if err != nil {
+		return fmt.Errorf("failed to get clone path: %w", err)
+	}
+
+	// All Git operations use the clone directory
+	gitCmd := func(args ...string) *exec.Cmd {
+		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
+	}
+
+	// Ensure we're on main branch before creating new branch
+	cmd := gitCmd("checkout", "main")
+	if err := cmd.Run(); err != nil {
+		// Try master branch if main doesn't exist
+		cmd = gitCmd("checkout", "master")
+		if err := cmd.Run(); err != nil {
+			return fmt.Errorf("failed to checkout main/master branch: %w", err)
+		}
+	}
+
+	// Pull latest changes
+	cmd = gitCmd("pull", "origin")
+	if err := cmd.Run(); err != nil {
+		s.logger.Warn("Failed to pull latest changes", slog.String("error", err.Error()))
+	}
+
+	// Delete branch if it exists (cleanup from previous attempts)
+	cmd = gitCmd("branch", "-D", branchName)
+	_ = cmd.Run() // Ignore error if branch doesn't exist
+
+	// Also delete remote tracking branch if it exists
+	cmd = gitCmd("push", "origin", "--delete", branchName)
+	_ = cmd.Run() // Ignore error if branch doesn't exist
+
+	// Create and checkout new branch
+	cmd = gitCmd("checkout", "-b", branchName)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to create branch: %w", err)
+	}
+
+	// Create individual task files for each subtask
+	tasksDir := filepath.Join(clonePath, "operations", "tasks")
+	if err := os.MkdirAll(tasksDir, 0755); err != nil {
+		return fmt.Errorf("failed to create tasks directory: %w", err)
+	}
+
+	var stagedFiles []string
+
+	// Update parent task to mark as completed
+	parentTaskFile := filepath.Join(tasksDir, fmt.Sprintf("%s.md", analysis.ParentTaskID))
+	if err := s.updateParentTaskAsCompleted(parentTaskFile, analysis); err != nil {
+		return fmt.Errorf("failed to update parent task: %w", err)
+	}
+
+	// Track parent task file for staging
+	parentRelativeFile := filepath.Join("operations", "tasks", fmt.Sprintf("%s.md", analysis.ParentTaskID))
+	stagedFiles = append(stagedFiles, parentRelativeFile)
+	s.logger.Info("Updated parent task file", slog.String("file", parentRelativeFile))
+
+	// Create a file for each subtask
+	for i, subtask := range analysis.Subtasks {
+		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+		taskFile := filepath.Join(tasksDir, fmt.Sprintf("%s.md", taskID))
+		taskContent := s.generateSubtaskFile(subtask, taskID, analysis.ParentTaskID)
+
+		if err := os.WriteFile(taskFile, []byte(taskContent), 0644); err != nil {
+			return fmt.Errorf("failed to write subtask file %s: %w", taskID, err)
+		}
+
+		// Track file for staging
+		relativeFile := filepath.Join("operations", "tasks", fmt.Sprintf("%s.md", taskID))
+		stagedFiles = append(stagedFiles, relativeFile)
+		s.logger.Info("Created subtask file", slog.String("file", relativeFile))
+	}
+
+	// Stage all subtask files
+	for _, file := range stagedFiles {
+		cmd = gitCmd("add", file)
+		if err := cmd.Run(); err != nil {
+			return fmt.Errorf("failed to stage file %s: %w", file, err)
+		}
+	}
+
+	// Commit changes
+	commitMsg := fmt.Sprintf("Create %d subtasks for task %s and mark parent as completed\n\nGenerated by Staff AI Agent System\n\nFiles modified:\n- %s.md (marked as completed)\n\nCreated individual task files:\n",
+		len(analysis.Subtasks), analysis.ParentTaskID, analysis.ParentTaskID)
+
+	// Add list of created files to commit message
+	for i := range analysis.Subtasks {
+		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
+		commitMsg += fmt.Sprintf("- %s.md\n", taskID)
+	}
+
+	if len(analysis.AgentCreations) > 0 {
+		commitMsg += fmt.Sprintf("\nProposed %d new agents for specialized skills", len(analysis.AgentCreations))
+	}
+	cmd = gitCmd("commit", "-m", commitMsg)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to commit: %w", err)
+	}
+
+	// Push branch
+	cmd = gitCmd("push", "-u", "origin", branchName)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("failed to push branch: %w", err)
+	}
+
+	s.logger.Info("Created subtask proposal branch", slog.String("branch", branchName))
+	return nil
+}
+
+// Close cleans up the service
+func (s *SubtaskService) Close() error {
+	if s.llmProvider != nil {
+		return s.llmProvider.Close()
+	}
+	return nil
+}
diff --git a/server/task/service_test.go b/server/task/service_test.go
new file mode 100644
index 0000000..5c7b337
--- /dev/null
+++ b/server/task/service_test.go
@@ -0,0 +1,687 @@
+package task
+
+import (
+	"context"
+	"os"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/iomodo/staff/llm"
+	"github.com/iomodo/staff/tm"
+)
+
+// MockLLMProvider implements a mock LLM provider for testing
+type MockLLMProvider struct {
+	responses []string
+	callCount int
+}
+
+func NewMockLLMProvider(responses []string) *MockLLMProvider {
+	return &MockLLMProvider{
+		responses: responses,
+		callCount: 0,
+	}
+}
+
+func (m *MockLLMProvider) ChatCompletion(ctx context.Context, req llm.ChatCompletionRequest) (*llm.ChatCompletionResponse, error) {
+	if m.callCount >= len(m.responses) {
+		return nil, nil
+	}
+
+	response := m.responses[m.callCount]
+	m.callCount++
+
+	return &llm.ChatCompletionResponse{
+		ID:      "mock-response",
+		Object:  "chat.completion",
+		Created: time.Now().Unix(),
+		Model:   req.Model,
+		Choices: []llm.ChatCompletionChoice{
+			{
+				Index: 0,
+				Message: llm.Message{
+					Role:    llm.RoleAssistant,
+					Content: response,
+				},
+				FinishReason: "stop",
+			},
+		},
+		Usage: llm.Usage{
+			PromptTokens:     100,
+			CompletionTokens: 300,
+			TotalTokens:      400,
+		},
+	}, nil
+}
+
+func (m *MockLLMProvider) CreateEmbeddings(ctx context.Context, req llm.EmbeddingRequest) (*llm.EmbeddingResponse, error) {
+	return &llm.EmbeddingResponse{
+		Object: "list",
+		Data: []llm.Embedding{
+			{
+				Object:    "embedding",
+				Index:     0,
+				Embedding: make([]float64, 1536),
+			},
+		},
+		Model: req.Model,
+		Usage: llm.Usage{
+			PromptTokens: 50,
+			TotalTokens:  50,
+		},
+	}, nil
+}
+
+func (m *MockLLMProvider) Close() error {
+	return nil
+}
+
+func TestNewSubtaskService(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	agentRoles := []string{"backend", "frontend", "qa"}
+
+	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
+
+	if service == nil {
+		t.Fatal("NewSubtaskService returned nil")
+	}
+
+	if service.llmProvider != mockProvider {
+		t.Error("LLM provider not set correctly")
+	}
+
+	if len(service.agentRoles) != 3 {
+		t.Errorf("Expected 3 agent roles, got %d", len(service.agentRoles))
+	}
+}
+
+func TestShouldGenerateSubtasks(t *testing.T) {
+	// Test decision to generate subtasks
+	decisionResponse := `{
+  "needs_subtasks": true,
+  "reasoning": "Complex task requiring multiple skills",
+  "complexity_score": 8,
+  "required_skills": ["backend", "frontend", "database"]
+}`
+
+	mockProvider := NewMockLLMProvider([]string{decisionResponse})
+	agentRoles := []string{"backend", "frontend", "qa"}
+	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
+
+	// Test the parseSubtaskDecision method directly since ShouldGenerateSubtasks is used by manager
+	decision, err := service.parseSubtaskDecision(decisionResponse)
+	if err != nil {
+		t.Fatalf("parseSubtaskDecision failed: %v", err)
+	}
+
+	if !decision.NeedsSubtasks {
+		t.Error("Expected decision to need subtasks")
+	}
+
+	if decision.ComplexityScore != 8 {
+		t.Errorf("Expected complexity score 8, got %d", decision.ComplexityScore)
+	}
+
+	if len(decision.RequiredSkills) != 3 {
+		t.Errorf("Expected 3 required skills, got %d", len(decision.RequiredSkills))
+	}
+}
+
+func TestAnalyzeTaskForSubtasks(t *testing.T) {
+	jsonResponse := `{
+  "analysis_summary": "This task requires breaking down into multiple components",
+  "subtasks": [
+    {
+      "title": "Backend Development",
+      "description": "Implement server-side logic",
+      "priority": "high",
+      "assigned_to": "backend",
+      "estimated_hours": 16,
+      "dependencies": [],
+      "required_skills": ["go", "api_development"]
+    },
+    {
+      "title": "Frontend Development", 
+      "description": "Build user interface",
+      "priority": "medium",
+      "assigned_to": "frontend",
+      "estimated_hours": 12,
+      "dependencies": ["0"],
+      "required_skills": ["react", "typescript"]
+    }
+  ],
+  "agent_creations": [
+    {
+      "role": "security_specialist",
+      "skills": ["security_audit", "penetration_testing"],
+      "description": "Specialized agent for security tasks",
+      "justification": "Authentication requires security expertise"
+    }
+  ],
+  "recommended_approach": "Start with backend then frontend",
+  "estimated_total_hours": 28,
+  "risk_assessment": "Medium complexity with API integration risks"
+}`
+
+	mockProvider := NewMockLLMProvider([]string{jsonResponse})
+	agentRoles := []string{"backend", "frontend", "qa", "ceo"} // Include CEO for agent creation
+	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
+
+	task := &tm.Task{
+		ID:          "test-task-123",
+		Title:       "Build authentication system",
+		Description: "Implement user login and registration",
+		Priority:    tm.PriorityHigh,
+		Status:      tm.StatusToDo,
+		CreatedAt:   time.Now(),
+		UpdatedAt:   time.Now(),
+	}
+
+	analysis, err := service.AnalyzeTaskForSubtasks(context.Background(), task)
+	if err != nil {
+		t.Fatalf("AnalyzeTaskForSubtasks failed: %v", err)
+	}
+
+	if analysis.ParentTaskID != task.ID {
+		t.Errorf("Expected parent task ID %s, got %s", task.ID, analysis.ParentTaskID)
+	}
+
+	if analysis.AnalysisSummary == "" {
+		t.Error("Analysis summary should not be empty")
+	}
+
+	// Should have 3 subtasks (1 for agent creation + 2 original)
+	if len(analysis.Subtasks) != 3 {
+		t.Errorf("Expected 3 subtasks (including agent creation), got %d", len(analysis.Subtasks))
+		t.Logf("Subtasks: %+v", analysis.Subtasks)
+		return // Exit early if count is wrong to avoid index errors
+	}
+
+	// Test agent creation was processed
+	if len(analysis.AgentCreations) != 1 {
+		t.Errorf("Expected 1 agent creation, got %d", len(analysis.AgentCreations))
+	} else {
+		agentCreation := analysis.AgentCreations[0]
+		if agentCreation.Role != "security_specialist" {
+			t.Errorf("Expected role 'security_specialist', got %s", agentCreation.Role)
+		}
+		if len(agentCreation.Skills) != 2 {
+			t.Errorf("Expected 2 skills, got %d", len(agentCreation.Skills))
+		}
+	}
+
+	// We already checked the count above
+
+	// Test first subtask (agent creation)
+	subtask0 := analysis.Subtasks[0]
+	if !strings.Contains(subtask0.Title, "Security_specialist") {
+		t.Errorf("Expected agent creation subtask for security_specialist, got %s", subtask0.Title)
+	}
+	if subtask0.AssignedTo != "ceo" {
+		t.Errorf("Expected agent creation assigned to 'ceo', got %s", subtask0.AssignedTo)
+	}
+
+	// Test second subtask (original backend task, now at index 1)
+	subtask1 := analysis.Subtasks[1]
+	if subtask1.Title != "Backend Development" {
+		t.Errorf("Expected title 'Backend Development', got %s", subtask1.Title)
+	}
+	if subtask1.Priority != tm.PriorityHigh {
+		t.Errorf("Expected high priority, got %s", subtask1.Priority)
+	}
+	if subtask1.AssignedTo != "backend" {
+		t.Errorf("Expected assigned_to 'backend', got %s", subtask1.AssignedTo)
+	}
+	if subtask1.EstimatedHours != 16 {
+		t.Errorf("Expected 16 hours, got %d", subtask1.EstimatedHours)
+	}
+	if len(subtask1.RequiredSkills) != 2 {
+		t.Errorf("Expected 2 required skills, got %d", len(subtask1.RequiredSkills))
+	}
+
+	// Test third subtask (original frontend task, now at index 2 with updated dependencies)
+	subtask2 := analysis.Subtasks[2]
+	if subtask2.Title != "Frontend Development" {
+		t.Errorf("Expected title 'Frontend Development', got %s", subtask2.Title)
+	}
+	if subtask2.Priority != tm.PriorityMedium {
+		t.Errorf("Expected medium priority, got %s", subtask2.Priority)
+	}
+	// Dependencies should be updated to account for the new agent creation subtask
+	if len(subtask2.Dependencies) != 1 || subtask2.Dependencies[0] != "1" {
+		t.Errorf("Expected dependencies [1] (updated for agent creation), got %v", subtask2.Dependencies)
+	}
+	if len(subtask2.RequiredSkills) != 2 {
+		t.Errorf("Expected 2 required skills, got %d", len(subtask2.RequiredSkills))
+	}
+
+	// Total hours should include agent creation time (4 hours)
+	if analysis.EstimatedTotalHours != 28 {
+		t.Errorf("Expected 28 total hours, got %d", analysis.EstimatedTotalHours)
+	}
+}
+
+func TestAnalyzeTaskForSubtasks_InvalidJSON(t *testing.T) {
+	invalidResponse := "This is not valid JSON"
+
+	mockProvider := NewMockLLMProvider([]string{invalidResponse})
+	agentRoles := []string{"backend", "frontend"}
+	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
+
+	task := &tm.Task{
+		ID:    "test-task-123",
+		Title: "Test task",
+	}
+
+	_, err := service.AnalyzeTaskForSubtasks(context.Background(), task)
+	if err == nil {
+		t.Error("Expected error for invalid JSON, got nil")
+	}
+
+	if !strings.Contains(err.Error(), "no JSON found") {
+		t.Errorf("Expected 'no JSON found' error, got: %v", err)
+	}
+}
+
+func TestAnalyzeTaskForSubtasks_InvalidAgentRole(t *testing.T) {
+	jsonResponse := `{
+  "analysis_summary": "Test analysis",
+  "subtasks": [
+    {
+      "title": "Invalid Assignment",
+      "description": "Test subtask",
+      "priority": "high",
+      "assigned_to": "invalid_role",
+      "estimated_hours": 8,
+      "dependencies": []
+    }
+  ],
+  "recommended_approach": "Test approach",
+  "estimated_total_hours": 8
+}`
+
+	mockProvider := NewMockLLMProvider([]string{jsonResponse})
+	agentRoles := []string{"backend", "frontend"}
+	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
+
+	task := &tm.Task{
+		ID:    "test-task-123",
+		Title: "Test task",
+	}
+
+	analysis, err := service.AnalyzeTaskForSubtasks(context.Background(), task)
+	if err != nil {
+		t.Fatalf("AnalyzeTaskForSubtasks failed: %v", err)
+	}
+
+	// Should fix invalid agent assignment to first available role
+	if analysis.Subtasks[0].AssignedTo != "backend" {
+		t.Errorf("Expected fixed assignment 'backend', got %s", analysis.Subtasks[0].AssignedTo)
+	}
+}
+
+func TestGenerateSubtaskPR(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
+
+	analysis := &tm.SubtaskAnalysis{
+		ParentTaskID:        "task-123",
+		AnalysisSummary:     "Test analysis summary",
+		RecommendedApproach: "Test approach",
+		EstimatedTotalHours: 40,
+		RiskAssessment:      "Low risk",
+		Subtasks: []tm.SubtaskProposal{
+			{
+				Title:          "Test Subtask",
+				Description:    "Test description",
+				Priority:       tm.PriorityHigh,
+				AssignedTo:     "backend",
+				EstimatedHours: 8,
+				Dependencies:   []string{},
+			},
+		},
+	}
+
+	// Test that PR generation fails when no PR provider is configured
+	_, err := service.GenerateSubtaskPR(context.Background(), analysis)
+	if err == nil {
+		t.Error("Expected error when PR provider not configured, got nil")
+	}
+
+	if !strings.Contains(err.Error(), "PR provider not configured") {
+		t.Errorf("Expected 'PR provider not configured' error, got: %v", err)
+	}
+}
+
+func TestBuildSubtaskAnalysisPrompt(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	agentRoles := []string{"backend", "frontend", "qa"}
+	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
+
+	task := &tm.Task{
+		Title:       "Build authentication system",
+		Description: "Implement user login and registration with OAuth",
+		Priority:    tm.PriorityHigh,
+		Status:      tm.StatusToDo,
+	}
+
+	prompt := service.buildSubtaskAnalysisPrompt(task)
+
+	if !strings.Contains(prompt, task.Title) {
+		t.Error("Prompt should contain task title")
+	}
+
+	if !strings.Contains(prompt, task.Description) {
+		t.Error("Prompt should contain task description")
+	}
+
+	if !strings.Contains(prompt, string(task.Priority)) {
+		t.Error("Prompt should contain task priority")
+	}
+
+	if !strings.Contains(prompt, string(task.Status)) {
+		t.Error("Prompt should contain task status")
+	}
+}
+
+func TestGetSubtaskAnalysisSystemPrompt(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	agentRoles := []string{"backend", "frontend", "qa", "devops"}
+	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
+
+	systemPrompt := service.getSubtaskAnalysisSystemPrompt()
+
+	if !strings.Contains(systemPrompt, "backend") {
+		t.Error("System prompt should contain backend role")
+	}
+
+	if !strings.Contains(systemPrompt, "frontend") {
+		t.Error("System prompt should contain frontend role")
+	}
+
+	if !strings.Contains(systemPrompt, "JSON") {
+		t.Error("System prompt should mention JSON format")
+	}
+
+	if !strings.Contains(systemPrompt, "subtasks") {
+		t.Error("System prompt should mention subtasks")
+	}
+}
+
+func TestIsValidAgentRole(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	agentRoles := []string{"backend", "frontend", "qa"}
+	service := NewSubtaskService(mockProvider, nil, agentRoles, nil, "example", "repo", nil, nil)
+
+	if !service.isValidAgentRole("backend") {
+		t.Error("'backend' should be a valid agent role")
+	}
+
+	if !service.isValidAgentRole("frontend") {
+		t.Error("'frontend' should be a valid agent role")
+	}
+
+	if service.isValidAgentRole("invalid") {
+		t.Error("'invalid' should not be a valid agent role")
+	}
+
+	if service.isValidAgentRole("") {
+		t.Error("Empty string should not be a valid agent role")
+	}
+}
+
+func TestParseSubtaskAnalysis_Priority(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
+
+	tests := []struct {
+		input    string
+		expected tm.TaskPriority
+	}{
+		{"high", tm.PriorityHigh},
+		{"HIGH", tm.PriorityHigh},
+		{"High", tm.PriorityHigh},
+		{"low", tm.PriorityLow},
+		{"LOW", tm.PriorityLow},
+		{"Low", tm.PriorityLow},
+		{"medium", tm.PriorityMedium},
+		{"MEDIUM", tm.PriorityMedium},
+		{"Medium", tm.PriorityMedium},
+		{"invalid", tm.PriorityMedium}, // default
+		{"", tm.PriorityMedium},        // default
+	}
+
+	for _, test := range tests {
+		jsonResponse := `{
+  "analysis_summary": "Test",
+  "subtasks": [{
+    "title": "Test",
+    "description": "Test",
+    "priority": "` + test.input + `",
+    "assigned_to": "backend",
+    "estimated_hours": 8,
+    "dependencies": []
+  }],
+  "recommended_approach": "Test",
+  "estimated_total_hours": 8
+}`
+
+		analysis, err := service.parseSubtaskAnalysis(jsonResponse, "test-task")
+		if err != nil {
+			t.Fatalf("parseSubtaskAnalysis failed for priority '%s': %v", test.input, err)
+		}
+
+		if len(analysis.Subtasks) != 1 {
+			t.Fatalf("Expected 1 subtask, got %d", len(analysis.Subtasks))
+		}
+
+		if analysis.Subtasks[0].Priority != test.expected {
+			t.Errorf("For priority '%s', expected %s, got %s",
+				test.input, test.expected, analysis.Subtasks[0].Priority)
+		}
+	}
+}
+
+func TestGenerateSubtaskFile(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
+
+	subtask := tm.SubtaskProposal{
+		Title:          "Implement API endpoints",
+		Description:    "Create REST API endpoints for user management",
+		Priority:       tm.PriorityHigh,
+		AssignedTo:     "backend",
+		EstimatedHours: 12,
+		Dependencies:   []string{"0"},
+		RequiredSkills: []string{"go", "rest_api"},
+	}
+
+	taskID := "parent-task-subtask-1"
+	parentTaskID := "parent-task"
+
+	content := service.generateSubtaskFile(subtask, taskID, parentTaskID)
+
+	// Verify YAML frontmatter
+	if !strings.Contains(content, "id: parent-task-subtask-1") {
+		t.Error("Generated file should contain task ID in frontmatter")
+	}
+	if !strings.Contains(content, "title: Implement API endpoints") {
+		t.Error("Generated file should contain task title in frontmatter")
+	}
+	if !strings.Contains(content, "assignee: backend") {
+		t.Error("Generated file should contain assignee in frontmatter")
+	}
+	if !strings.Contains(content, "status: todo") {
+		t.Error("Generated file should have 'todo' status")
+	}
+	if !strings.Contains(content, "priority: high") {
+		t.Error("Generated file should contain priority in frontmatter")
+	}
+	if !strings.Contains(content, "parent_task_id: parent-task") {
+		t.Error("Generated file should contain parent task ID")
+	}
+	if !strings.Contains(content, "estimated_hours: 12") {
+		t.Error("Generated file should contain estimated hours")
+	}
+
+	// Verify dependencies are converted properly
+	if !strings.Contains(content, "dependencies:") {
+		t.Error("Generated file should contain dependencies section")
+	}
+	if !strings.Contains(content, "- parent-task-subtask-1") {
+		t.Error("Dependencies should be converted to subtask IDs")
+	}
+
+	// Verify required skills
+	if !strings.Contains(content, "required_skills:") {
+		t.Error("Generated file should contain required skills section")
+	}
+	if !strings.Contains(content, "- go") {
+		t.Error("Generated file should contain required skills")
+	}
+
+	// Verify markdown content
+	if !strings.Contains(content, "# Task Description") {
+		t.Error("Generated file should contain markdown task description")
+	}
+	if !strings.Contains(content, "Create REST API endpoints for user management") {
+		t.Error("Generated file should contain task description in body")
+	}
+}
+
+func TestUpdateParentTaskAsCompleted(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
+
+	// Create a temporary task file for testing
+	taskContent := `---
+id: test-task-123
+title: Test Task
+description: A test task for validation
+assignee: backend
+status: todo
+priority: high
+created_at: 2024-01-01T10:00:00Z
+updated_at: 2024-01-01T10:00:00Z
+completed_at: null
+---
+
+# Task Description
+
+A test task for validation
+`
+
+	// Create temporary file
+	tmpFile, err := os.CreateTemp("", "test-task-*.md")
+	if err != nil {
+		t.Fatalf("Failed to create temp file: %v", err)
+	}
+	defer os.Remove(tmpFile.Name())
+
+	if err := os.WriteFile(tmpFile.Name(), []byte(taskContent), 0644); err != nil {
+		t.Fatalf("Failed to write temp file: %v", err)
+	}
+
+	// Create analysis with subtasks
+	analysis := &tm.SubtaskAnalysis{
+		ParentTaskID:        "test-task-123",
+		EstimatedTotalHours: 20,
+		Subtasks: []tm.SubtaskProposal{
+			{
+				Title:      "Subtask 1",
+				AssignedTo: "backend",
+			},
+			{
+				Title:      "Subtask 2",
+				AssignedTo: "frontend",
+			},
+		},
+	}
+
+	// Update the parent task
+	err = service.updateParentTaskAsCompleted(tmpFile.Name(), analysis)
+	if err != nil {
+		t.Fatalf("updateParentTaskAsCompleted failed: %v", err)
+	}
+
+	// Read the updated file
+	updatedContent, err := os.ReadFile(tmpFile.Name())
+	if err != nil {
+		t.Fatalf("Failed to read updated file: %v", err)
+	}
+
+	updatedString := string(updatedContent)
+
+	// Verify the status was changed to completed
+	if !strings.Contains(updatedString, "status: completed") {
+		t.Error("Updated file should contain 'status: completed'")
+	}
+
+	// Verify completed_at was set (should not be null)
+	if strings.Contains(updatedString, "completed_at: null") {
+		t.Error("Updated file should have completed_at timestamp, not null")
+	}
+
+	// Verify subtask information was added
+	if !strings.Contains(updatedString, "## Subtasks Created") {
+		t.Error("Updated file should contain subtasks information")
+	}
+
+	if !strings.Contains(updatedString, "test-task-123-subtask-1") {
+		t.Error("Updated file should reference created subtask IDs")
+	}
+
+	if !strings.Contains(updatedString, "**Total Estimated Hours:** 20") {
+		t.Error("Updated file should contain total estimated hours")
+	}
+}
+
+func TestClose(t *testing.T) {
+	mockProvider := NewMockLLMProvider([]string{})
+	service := NewSubtaskService(mockProvider, nil, []string{"backend"}, nil, "example", "repo", nil, nil)
+
+	err := service.Close()
+	if err != nil {
+		t.Errorf("Close should not return error, got: %v", err)
+	}
+}
+
+// Benchmark tests
+func BenchmarkAnalyzeTaskForSubtasks(b *testing.B) {
+	jsonResponse := `{
+  "analysis_summary": "Benchmark test",
+  "subtasks": [
+    {
+      "title": "Benchmark Subtask",
+      "description": "Benchmark description",
+      "priority": "high",
+      "assigned_to": "backend",
+      "estimated_hours": 8,
+      "dependencies": []
+    }
+  ],
+  "recommended_approach": "Benchmark approach",
+  "estimated_total_hours": 8
+}`
+
+	mockProvider := NewMockLLMProvider([]string{jsonResponse})
+	service := NewSubtaskService(mockProvider, nil, []string{"backend", "frontend"}, nil, "example", "repo", nil, nil)
+
+	task := &tm.Task{
+		ID:          "benchmark-task",
+		Title:       "Benchmark Task",
+		Description: "Task for benchmarking",
+		Priority:    tm.PriorityHigh,
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		// Reset mock provider for each iteration
+		mockProvider.callCount = 0
+		_, err := service.AnalyzeTaskForSubtasks(context.Background(), task)
+		if err != nil {
+			b.Fatalf("AnalyzeTaskForSubtasks failed: %v", err)
+		}
+	}
+}
