Use when creating or adapting carve-out schedules with strict quality gates, phase milestones, task dependencies, and XLSX/XML outputs.
Schedule Generation
Purpose
Generate a project schedule as Excel workbook (XLSX) + MS Project XML from canonical script pattern. The XML generator (generate_msp_xml.py) requires a CSV — kept permanently alongside XLSX and XML.
Canonical Sources
generate_msp_xml.py — canonical CSV→XML converter; do NOT duplicate logic
Existing project generators (e.g. generate_bravo_schedule.py) — format/structure reference ONLY; never copy task lists, dates, resources, or project-specific content
Generation Steps
Create new generate_{ProjectName}_schedule.py script from scratch
Define TASKS list with all tasks, dates, durations, resources derived from current project parameters (start date, GoLive, completion date, sites, users, applications, carve-out model, TSA)
Plan realistic phase durations based on scope/complexity — do NOT reuse other projects' task lists
✗ No deployment waves (pre-packaged only, configured pre-QG4)
✗ No architecture changes
✗ No unplanned enhancements
Hypercare = support + stabilization ONLY.
Supporting Pre-GoLive Rules
ALL migrations complete before QG4: device reimaging, M365 migration, OneDrive migration, app waves, data segregation
Hypercare duration: static 90 calendar days minimum (never less), starts day after GoLive
Wave 2/3 post-GoLive: allowed ONLY if pre-packaged and pre-configured before QG4 (phased activation, not migration)
XML Output Rules — Critical (MS Project Import)
Generated via generate_msp_xml.py — do NOT hand-write XML.
Element
Correct
Wrong (Causes Issues)
<Duration>
PT{days*8}H0M0S (working hours)
P{days}D (calendar ISO — errors)
<Start>
20YY-MM-DDT08:00:00
T00:00:00 (wrong time)
<Finish> (normal)
20YY-MM-DDT17:00:00
T00:00:00 (wrong time)
<Finish> (milestone)
20YY-MM-DDT08:00:00
T17:00:00 (wrong time)
<DurationFormat>
7 (on every task)
Missing (parsing fails)
<Calendars>
Standard 5-day calendar
Missing (date drift)
<Resources>
All assigned resources
Missing (import fails)
<Assignments>
All assignments
Missing (unassigned)
XML Circular Reference Prevention
MS Project sets ALL durations to 0 on import if violated:
Never write <PredecessorLink> on summary tasks (level 1–2)
MS Project derives timing from children only
Creates circular scheduling
generate_msp_xml.py enforces: if is_summary: break
Never reference summary task ID as predecessor of detail task
Indirect circular reference (depends on own parent)
generate_msp_xml.py enforces: if pred_id in summary_ids: continue
First detail tasks of new phase → point to last DETAIL task of previous phase (not phase summary)
Gate milestones → reference last DETAIL task(s) of workstreams (not summaries)
Example: QG2&3 references final tasks of all Phase 2 workstreams (tasks 62, 68, 72, 75, 80), NOT workstream summaries
MS Project Element Ordering (Strict Sequence)
Missing or mis-ordered elements cause silent date drift (e.g. GoLive months late).
<Task><UID>…</UID><ID>…</ID><Name>…</Name><TaskMode>1</TaskMode><!-- MUST follow <Name> immediately --><Duration>PT…</Duration><DurationFormat>7</DurationFormat><ManualDuration>PT…</ManualDuration><Start>20YY-MM-DDT08:00:00</Start><ManualStart>20YY-MM-DDT08:00:00</ManualStart><Finish>20YY-MM-DDT…</Finish><ManualFinish>20YY-MM-DDT…</ManualFinish><OutlineLevel>…</OutlineLevel><Summary>…</Summary><Milestone>…</Milestone><ConstraintType>2</ConstraintType><!-- Must Start On (non-summary only) --><ConstraintDate>20YY-MM-DDT08:00:00</ConstraintDate><CalendarUID>-1</CalendarUID></Task>
Critical Rules:
<TaskMode>1</TaskMode> anywhere other than immediately after <Name> is silently ignored
<ManualStart> / <ManualFinish> are fields MS Project displays — <Start> / <Finish> alone insufficient
<ConstraintType>2</ConstraintType> + <ConstraintDate> provides hard date pin
Summary tasks should NOT have <ConstraintType> — inherit from children
Subprocess Pattern for generate_{ProjectName}_schedule.py
CSV_PATH = HERE / "active-projects" / PROJECT_NAME / f"{PROJECT_NAME}_Project_Schedule.csv"# In main:
_generate_excel()
_write_temp_csv(CSV_PATH)
result = subprocess.run([sys.executable, str(HERE / "generate_msp_xml.py"),
"--csv", str(CSV_PATH), "--out", str(XML_PATH),
"--project", PROJECT_NAME], capture_output=True, text=True)
if result.returncode != 0:
print(f"✗ XML generation failed:\n{result.stderr}")
sys.exit(1)
CSV kept permanently — do NOT use tempfile or delete
XLSX Formatting Standards (Bosch Blue Theme)
Row Type
Fill
Font
Bold
Header
#002147 (near-black blue)
White
Yes
Phase (L1)
#003B6E (dark Bosch blue)
White
Yes
Section (L2, non-milestone)
#0066CC (mid blue)
White
Yes
Milestone (any level)
#FFF2CC (amber)
Black
Yes
Detail (even)
#EFF4FB (light blue)
Black
No
Detail (odd)
White
Black
No
Additional:
Freeze pane on row 2 (below header)
Auto-filter on header row
Name indented by outline level (2 spaces per level beyond 1)
Milestone rows: always black bold (overrides section white-font rule)
Output Deliverables
Schedule complete only when all three files exist: