Generate project schedules with task dependencies, critical path analysis, resource constraints, and milestone planning in markdown format with Gantt representations and schedule optimization capabilities.
Generate project schedules with task dependencies, critical path analysis, resource constraints, and milestone planning in markdown format with Gantt representations and schedule optimization capabilities.
license
MIT
Plan.BuildSchedule Skill
Intent
Generate comprehensive project schedules based on task breakdowns and effort estimates, incorporating dependency management, critical path analysis, resource constraints, and milestone planning to create optimized project timelines with clear deliverable checkpoints and markdown-based Gantt chart visualizations.
Inputs
Source: projects/[project-name]/artifacts/Analysis/task-breakdown.json (generated by plan-derivetasks skill)
Source: projects/[project-name]/artifacts/Analysis/effort-estimates.json (generated by plan-estimateeffort skill)
Optional: Resource allocation constraints and team availability data
Optional: Project deadlines and milestone requirements from project charter
Format: Structured task and estimation data with dependencies and effort calculations
Outputs
Files Generated:
projects/[project-name]/artifacts/Analysis/project-schedule.json - Structured schedule data for programmatic use
projects/[project-name]/artifacts/Analysis/project-schedule.md - Human-readable schedule with Gantt representation
projects/[project-name]/artifacts/Analysis/critical-path-analysis.md - Critical path analysis and schedule optimization report
projects/[project-name]/artifacts/Analysis/milestone-plan.md - Milestone definitions and delivery checkpoints
defcalculate_early_times(tasks):
"""
Calculate Early Start (ES) and Early Finish (EF) for all tasks
"""# Topological sort to process tasks in dependency order
sorted_tasks = topological_sort(tasks)
for task in sorted_tasks:
ifnot task.predecessors:
# Tasks with no dependencies start at project start
task.early_start = project_start_date
else:
# ES = max(EF of all predecessors + lag)
predecessor_finishes = []
for pred in task.predecessors:
finish_time = pred.early_finish + pred.lag_to(task)
predecessor_finishes.append(finish_time)
task.early_start = max(predecessor_finishes)
# EF = ES + Duration
task.early_finish = task.early_start + task.duration
return tasks
Backward Pass Calculation
defcalculate_late_times(tasks):
"""
Calculate Late Start (LS) and Late Finish (LF) for all tasks
"""# Process tasks in reverse dependency order
sorted_tasks = reverse_topological_sort(tasks)
# Set project end date from latest early finish
project_end = max(task.early_finish for task in tasks)
for task in sorted_tasks:
ifnot task.successors:
# Tasks with no successors finish at project end
task.late_finish = project_end
else:
# LF = min(LS of all successors - lag)
successor_starts = []
for succ in task.successors:
start_time = succ.late_start - task.lag_to(succ)
successor_starts.append(start_time)
task.late_finish = min(successor_starts)
# LS = LF - Duration
task.late_start = task.late_finish - task.duration
# Calculate slack
task.total_slack = task.late_start - task.early_start
task.free_slack = min(succ.early_start for succ in task.successors) - task.early_finish
return tasks
3. Resource Leveling and Allocation
defapply_resource_leveling(schedule, resource_constraints):
"""
Level resources to smooth workload peaks and respect constraints
"""
leveled_schedule = copy.deepcopy(schedule)
# Identify resource overallocations by time period
resource_profile = build_resource_profile(schedule)
overallocations = identify_overallocations(resource_profile, resource_constraints)
for overallocation in overallocations:
# Find tasks that can be delayed (non-critical with slack)
delayable_tasks = find_delayable_tasks(overallocation.period, schedule)
# Sort by priority (least impactful to delay first)
prioritized_tasks = sort_by_delay_priority(delayable_tasks)
for task in prioritized_tasks:
if overallocation.resolved():
break# Delay task within its slack allowance
max_delay = min(task.total_slack, overallocation.excess_demand)
task.scheduled_start += max_delay
task.scheduled_finish += max_delay
# Update resource allocation
update_resource_profile(resource_profile, task, max_delay)
overallocation.reduce_excess(task.resource_demand * max_delay)
return leveled_schedule
4. Milestone Planning Algorithm
defgenerate_milestone_schedule(schedule, task_breakdown):
"""
Generate milestone schedule based on task completion and deliverables
"""
milestones = []
# Identify natural milestone candidates
milestone_candidates = identify_milestone_tasks(schedule, task_breakdown)
for candidate in milestone_candidates:
milestone = Milestone(
name=generate_milestone_name(candidate),
target_date=candidate.scheduled_finish,
deliverables=candidate.deliverables,
dependencies=find_milestone_dependencies(candidate, milestones)
)
# Assess milestone risk based on critical path proximity
milestone.risk_assessment = assess_milestone_risk(candidate, schedule)
milestones.append(milestone)
# Add phase completion milestonesfor phase in task_breakdown['phases']:
phase_tasks = get_phase_tasks(phase, schedule)
phase_completion = max(task.scheduled_finish for task in phase_tasks)
milestones.append(Milestone(
name=f"{phase['phase_name']} Completion",
target_date=phase_completion,
milestone_type='phase_completion',
deliverables=aggregate_phase_deliverables(phase_tasks)
))
return sort_milestones_chronologically(milestones)
5. Schedule Optimization Strategies
Fast Tracking
Identify tasks that can run in parallel instead of sequence
Assess risk of increased coordination overhead
Calculate time savings vs. risk increase
Crashing
Identify tasks where additional resources can reduce duration
Calculate cost-benefit of resource increases
Optimize resource allocation for maximum impact
Buffer Management
Add project buffers for uncertainty management
Distribute buffer time across critical and near-critical paths
Monitor buffer consumption during execution
Integration Workflow
1. Input Validation and Processing
defvalidate_inputs(task_breakdown, effort_estimates):
"""
Ensure input data is consistent and complete
"""# Verify all tasks in breakdown have effort estimates
missing_estimates = find_missing_estimates(task_breakdown, effort_estimates)
if missing_estimates:
raise ValueError(f"Missing effort estimates for tasks: {missing_estimates}")
# Check for circular dependencies
cycles = detect_dependency_cycles(task_breakdown['tasks'])
if cycles:
raise ValueError(f"Circular dependencies detected: {cycles}")
# Validate dependency references
validate_dependency_references(task_breakdown['tasks'])
returnTrue