Claude-skills-kit okr-progress-narrator
Transform raw OKR data (metrics, percentages, notes) from files or pasted text into a readable narrative progress update for stakeholders. Use when preparing weekly or quarterly OKR reports, board updates, or team syncs. Triggers: 'okr update', 'narrate okr progress', 'stakeholder okr update', 'generate okr report', 'okr status update', 'окр апдейт', 'нарратив по OKR', 'прогресс-апдейт для стейкхолдеров', 'оформи OKR', 'прогресс по целям'.
git clone https://github.com/KirKruglov/claude-skills-kit
T=$(mktemp -d) && git clone --depth=1 https://github.com/KirKruglov/claude-skills-kit "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/okr-progress-narrator" ~/.claude/skills/kirkruglov-claude-skills-kit-okr-progress-narrator && rm -rf "$T"
skills/okr-progress-narrator/SKILL.mdOKR Progress Narrator
This skill takes raw OKR data — tables, lists, or free-form notes with objectives, key results, current values, and targets — and converts them into a structured narrative progress update in
okr-update-YYYY-MM-DD.md. The output is designed to be shared directly with stakeholders: executive summary, per-objective narrative, KR status table, risks, and next steps.
Input:
- OKR data as a file (
,.md
,.txt
) or pasted text in chat.csv - Optional: period label (Q1 2026, Sprint 12), audience (CEO, board, team), tone
Output:
— narrative update with executive summary, per-objective sections, and risk blockokr-update-YYYY-MM-DD.md
Language Detection
Detect the user's language from their message and OKR data:
- If Russian (or Cyrillic content): respond and write the output document in Russian, using the output template below with translated section headers (e.g., "Итоговая сводка", "Цели", "Ключевые риски", "Следующие шаги")
- If English: respond and write the output document in English with standard headers
- If ambiguous: use the language of the trigger phrase
- Translate objective/KR names to the output language if the source is mixed-language
Instructions
Step 1: Validate and Parse Input
-
Identify the input source:
- File path provided: Read the file. Supported formats:
,.md
,.txt.csv - Text pasted in chat: Use the message content directly
- No input provided: Ask the user via AskUserQuestion to provide OKR data (file or paste)
- File path provided: Read the file. Supported formats:
-
Parse OKR structure — detect one of these layouts:
- Markdown table: columns map to Objective / Key Result / Current / Target / %Progress / Status / Notes
- Indented list:
orObjective:
as headers,O1:
or- KR:
as childrenKR1.1: - CSV/TSV: use header row to identify columns
- Free-form text: extract Objective/KR pairs using keyword matching (Objective, Goal, KR, Key Result, Target, Цель, КР, Результат)
-
For each Key Result, identify:
- Name / description
- Current value (numeric or qualitative)
- Target value (if present)
- Direction: whether higher or lower values are better (default: higher is better)
- If metric name contains keywords like "churn", "rate" (in negative context), "cost", "time", "latency", "errors": assume lower is better
- Otherwise: higher is better
- % progress (compute if current + target present):
- If higher is better:
round(current / target * 100) - If lower is better and current ≤ target:
✅ exceeded (goal met) - If lower is better and current > target: shortfall percentage =
(used to classify severity, not as actual progress)round(((current - target) / target) * 100)
- If higher is better:
- Status (on track / at risk / off track) — use provided value, or derive from % (see Step 2)
- Notes / context (optional)
-
If file cannot be read or OKR structure is unrecognizable:
- Stop. Report: "Could not recognize OKR structure in [filename / input]. Please provide data with Objective and Key Result fields."
-
Capture optional parameters:
- Period: from user message or file metadata (e.g., "Q2 2026", "April")
- Audience: CEO / board / team / general (default: general)
- Tone: formal / conversational (default: formal)
- Focus: all / at-risk-only / highlights-only (default: all)
Step 2: Classify Status
For each Key Result:
- If status is explicitly provided in the data → use it as-is
- If status is absent but a qualitative marker is present (e.g., "done", "completed", "✅", "achieved"):
- Mark as
if the description indicates completion or overachievement✅ exceeded
- Mark as
- If status is absent but notes or context suggest risk (e.g., "blocked", "slipped", "at risk", "delayed", "behind"):
- Mark as
(even if percentage is on track)🟡 at risk - Exception: if notes clearly describe a temporary issue and the underlying metrics are strong, use percentage-based classification
- Mark as
- If status is absent but % progress is computable:
- For "higher is better" metrics:
- Determine metric category and apply appropriate threshold:
- Business-critical metrics (keywords: "revenue", "MRR", "ARR", "sales", "deal", "customer value", "engagement", "retention", "growth"): ≥ 85% on track
- All other operational/technical metrics: ≥ 70% on track
- Based on category:
- ≥ threshold:
🟢 on track - 50%–(threshold-1)%:
🟡 at risk - < 50%:
🔴 off track -
100%:
✅ exceeded
- ≥ threshold:
- Determine metric category and apply appropriate threshold:
- For "lower is better" metrics (e.g., churn, cost, latency):
- If current ≤ target:
(goal met)✅ exceeded - If current > target: classify by shortfall percentage =
((current - target) / target) * 100- Shortfall > 20%:
(significantly worse than target)🔴 off track - Shortfall 10–20%:
(moderately worse than target)🟡 at risk - Shortfall ≤ 10%:
(slightly worse but within acceptable margin)🟢 on track
- Shortfall > 20%:
- If current ≤ target:
- For "higher is better" metrics:
- If neither status nor numeric data is available:
- Mark as
— do not invent a status⬜ no data
- Mark as
Derive Objective status:
- 🟢 if all KRs are on track or exceeded
- 🟡 if any KR is at risk
- 🔴 if any KR is off track
- ⬜ if all KRs have no data
Step 3: Generate Narrative
For each Objective:
-
Write a narrative paragraph (2–4 sentences):
- What has been achieved so far
- What the current state implies (momentum, risk, or completion)
- If notes/context are available → weave them in naturally
- Do NOT repeat exact numbers already shown in the KR table
- Do NOT invent reasons for low progress if not provided in data
-
Adapt to audience:
- CEO / board:
- Lead with business impact and strategic implications
- Skip implementation details, engineering blockers, tactical issues
- Use outcome-focused language: "revenue target within reach", "market opportunity", "delivery risk identified", "strategic pivot needed"
- Emphasize why each KR matters to the business
- For at-risk items: state the business impact and mitigation approach (if known)
- Team: Include operational detail, blockers, dependencies, and next steps if present
- General (default): Neutral business tone. Balanced detail — progress + context without excessive implementation specifics
- CEO / board:
-
Apply focus filter if specified:
: include only 🟡 and 🔴 objectives in per-objective sectionsat-risk-only
: include only 🟢 and ✅ objectiveshighlights-only
(default): include all objectivesall
Edge Cases:
- KR with % > 100: show as-is, mark
, phrase as achievement in narrative (e.g., "exceeded target by X%")✅ exceeded - KR with no numeric data and no notes: write "Data not yet reported for this period"
- All KRs are 🟢 or ✅: omit "Key Risks" section entirely; do not force a risk if none exists
- Only 1 KR with no parent Objective: group under a generic "Overall Metrics" (or in Russian: "Ключевые метрики") objective header; create a single objective section
- Mixed languages in data (EN objective names + RU notes): normalize to the output language (use output language setting from Step 1); translate objective/KR names and notes if needed
Step 4: Generate Executive Summary
Write 2–4 sentences covering:
- How many objectives are on track / at risk / off track (e.g., "2 of 3 objectives are on track")
- Top highlight: the best-performing KR or achieved milestone
- Top risk: the most critical at-risk or off-track item (skip if none)
Keep the summary self-contained — it should make sense without reading the full document.
Step 5: Compile Document
Assemble the output using the template below. Apply these rules:
- Omit "Key Risks" section if all KRs are on track (🟢) or exceeded (✅); always include it if any KR is 🟡 or 🔴
- Omit "Next Steps" section if no next-step data, action items, or blockers are present in the input or notes
- Use period label if provided (e.g., "Q2 2026", "April"); otherwise use "Current Period"
- Round all percentages to nearest whole number
- If audience is CEO: ensure narrative is outcome-focused and strategic; remove tactical details
Step 6: Save Output
- Write file as
(today's date)okr-update-YYYY-MM-DD.md - Save to:
- The folder containing the input file (if file was provided)
- The working directory (if text was pasted)
- Confirm: "Saved: okr-update-[date].md — [N] objectives, [N] KRs. [N] at risk."
Output Format
# OKR Progress Update — [Period] **Prepared:** YYYY-MM-DD **Audience:** [if specified] --- ## Executive Summary [2–4 sentences: overall status, top highlight, top risk] --- ## Objectives ### [Objective 1 Name] — 🟢 On Track [Narrative paragraph: 2–4 sentences on progress, momentum, notable context] | Key Result | Current | Target | Progress | Status | |------------|---------|--------|----------|--------| | [KR 1.1] | [value] | [value]| [%] | 🟢 | | [KR 1.2] | [value] | [value]| [%] | 🟡 | --- ### [Objective 2 Name] — 🔴 Off Track [Narrative paragraph] | Key Result | Current | Target | Progress | Status | |------------|---------|--------|----------|--------| | [KR 2.1] | [value] | [value]| [%] | 🔴 | --- ## Key Risks | Key Result | Objective | Status | Context | |------------|-----------|--------|---------| | [KR name] | [O name] | 🔴 | [note] | --- ## Next Steps - [Next planned action if present in data] --- *Generated by okr-progress-narrator · [date]*
Negative Cases
- No input provided → ask for OKR data via AskUserQuestion; do not generate a blank document
- File path provided but file does not exist → stop; report exact path checked; ask user to verify
- Input file has no recognizable OKR structure → stop; report the file name; suggest format hint
- All objectives have no data (
) → generate document but flag in Executive Summary: "No quantitative data available for this period — narrative based on qualitative notes only"⬜ - Period specified but data appears to be from a different period → include a note: "Note: data timestamps suggest this may be from [inferred period]. Review before sharing."