Kickoff Deck
Generate a Project+ kickoff deck .pptx. Draft-first: parse what the user gave, fill the schema with facts + TBDs, run the script. Only interview if the user explicitly asks.
Hard rules
Never invent. No made-up metrics, dates, names, risks, or commitments. Unknown → [TBD — reason]. A kickoff deck shown to stakeholders with invented content damages PM credibility on day one.
Preserve exact time/date/quantity wording — by table. Never convert imprecision into precision to make a milestone or SLA look concrete.
| User said |
NEVER write |
Write |
| October |
October 31, end of October, 10/31 |
October |
| Q2 |
June 30, Q2 2026-06-30, end of June |
Q2 |
| end of April |
April 30, late April 2026 |
end of April |
| $150k |
$150,000, $150K USD |
$150k |
| ~6 months |
180 days, 6.0 months |
~6 months |
| zero downtime |
99.9% uptime, 99.99% SLA |
zero downtime |
Verbatim-grep check (mandatory pre-render step). Before emitting JSON, for every number, percentage, date, dollar figure, or SLA in your draft, search the user's original message for that exact token. If the token is not present literally, replace it with [TBD]. This converts "don't invent" from a principle into a mechanical check. "99.9% uptime" in the draft when Ken said only "zero downtime" fails this check — strip it.
Reporting-line managers are NOT team slide entries. "Marcus reports to Raj" → Raj does NOT appear on the team slide. Build a ban list from any name appearing only inside "X reports to Y", "under Y", "Y's report", "rolls up to Y", or "Y is X's manager" phrases. That ban list cannot appear on the team slide. The sponsor is the exception (and only if named separately from the reporting-line phrase).
Don't invent stakeholders from project keywords. "Finance dashboard" does NOT create a "Finance Team" bullet. Only list people/groups the user explicitly named.
Keep slides tight. Max 5 bullets per slide, ≤12 words per bullet. Kickoff decks are read aloud — cramped slides fail.
Run it
python3 scripts/create_kickoff.py --output "<dir>/<ProjectName>_Kickoff_v1.pptx" --source /tmp/source.txt <<'JSON'
{ ...schema... }
JSON
Pass --source <path> with the user's raw message text. The script will lint every \d+%, $\d+[kKmM]?, and calendar date in the draft against the source and add any unverified figures to the Draft Gaps slide with a ⚠ unverified marker. If you omit --source, linting is skipped (acceptable for testing, not acceptable for user deliverables).
Script handles all layout, TBD highlighting, Draft Gaps summary slide, figure linting, and open_questions.md when TBDs ≥ 5.
JSON schema
{
"header": {
"project_name": "string",
"project_manager": "string or [TBD]",
"sponsor": "string or [TBD]",
"date": "YYYY-MM-DD",
"version": "v1"
},
"vision": "1–2 sentences on why this project exists (from user's words)",
"objectives": [
"SMART-ish objective bullet or [TBD]"
],
"scope": {
"in_scope": ["bullet"],
"out_of_scope": ["bullet"]
},
"team": [
{"name": "string or [TBD]", "role": "string or [TBD]"}
],
"milestones": [
{"name": "string", "target": "date or phase wording or [TBD]"}
],
"risks": [
{"risk": "string", "mitigation": "string or [TBD]"}
],
"ways_of_working": {
"cadence": "e.g. weekly standup / biweekly steering / [TBD]",
"tools": "e.g. Slack #channel, Jira, email / [TBD]",
"decision_forum": "where decisions get made / [TBD]"
},
"asks": [
"what the PM needs from stakeholders today or [TBD]"
]
}
Arrays may be empty. Any string may be [TBD — reason]. Keep each bullet ≤12 words.
Before running the script, do a fidelity pass: for every name, date, metric, or risk, point to a verbatim phrase in the user's message. If you can't, replace with [TBD].
1---2name: kickoff-deck3description: Generate a Project+ style project kickoff deck as a .pptx — title, vision, objectives, scope, team, milestones, risks, ways of working, and asks. Use whenever a user needs to run or prepare for a project kickoff meeting — triggers include "kickoff deck", "kickoff slides", "kickoff presentation", "kickoff meeting", "project kickoff", "launch deck", or any context where a PM is formally introducing a new project to stakeholders and team. Enforces Project+ kickoff structure and prevents fabrication of metrics, dates, names, or commitments the user never stated.4---56# Kickoff Deck78Generate a Project+ kickoff deck .pptx. Draft-first: parse what the user gave, fill the schema with facts + TBDs, run the script. Only interview if the user explicitly asks.910## Hard rules11121. **Never invent.** No made-up metrics, dates, names, risks, or commitments. Unknown → `[TBD — reason]`. A kickoff deck shown to stakeholders with invented content damages PM credibility on day one.132. **Preserve exact time/date/quantity wording — by table.** Never convert imprecision into precision to make a milestone or SLA look concrete.1415 | User said | NEVER write | Write |16 |---|---|---|17 | October | October 31, end of October, 10/31 | October |18 | Q2 | June 30, Q2 2026-06-30, end of June | Q2 |19 | end of April | April 30, late April 2026 | end of April |20 | $150k | $150,000, $150K USD | $150k |21 | ~6 months | 180 days, 6.0 months | ~6 months |22 | zero downtime | 99.9% uptime, 99.99% SLA | zero downtime |23243. **Verbatim-grep check (mandatory pre-render step).** Before emitting JSON, for every number, percentage, date, dollar figure, or SLA in your draft, search the user's original message for that exact token. If the token is not present **literally**, replace it with `[TBD]`. This converts "don't invent" from a principle into a mechanical check. `"99.9% uptime"` in the draft when Ken said only `"zero downtime"` fails this check — strip it.254. **Reporting-line managers are NOT team slide entries.** *"Marcus reports to Raj"* → Raj does NOT appear on the team slide. Build a ban list from any name appearing only inside `"X reports to Y"`, `"under Y"`, `"Y's report"`, `"rolls up to Y"`, or `"Y is X's manager"` phrases. That ban list cannot appear on the team slide. The sponsor is the exception (and only if named separately from the reporting-line phrase).265. **Don't invent stakeholders from project keywords.** *"Finance dashboard"* does NOT create a "Finance Team" bullet. Only list people/groups the user explicitly named.276. **Keep slides tight.** Max 5 bullets per slide, ≤12 words per bullet. Kickoff decks are read aloud — cramped slides fail.2829## Run it3031```bash32python3 scripts/create_kickoff.py --output "<dir>/<ProjectName>_Kickoff_v1.pptx" --source /tmp/source.txt <<'JSON'33{ ...schema... }34JSON35```3637Pass `--source <path>` with the user's raw message text. The script will lint every `\d+%`, `$\d+[kKmM]?`, and calendar date in the draft against the source and add any unverified figures to the Draft Gaps slide with a `⚠ unverified` marker. If you omit `--source`, linting is skipped (acceptable for testing, not acceptable for user deliverables).3839Script handles all layout, TBD highlighting, Draft Gaps summary slide, figure linting, and `open_questions.md` when TBDs ≥ 5.4041## JSON schema4243```json44{45 "header": {46 "project_name": "string",47 "project_manager": "string or [TBD]",48 "sponsor": "string or [TBD]",49 "date": "YYYY-MM-DD",50 "version": "v1"51 },52 "vision": "1–2 sentences on why this project exists (from user's words)",53 "objectives": [54 "SMART-ish objective bullet or [TBD]"55 ],56 "scope": {57 "in_scope": ["bullet"],58 "out_of_scope": ["bullet"]59 },60 "team": [61 {"name": "string or [TBD]", "role": "string or [TBD]"}62 ],63 "milestones": [64 {"name": "string", "target": "date or phase wording or [TBD]"}65 ],66 "risks": [67 {"risk": "string", "mitigation": "string or [TBD]"}68 ],69 "ways_of_working": {70 "cadence": "e.g. weekly standup / biweekly steering / [TBD]",71 "tools": "e.g. Slack #channel, Jira, email / [TBD]",72 "decision_forum": "where decisions get made / [TBD]"73 },74 "asks": [75 "what the PM needs from stakeholders today or [TBD]"76 ]77}78```7980Arrays may be empty. Any string may be `[TBD — reason]`. Keep each bullet ≤12 words.8182Before running the script, do a fidelity pass: for every name, date, metric, or risk, point to a verbatim phrase in the user's message. If you can't, replace with `[TBD]`.