Daily standup prep
An opinionated library of reusable agent skills. Contains practical skills for writing, planning, triage, architecture, and workspace workflows
npx -y skills add risadams/skills --skill daily-standup-prepAssembled 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.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
30.6 KB, 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
| Param | Default | Maps to PS |
|---|---|---|
Teams | ["Pyrite"] | -Teams (string[]) |
DaysToLookBack | 2 | -DaysToLookBack |
JQL | auto-built | -JQL |
GitRepoPath | D:\paas\ | -GitRepoPath |
Inc | 25 | -Inc |
Sprint | 1 | -Sprint |
IncludeJiraIssues / IncludeGitCommits / IncludeGitLabActivity / IncludeConfluenceActivity / IncludeKanbanDiagram / IncludeStandupOrder | all true | same |
IncludeSprintPulse | true | new — 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)
| Placeholder | Memory file | Default 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.md | PP — 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 table | If absent, prompt and add a row: bessemer → bessemer (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:
- Look for
{{rosters_dir}}\<Team>.csv(case-insensitive). If present, use it. - If missing and
D:\powershell-scripting\src\bin\Teams\<Team>.csvexists, prompt viaAskUserQuestion: "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. - On
Copy:mkdir -p "{{rosters_dir}}", then copy the file. Tell the user the new path is the canonical location going forward. - 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)DaysToLookBackdays ago.since_iso=YYYY-MM-DDTHH:mm:ssZfor GitLab/Confluence cutoffs.since_date=YYYY-MM-DDforgit log --since.- If
JQLarg is empty: buildproject = {{jira_project}} AND updated >= startOfDay(-{N}d)whereN = 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 (
IncludeJiraIssuesorIncludeKanbanDiagram):jira_search(jql=<jql>, fields="summary,status,assignee,issuetype,updated")with pagination to a sane cap. For each result, follow up withjira_get_changelogandjira_get_commentsonly when the issue'supdatedis within the window — skip the fetch otherwise to save tokens. - Jira kanban (
IncludeKanbanDiagramonly): secondjira_searchwithproject = {{jira_project}} AND sprint in openSprints() AND labels in ({lowercase team names}). Capturekey, summary, status, assignee.displayName, issuetype.name. - GitLab MRs + discussions (
IncludeGitLabActivity):list_group_projects(group_id="{{gitlab.bessemer}}")to get all project IDs in the group (subgroups included).- For each project:
list_merge_requests(project_id, updated_after=<since_iso>, per_page=100). - 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}}\.gitexists;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 $hasRecentActivityfilter.) - Git/GitLab/Confluence inclusion — keep an activity iff its author matches a team member.
- Set
member.HasActivity = truefor any matched member, and append the activity to the member'sIssues / Commits / GitLabActivities / ConfluenceActivitieslists 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
chartcode fence (Chart.js backend via theobsidian-chartscommunity 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):
- Determine actual data points. From the JSONL trend rows, build a list
samples = [(day_n, scope_points, done_points), …]whereday_nis integer days sinceStartDate(Pittsburgh local,day_0 = StartDate),scope_points = totals.points,done_points = by_status.done.points. Sort byday_n. De-duplicate byday_nkeeping the latestsnapshot_atper row. - Build the x-axis. Full sprint range —
x_axis = list(range(0, sprint_length_days + 1))wheresprint_length_days = (EndDate - StartDate).days. The x-axis always spans day 0 → daysprint_length_days, regardless of how far into the sprint we are. - Build the actual scope series. For each
day_ninx_axis:- If
day_n ≤ today_nAND a sample exists forday_n: use the sample'sscope_points. - If
day_n ≤ today_nAND no sample exists (weekend/holiday/gap): carry forward the previous day'sscope_pointsvalue (last-known wins). - If
day_n > today_n(future): emitnull.
- If
- Build the actual done series. Same logic as scope, but using
done_points. Day 0 defaults to0if no sample exists. - Build the pinned scope series (visually distinct future segment). For each
day_ninx_axis:- If
day_n < today_n: emitnull. - If
day_n ≥ today_n: emit today's actualscope_points. (The series starts at today's point so the line connects visually from the actual series.)
- If
- Build the pinned done series. Same logic as pinned scope, but using
done_points. - Build the capacity reference series. Constant
Capacityacross alllen(x_axis)days. - 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. - Title. None at the chart level (the markdown heading carries it). Set the surrounding section heading to
### Burn-up. - Validate before emitting. Confirm all five series have length
len(x_axis); confirmnullis used (notNone/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-chartsplugin) renders each series in a distinct color, so the "actual" and "pinned" segments are visually different even though they share the chart. Thenullvalues create true gaps in the line, so past/future are visually separate. Do not addchartjs:style overrides unless the user explicitly asks — the default rendering is the canonical shape.Plugin dependency. The
chartcode fence requires theobsidian-chartscommunity plugin enabled in the vault (folder:{{vault_root}}/.obsidian/plugins/obsidian-charts/). On first run, verify viaGlobthat 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 Mermaidxychart-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._ - Determine actual data points. From the JSONL trend rows, build a list
-
statistics-expert → produce a single-paragraph forecast: project end-of-sprint completed points using simple linear extrapolation from the trend, compare against
Capacityandvelocity.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. IfIncludeStandupOrderis off, leave the placeholder empty.{{jira_state}}— Mermaidflowchartwith five status columns (Blocked / Ready / In Progress / In Review / Done). Spec in REFERENCE.md. IfIncludeKanbanDiagramis off, empty.{{jira_issues}}— per-issue blocks with### KEY - Summary, type/status/assignee line, then a bulleted activity log of(date) WHO / WHAT / WHYplustextcode fences for details.{{git_updates}}— per-member blocks### [[@First Last]]then- (date)hash7- messagelines, 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 atextcode fence).
Phase 6 — Substitute and write
Read{{template_path}}. The template is the user's master Standup template — never modify it.- Replace placeholders in this exact set (matches the PS
ConvertTo-TemplateMarkdownfunction 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 formatYYYY-MM-DD(Pittsburgh local). Team name written TitleCase (first char upper, rest lower) to match the PS$formattedTeamline. 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 Pulseheading containing{{burndown_chart}}, then### Forecast{{forecast_note}}, then### Suggestions{{scrum_suggestions}}). - 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. mkdir -pthe parent directory.- Never overwrite silently. If the file exists,
Readit, thenAskUserQuestion:Overwrite/Append as ## Re-run HH:MM section/Skip save. Writethe 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-snapshotviaSkillwith--phase "daily". Never reimplement Jira sprint fetching inline —sprint-snapshotowns the JQL, identity matching, capacity math, and the JSONL trend schema. If its phase derivation logic doesn't recognizedaily, pass it through as an explicit--phaseoverride (the skill already supports arbitrary phase strings via that flag). -
The pulse council is always delegated to
clarity-councilviaSkillwith personas pinned toinfographics-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), invokeobsidian-markdownviaSkillrather 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 toobsidian-vaultif the run will need to verify many person notes — its search is more efficient than repeatedGlobcalls. For a single team run (≤15 lookups) the inlineGlobis fine. -
If the user later wants a dashboard
.basefile that aggregates team standups (e.g. "all standups for Pyrite this sprint"), invokeobsidian-basesrather 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 thatRead+Globcannot 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.
fetchandlogonly — never checkout, pull, or merge. - No vault writes outside
Scrum Teams/. The template at🗃Templates/Standup.mdis 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.
pyrite→Pyrite(first char upper, rest lower) — matches the PS$formattedTeamline so vault paths and frontmatter stay consistent. - Pittsburgh local time. All
Datecolumns and the filename use America/New_York. Thegit log%aIand 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
dailysnapshot must come fromsprint-snapshotand the burndown/forecast/suggestions must come fromclarity-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.jsonlto feed the chart but never edits past rows. Pastdaily.canvas/daily.mdare 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
🤼 Teamfolder doesn't have a@First Last.mdnote for a roster member — render plainFirst Lastinstead 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
bessemergroup 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 missing —
sprint-snapshotwill 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.
| Skill | Use it for |
|---|---|
daily-briefing | Personal (Outlook-driven) morning prep. Sibling skill — both can run on the same morning. Same {{vault_root}} resolution pattern. |
sprint-snapshot | Owns 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-council | Owns 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-component | Pattern reference for memory-driven default Jira project + bulk AskUserQuestion pacing if the multi-team loop ever grows beyond a handful of teams. |
issue-feature-breakdown | Pattern reference for Jira+Confluence context-gathering depth. |
obsidian-markdown | Canonical reference for Obsidian Flavored Markdown. Consult before extending the standup template with new constructs (callouts, embeds, dataview, block IDs, frontmatter properties). |
obsidian-vault | Use 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-cli | Use for property/task queries, frontmatter inspection, and any CLI-driven vault operation that Read + Glob cannot do cheaply. |
obsidian-bases | Use 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-canvas | Use if the user wants a visual board summarizing the standup (e.g. a sprint-overview canvas with linked standup notes as nodes). |