agentsclimarketplace

Daily standup prep

Skill risadams/skills/daily-standup-prep

Generate a per-team standup markdown report by gathering activity over the last N days from Jira, GitLab, Confluence, and a local Git repo. Maps activity to team members from a roster CSV, renders a Mermaid kanban + randomized talking order, captures a `daily`-tagged sprint snapshot, and runs a clarity-council (infographics-expert burndown chart + statistics-expert forecast + scrum-master suggestions) for sprint pulse. Writes one file per team into the Obsidian vault. Use when the user says "daily standup prep", "standup report", "generate standup", "scrum prep", or invokes /daily-standup-prep.From its SKILL.md

Install
npx -y skills add risadams/skills --skill daily-standup-prep

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

30.6 KB, ~7.7k tokens by cl100k_base, as published. Nobody here has run it

Daily Standup Prep

Per-team standup report. Read-only across Jira, GitLab, Confluence, and Git. Writes one markdown file per team to the Obsidian vault.

This skill is a Claude Code port of D:\powershell-scripting\src\bin\Get-Standup-Report.ps1 — same inputs, same template placeholders, same output path layout, same identity-matching rules. See REFERENCE.md for the algorithm and per-section formatter contracts. See EXAMPLES.md for invocation parity with the PS script.

Quick start

/daily-standup-prep                                 → Pyrite, last 2 days, INC 25 / Sprint 1
/daily-standup-prep Onyx                            → single team
/daily-standup-prep Pyrite,Onyx --days 3 --inc 26   → multi-team, custom window
/daily-standup-prep --no-gitlab --no-confluence     → toggle sections off

Parameters

ParamDefaultMaps to PS
Teams["Pyrite"]-Teams (string[])
DaysToLookBack2-DaysToLookBack
JQLauto-built-JQL
GitRepoPathD:\paas\-GitRepoPath
Inc25-Inc
Sprint1-Sprint
IncludeJiraIssues / IncludeGitCommits / IncludeGitLabActivity / IncludeConfluenceActivity / IncludeKanbanDiagram / IncludeStandupOrderall truesame
IncludeSprintPulsetruenew — runs Phase 4.5 (daily snapshot + council burndown/forecast/suggestions). Toggle off with --no-sprint-pulse

JIRA base, Confluence base, GitLab base + group, vault root, and template path are all resolved from memory — never accept them as args. See Config resolution below.

Config resolution (run once at the start of every invocation)

PlaceholderMemory fileDefault content / how to populate
{{vault_root}}reference_obsidian_vault.md (**Vault root:** line)C:\Users\chris.adams\dev\gd-pkms\ — already populated
{{jira_project}}reference_jira_default_project.md (**Default Jira project key:** line)SC2 — already populated
{{confluence_space}}reference_confluence_default_space.mdPP — already populated
{{gitlab_base_url}}reference_gitlab_config.md (**GitLab base URL:** line)If <unset>, prompt and persist https://gdgitlab01.gd-ms.us (the PS-script default)
{{gitlab.bessemer}}same memory, Common project paths tableIf absent, prompt and add a row: bessemerbessemer (group path)
{{template_path}}derived{{vault_root}}\🗃Templates\Standup.md (no separate memory)
{{rosters_dir}}derived{{vault_root}}\Scrum Teams\_rosters\
{{output_root}}derived{{vault_root}}\Scrum Teams\ (per-team subfolder appended later)

If a memory file is missing or its value is <unset>, prompt once via AskUserQuestion with the PS-script default as the recommended option, then write the answer back so the next run skips the prompt. Same pattern as daily-briefing.

Roster bootstrap (first-run only)

The PS script reads D:\powershell-scripting\src\bin\Teams\<Team>.csv. We move ownership of those CSVs into the vault so the user maintains them in one place going forward.

For each team in the run:

  1. Look for {{rosters_dir}}\<Team>.csv (case-insensitive). If present, use it.
  2. If missing and D:\powershell-scripting\src\bin\Teams\<Team>.csv exists, prompt via AskUserQuestion: "No roster found at {{rosters_dir}}\<Team>.csv. Copy from the powershell-scripting repo?" — options: Copy (recommended), Use repo path this run only, Skip team.
  3. On Copy: mkdir -p "{{rosters_dir}}", then copy the file. Tell the user the new path is the canonical location going forward.
  4. If neither path exists, skip the team and warn — do not invent a roster.

CSV format is the same headerless layout the PS Team-Helpers module uses: FullName,Email,Alias,Role,Flags. Lines starting with // and blanks are ignored. Alias and Flags accept ;-separated values. See REFERENCE.md.

Workflow (per team)

Loop the steps below for each team in Teams. Each iteration is independent — one file per team, matching the PS script's $teamsToProcess | ForEach-Object block.

Per-team progress:
- [ ] Phase 1: Resolve config + load roster
- [ ] Phase 2: Compute window + auto-build JQL
- [ ] Phase 3: Gather data (Jira, Git, GitLab, Confluence) — parallel
- [ ] Phase 4: Match activity to team members + flag HasActivity
- [ ] Phase 4.5: Sprint pulse — daily snapshot + council (burndown / forecast / suggestions)
- [ ] Phase 5: Render section markdown + Mermaid kanban + talking order
- [ ] Phase 6: Substitute template placeholders + write to vault
- [ ] Phase 7: Console summary

Phase 1 — Config + roster

Resolve every {{placeholder}} per the table above. Load the roster CSV into a list of {FullName, FirstName, LastName, JiraName, Email, Alias[], DisplayFirstName, Role, Flags[]} records — derive JiraName = "{Last}, {First}" and DisplayFirstName = Alias[0] ?? FirstName. Tag each member with HasActivity = false and empty Issues / Commits / GitLabActivities / ConfluenceActivities lists.

Phase 2 — Window + JQL

  • activity_since = midnight (Pittsburgh local) DaysToLookBack days ago.
  • since_iso = YYYY-MM-DDTHH:mm:ssZ for GitLab/Confluence cutoffs.
  • since_date = YYYY-MM-DD for git log --since.
  • If JQL arg is empty: build project = {{jira_project}} AND updated >= startOfDay(-{N}d) where N = DaysToLookBack.

State the chosen window in one short sentence: "Gathering Pyrite standup for window 2026-05-11 → 2026-05-13 (2-day lookback)."

Phase 3 — Gather data (parallel)

Issue these MCP/Bash calls in a single response when section toggles allow:

  • Jira issues (IncludeJiraIssues or IncludeKanbanDiagram): jira_search(jql=<jql>, fields="summary,status,assignee,issuetype,updated") with pagination to a sane cap. For each result, follow up with jira_get_changelog and jira_get_comments only when the issue's updated is within the window — skip the fetch otherwise to save tokens.
  • Jira kanban (IncludeKanbanDiagram only): second jira_search with project = {{jira_project}} AND sprint in openSprints() AND labels in ({lowercase team names}). Capture key, summary, status, assignee.displayName, issuetype.name.
  • GitLab MRs + discussions (IncludeGitLabActivity):
    1. list_group_projects(group_id="{{gitlab.bessemer}}") to get all project IDs in the group (subgroups included).
    2. For each project: list_merge_requests(project_id, updated_after=<since_iso>, per_page=100).
    3. For each MR: mr_discussions(project_id, merge_request_iid) capped at 100 notes.
  • GitLab pipelines (IncludeGitLabActivity): for each project, list_pipelines(project_id, updated_after=<since_iso>, per_page=100). For each, get_pipeline(project_id, pipeline_id) to read the triggering user.
  • Confluence pages (IncludeConfluenceActivity): confluence_search(cql="lastModified >= '{since_date}' AND space = {{confluence_space}}"). For each, confluence_get_page(page_id, expand="history.lastUpdated,version,space,body.view").
  • Git commits (IncludeGitCommits): Bash sequence — confirm {{git_repo}}\.git exists; git -C "{{git_repo}}" fetch --all; git -C "{{git_repo}}" log --all --since="{since_date}" --pretty=format:"%H|%an|%ae|%aI|%s". Parse pipe-delimited lines.

If any external system fails to respond, log a warning and continue with empty results for that section — never fabricate. If IncludeKanbanDiagram is on but Jira fails, render _No kanban data — Jira unavailable._ rather than skipping the placeholder.

Phase 4 — Match activity to team members

Use the cascading 8-strategy matcher described in REFERENCE.md. For every activity record, attempt to match by (email, displayName, username) — Jira gives email + displayName; GitLab gives email + name + username; Confluence gives email + displayName; Git gives email + author name only.

Filter rules:

  • Jira issue inclusion — keep an issue iff its assignee matches a team member OR any comment/changelog entry within the window was authored by a team member. (Direct port of the PS $isAssignedToTeamMember -or $hasRecentActivity filter.)
  • Git/GitLab/Confluence inclusion — keep an activity iff its author matches a team member.
  • Set member.HasActivity = true for any matched member, and append the activity to the member's Issues / Commits / GitLabActivities / ConfluenceActivities lists for the talking-order/per-member sections.

Phase 4.5 — Sprint pulse (daily snapshot + council)

Skip entirely if IncludeSprintPulse is off — substitute empty strings for the three pulse placeholders in Phase 6.

Step 1 — Daily sprint snapshot. Invoke the sprint-snapshot skill via Skill for the current team with --phase "daily". This writes daily.canvas + daily.md to the team's current sprint folder (overwriting yesterday's daily.* is fine — the trend record lives in _snapshots.jsonl) and appends a row to that JSONL trend log. The JSONL is the burndown's data source. If sprint-snapshot fails (Jira down, sprint config missing, etc.), surface the failure in the console summary, render _Sprint pulse unavailable — daily snapshot failed._ for {{burndown_chart}}, leave the other two pulse placeholders empty, and continue. Never fabricate trend data.

Step 2 — Read trend data. Read the team's _snapshots.jsonl from {{output_root}}\<TeamTitleCase>\Scrum 📅\INC {Inc}\Sprint {Sprint}\_snapshots.jsonl. Parse the rows for the current sprint only (filter by inc + sprint). Extract (snapshot_at, remaining, totals.points, by_status.done.points) per row. Also pull capacity, velocity.last, and velocity.avg3 from the most recent row. If the JSONL has fewer than 2 rows for this sprint, the burndown will be a single point — note this in the rendered output, do not fake additional data points.

Step 3 — Run clarity-council. Invoke the clarity-council skill via Skill with three personas: infographics-expert, statistics-expert, scrum-master. Pass the parsed JSONL trend rows, sprint config (StartDate, EndDate, Capacity, LastSprintVelocity, AvgVelocityLast3), the day count (day X of 21), and the current matched-activity summary from Phase 4 as the council's shared context. Ask each persona for a tightly scoped artifact:

  • infographics-expert → render an Obsidian Charts plugin burn-up chart following the exact shape below. The chart uses a chart code fence (Chart.js backend via the obsidian-charts community plugin, which must be installed in the vault). Burn-up (not burn-down) is the canonical shape because it visualizes scope changes explicitly — your sprints regularly take +20–40 pts of scope creep, which burn-down folds into a misleading "remaining" line.

    Burn-up chart contract (must be followed verbatim; no creative reinterpretation):

    1. Determine actual data points. From the JSONL trend rows, build a list samples = [(day_n, scope_points, done_points), …] where day_n is integer days since StartDate (Pittsburgh local, day_0 = StartDate), scope_points = totals.points, done_points = by_status.done.points. Sort by day_n. De-duplicate by day_n keeping the latest snapshot_at per row.
    2. Build the x-axis. Full sprint range — x_axis = list(range(0, sprint_length_days + 1)) where sprint_length_days = (EndDate - StartDate).days. The x-axis always spans day 0 → day sprint_length_days, regardless of how far into the sprint we are.
    3. Build the actual scope series. For each day_n in x_axis:
      • If day_n ≤ today_n AND a sample exists for day_n: use the sample's scope_points.
      • If day_n ≤ today_n AND no sample exists (weekend/holiday/gap): carry forward the previous day's scope_points value (last-known wins).
      • If day_n > today_n (future): emit null.
    4. Build the actual done series. Same logic as scope, but using done_points. Day 0 defaults to 0 if no sample exists.
    5. Build the pinned scope series (visually distinct future segment). For each day_n in x_axis:
      • If day_n < today_n: emit null.
      • If day_n ≥ today_n: emit today's actual scope_points. (The series starts at today's point so the line connects visually from the actual series.)
    6. Build the pinned done series. Same logic as pinned scope, but using done_points.
    7. Build the capacity reference series. Constant Capacity across all len(x_axis) days.
    8. Y-axis bounds. y_min = 0, y_max = ceil(max(all actual scope values + [Capacity]) * 1.1) so the highest point isn't flush with the top edge.
    9. Title. None at the chart level (the markdown heading carries it). Set the surrounding section heading to ### Burn-up.
    10. Validate before emitting. Confirm all five series have length len(x_axis); confirm null is used (not None / NaN / empty string) for future-day gaps in the "actual" series and past-day gaps in the "pinned" series; confirm every non-null value is finite and inside [y_min, y_max]. If any check fails, do not emit the chart — emit a one-line markdown note explaining what failed, and surface it so the run can be debugged.

    Reference template (substitute the computed values; this is the only acceptable shape):

    ### Burn-up
    
    ```chart
    type: line
    labels: ["0","1","2",...,"<sprint_length_days>"]
    series:
      - title: "Scope (actual)"
        data: [<scope values for days 0..today_n; null for days today_n+1..end>]
      - title: "Done (actual)"
        data: [<done values for days 0..today_n; null for days today_n+1..end>]
      - title: "Scope (pinned — no future data)"
        data: [<null for days 0..today_n-1; today's scope repeated for days today_n..end>]
      - title: "Done (pinned — no future data)"
        data: [<null for days 0..today_n-1; today's done repeated for days today_n..end>]
      - title: "Capacity (<Capacity> pts)"
        data: [<Capacity repeated len(x_axis) times>]
    tension: 0.2
    width: 100%
    labelColors: false
    fill: false
    beginAtZero: true
    bestFit: false
    yTitle: "Points"
    xTitle: "Sprint day (0 = <StartDate>, <sprint_length_days> = <EndDate> close)"
    yMin: 0
    yMax: <y_max>
    ```
    
    **Reading the chart**:
    
    - **Solid lines (days 0–<today_n>)** = actual snapshot data. <One-sentence summary of scope trajectory: trim, creep, what drove changes>. Done climbs ~<observed pts/day> pts/day average.
    - **Past gaps** (if any: weekend/holiday days with no snapshot) are carry-forward — value held from the previous day.
    - **Pinned lines (days <today_n>–<sprint_length_days>)** = today's values held flat, NOT a forecast. The visible gap between Scope (<today_scope>) and Done (<today_done>) at day <sprint_length_days> = ~<gap> pts that would land in next sprint at observed cadence.
    - **Capacity (<Capacity> pts)** = horizontal reference; scope is currently <+/-N> vs capacity.
    - **What it would take to close the sprint**: done line would need to climb +<gap> pts in <days_remaining> days (~<required pts/day> pts/day) — <compare to historical velocity>. <Sprint N+1 carry-over recommendation if gap > observed-cadence × days-remaining>.
    

    Chart.js (via the obsidian-charts plugin) renders each series in a distinct color, so the "actual" and "pinned" segments are visually different even though they share the chart. The null values create true gaps in the line, so past/future are visually separate. Do not add chartjs: style overrides unless the user explicitly asks — the default rendering is the canonical shape.

    Plugin dependency. The chart code fence requires the obsidian-charts community plugin enabled in the vault (folder: {{vault_root}}/.obsidian/plugins/obsidian-charts/). On first run, verify via Glob that the plugin folder exists. If missing, surface a one-line warning in the console summary and emit the chart anyway — Obsidian will render the raw YAML as a code block until the plugin is installed, which is recoverable. Do not fall back to Mermaid xychart-beta — the historical shape is inferior and the user has explicitly chosen Charts plugin going forward.

    Single-sample case. If only one trend row exists, day 0 acts as the implicit second point: Scope (actual) = [<sample.scope>, ..., null after sample.day_n], Done (actual) = [0, ..., <sample.done>, ..., null after sample.day_n]. The pinned series start at sample.day_n. Caption appends: _First snapshot at day <N> — trend will fill in over coming days._

  • statistics-expert → produce a single-paragraph forecast: project end-of-sprint completed points using simple linear extrapolation from the trend, compare against Capacity and velocity.avg3, and state a confidence band (e.g. "tracking 5pts under commit, ±3pts based on 3-sprint variance"). Hard cap: ≤4 sentences. No charts — words only. Must explicitly call out if the trend data is too sparse to forecast (≤2 rows).

  • scrum-master → 1–3 actionable suggestions for the team based on the day's matched activity (Phase 4) + the snapshot bucket counts. Examples: "two tickets in In Review for >3 days — chase reviewers", "Ada has no activity tracked in 2 days — confirm not blocked", "WIP at 8 vs limit 5 — pull from Ready before starting new". Bullet list. No vague platitudes — each suggestion names a ticket, person, or measurable signal.

Step 4 — Capture artifacts. Store the three council outputs as the strings {{burndown_chart}} (the Obsidian Charts chart code fence including its ```chart opening and closing ``` fences, followed by the "Reading the chart" markdown block — see infographics-expert contract above), {{forecast_note}} (the statistics-expert paragraph, plain markdown), and {{scrum_suggestions}} (the bullet list, plain markdown). These feed Phase 6. The placeholder name {{burndown_chart}} is retained for template-backward-compatibility — its content is a burn-up chart per the v2 contract. The vault-side Standup template at {{vault_root}}/🗃Templates/Standup.md does not need to change; the substitution drops the new chart shape into the existing slot.

Phase 5 — Render sections

Each placeholder in the template gets a string built from the matched data. Formatter contracts (exact markdown shape) live in REFERENCE.md:

  • {{talking_order}} — randomized active members () first, inactive (🧽) last. Each line - [ ] [[@First Last]] - ✅ (or 🧽). Multi-team runs append (TeamName) after the wikilink. If IncludeStandupOrder is off, leave the placeholder empty.
  • {{jira_state}} — Mermaid flowchart with five status columns (Blocked / Ready / In Progress / In Review / Done). Spec in REFERENCE.md. If IncludeKanbanDiagram is off, empty.
  • {{jira_issues}} — per-issue blocks with ### KEY - Summary, type/status/assignee line, then a bulleted activity log of (date) WHO / WHAT / WHY plus text code fences for details.
  • {{git_updates}} — per-member blocks ### [[@First Last]] then - (date) hash7 - message lines, sorted desc by date.
  • {{gitlab_updates}} — three subsections (## Merge Request Activity, ## Comment Activity, ## Pipeline Activity) only if non-empty; otherwise the placeholder line _No GitLab activity found in the specified time period._.
  • {{confluence_updates}} — per-page blocks with title + space tag, type/last-modified/author line, link, and a content snippet (first 200 chars of stripped HTML in a text code fence).

Phase 6 — Substitute and write

  1. Read {{template_path}}. The template is the user's master Standup template — never modify it.
  2. Replace placeholders in this exact set (matches the PS ConvertTo-TemplateMarkdown function plus the three Phase 4.5 additions): {{date}}, {{team}}, {{sprint}}, {{increment}}, {{talking_order}}, {{jira_state}}, {{jira_issues}}, {{git_updates}}, {{confluence_updates}}, {{gitlab_updates}}, {{burndown_chart}}, {{forecast_note}}, {{scrum_suggestions}}. Date format YYYY-MM-DD (Pittsburgh local). Team name written TitleCase (first char upper, rest lower) to match the PS $formattedTeam line. The three pulse placeholders are no-ops if the user's template doesn't reference them — the substitution still runs cleanly. Note this once when a template lacks them so the user knows to add them if they want the pulse rendered (e.g. under a ## Sprint Pulse heading containing {{burndown_chart}}, then ### Forecast {{forecast_note}}, then ### Suggestions {{scrum_suggestions}}).
  3. Compute output path: {{vault_root}}\Scrum Teams\<TeamTitleCase>\Scrum 📅\INC {Inc}\Sprint {Sprint}\YYYY-MM-DD.md — note the 📅 emoji is preserved literally; forward slashes work fine in bash on Windows.
  4. mkdir -p the parent directory.
  5. Never overwrite silently. If the file exists, Read it, then AskUserQuestion: Overwrite / Append as ## Re-run HH:MM section / Skip save.
  6. Write the file. Print the saved path back as a clickable markdown link.

Sibling-skill delegation in Phase 4.5 / Phase 6:

  • The daily snapshot is always delegated to sprint-snapshot via Skill with --phase "daily". Never reimplement Jira sprint fetching inline — sprint-snapshot owns the JQL, identity matching, capacity math, and the JSONL trend schema. If its phase derivation logic doesn't recognize daily, pass it through as an explicit --phase override (the skill already supports arbitrary phase strings via that flag).

  • The pulse council is always delegated to clarity-council via Skill with personas pinned to infographics-expert + statistics-expert + scrum-master. Do not author burndown SVG/Mermaid, forecast paragraphs, or suggestions inline — let each persona produce its own artifact under its own constraints.

  • If extending the template with new Obsidian Flavored Markdown constructs (callouts, embeds, dataview, block IDs, frontmatter properties beyond Increment/Sprint/Date), invoke obsidian-markdown via Skill rather than authoring the syntax inline — it's the canonical reference and stays in sync with vault conventions.

  • For wikilink target verification (the [[@First Last]] rule in talking_order / git_updates), prefer delegating the lookup to obsidian-vault if the run will need to verify many person notes — its search is more efficient than repeated Glob calls. For a single team run (≤15 lookups) the inline Glob is fine.

  • If the user later wants a dashboard .base file that aggregates team standups (e.g. "all standups for Pyrite this sprint"), invoke obsidian-bases rather than hand-authoring the YAML.

  • For CLI-driven vault inspection (e.g. checking note frontmatter, running a vault-wide property query before deciding whether to overwrite), invoke obsidian-cli — it has direct property/task access that Read+Glob cannot replicate cheaply.

Phase 7 — Console summary

Print a brief block per team (matches the PS === REPORT GENERATION SUMMARY === block):

=== <Team> standup report ===
Team members loaded: N
Jira issues included: N (of M scanned)
Git commits matched: N
GitLab activities matched: N
Confluence activities matched: N
Sprint pulse: snapshot=<ok|failed|skipped> · trend rows=N · council=<ok|failed|skipped>
Saved: <markdown link>

Rules

  • Read-only across Jira, GitLab, Confluence. Never transition issues, post comments, approve MRs, edit pages, or modify any external state.
  • Read-only on the Git repo. fetch and log only — never checkout, pull, or merge.
  • No vault writes outside Scrum Teams/. The template at 🗃Templates/Standup.md is read-only too.
  • Never overwrite an existing standup file silently. Always confirm via AskUserQuestion.
  • Confirm before persisting to memory. When populating an <unset> value (GitLab base URL, etc.), use the PS-script default as the recommended option but let the user override before writing.
  • Wikilinks for team members only when the vault person note exists. Use Glob("{{vault_root}}/🤼 Team/**/@*.md") to verify before writing [[@First Last]]. If the vault has no canonical note for a roster member, render plain text — don't pollute the graph with broken links.
  • TitleCase team names in output. pyritePyrite (first char upper, rest lower) — matches the PS $formattedTeam line so vault paths and frontmatter stay consistent.
  • Pittsburgh local time. All Date columns and the filename use America/New_York. The git log %aI and ISO timestamps from Jira/GitLab/Confluence are converted before display.
  • Section toggle semantics match the PS script. Skipping a section (e.g., --no-gitlab) means: don't gather, don't fetch, and substitute an empty string for the placeholder — the template still resolves cleanly.
  • No fabricated data. If an MCP fails, surface the failure in the console summary and put a _<system> unavailable_ note in the corresponding section. Do not invent.
  • Sprint pulse is delegated, never inlined. The daily snapshot must come from sprint-snapshot and the burndown/forecast/suggestions must come from clarity-council's three pinned personas. Do not author burndown charts, forecasts, or scrum-master suggestions inline — that bypasses the persona constraints (infographics-expert's chartjunk rules, statistics-expert's confidence-band requirement, etc.) that make these artifacts trustworthy.
  • Burndown trend data is read-only and append-only. Phase 4.5 reads _snapshots.jsonl to feed the chart but never edits past rows. Past daily.canvas / daily.md are allowed to be overwritten — the trend record lives in the JSONL.

Edge cases

  • No team members loaded — warn and skip the team. Don't render an empty report (matches PS if ($teamMembers.Count -eq 0) guard).
  • Roster CSV missing for one of N teams — process the others; warn for the missing one.
  • Vault 🤼 Team folder doesn't have a @First Last.md note for a roster member — render plain First Last instead of a wikilink in {{talking_order}} and {{git_updates}}.
  • Git repo not present at {{git_repo}} — skip git commit collection silently; render an empty {{git_updates}} section.
  • Jira sprint label missing for the team (kanban query returns 0) — render _No <Team> items found in current sprint._ for {{jira_state}}.
  • GitLab bessemer group returns 0 projects — surface a warning; the user may have lost group membership. Render _No GitLab activity found in the specified time period._.
  • Re-run on the same day — same overwrite/append/skip prompt as daily-briefing.
  • Multi-team run, partial failure — generate reports for the teams that succeeded; surface per-team status in the final summary block.
  • Sprint pulse with no prior snapshots — first daily run of a sprint will only have one trend row after Step 1 writes it. Render the burndown as a single point with a one-line caption (e.g. _First daily snapshot of Sprint N — trend will fill in over coming days._) and let the statistics-expert flag the data as too sparse to forecast.
  • Sprint config note missingsprint-snapshot will prompt to create one. If the user declines, skip the entire pulse phase rather than half-rendering it.

Related skills

This skill writes into and reads from the user's Obsidian vault. When any vault-related extension or refinement is needed, delegate to the relevant obsidian-* skill via Skill rather than reimplementing — they are the canonical references for vault conventions and stay in sync with Obsidian feature changes.

SkillUse it for
daily-briefingPersonal (Outlook-driven) morning prep. Sibling skill — both can run on the same morning. Same {{vault_root}} resolution pattern.
sprint-snapshotOwns the daily snapshot in Phase 4.5. Always invoke via Skill with --phase "daily"; never reimplement Jira sprint fetching, identity matching, or the JSONL trend schema inline. The _snapshots.jsonl it writes is the burndown's data source.
clarity-councilOwns the pulse council in Phase 4.5. Always invoke with the three pinned personas (infographics-expert, statistics-expert, scrum-master). Lets each persona enforce its own constraints on the burndown chart, forecast, and suggestions.
issue-suggest-componentPattern reference for memory-driven default Jira project + bulk AskUserQuestion pacing if the multi-team loop ever grows beyond a handful of teams.
issue-feature-breakdownPattern reference for Jira+Confluence context-gathering depth.
obsidian-markdownCanonical reference for Obsidian Flavored Markdown. Consult before extending the standup template with new constructs (callouts, embeds, dataview, block IDs, frontmatter properties).
obsidian-vaultUse for batch wikilink target verification, vault-wide note discovery, and managing the standup index notes. Prefer over repeated Glob calls when the run needs >15 lookups.
obsidian-cliUse for property/task queries, frontmatter inspection, and any CLI-driven vault operation that Read + Glob cannot do cheaply.
obsidian-basesUse when the user wants a dashboard .base file (e.g. "show me all standups for Pyrite this sprint", "which team members had no activity in the last 5 standups"). Don't hand-author .base YAML.
obsidian-canvasUse if the user wants a visual board summarizing the standup (e.g. a sprint-overview canvas with linked standup notes as nodes).

What ships with it: 2 files

12.9 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.