From 2cd4812bed44ab6639893de69f6f689be9c01719 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sat, 30 May 2026 20:50:46 +0200 Subject: [PATCH] Add monthly-review skill Add .claude/skills/monthly-review: a Claude Code skill that builds a higher-level monthly timesheet review by synthesizing the weekly review sections of the month's week notes, and writes it as a note in Work / Self-Reviews. Uses a strict calendar-month day filter (straddling weeks count only for their in-month days), the weekly review sections as the source of truth, and the CLI only for per-week totals. The review has a month-level narrative (shape, major threads, recurring work) plus an inspections section: time allocation, stuck/recurring threads, and long weeks (a low-logged week is treated as unlogged leave, not reduced output). Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/monthly-review/SKILL.md | 290 +++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 .claude/skills/monthly-review/SKILL.md diff --git a/.claude/skills/monthly-review/SKILL.md b/.claude/skills/monthly-review/SKILL.md new file mode 100644 index 0000000..640f8e0 --- /dev/null +++ b/.claude/skills/monthly-review/SKILL.md @@ -0,0 +1,290 @@ +--- +name: monthly-review +description: >- + Generate a higher-level monthly timesheet review from the weekly review + sections of one calendar month's Joplin week notes, and write it as a note in + Work / Self-Reviews. Produces a month-level narrative of the work done plus an + inspections section (time allocation, stuck/recurring threads, long weeks). + Use when the user asks for a monthly review, a month recap, to "review my + month", to summarize a month of work, or to prep for a monthly/checkin + overview. Optionally takes a month (e.g. "April", "2026-04", "last month") to + target a month other than the current one. +--- + +# Monthly timesheet review + +Build a month-level review by synthesizing the **weekly review sections** that +already exist in that month's week notes, and write it into a note in +`Work / Self-Reviews`. The weekly reviews are granular (one week each); this +zooms out: collapse the week-by-week detail into month-level arcs, say where the +big threads landed, and surface patterns that are only visible across the whole +month. + +This is the bigger sibling of the `weekly-review` skill. The reference for the +target output is the existing `2026 - Year Review (W01-W22)` note in +`Work / Self-Reviews`: it is synthesized from weekly review sections at year +scale. A monthly review is the same idea, one month wide, plus an explicit +inspections section. + +Read `README.md` and `CLAUDE.md` first if you are not already familiar with the +project. The timesheet structure, table format, and Joplin notebook layout are +described there. The `weekly-review` skill describes the weekly review format +this one consumes. + +## Inputs + +- Optional target month. Accept a month name (`April`), `YYYY-MM` (`2026-04`), + `last month`, `this month`, or any date (the month containing it). Default to + the **current** calendar month relative to today. +- If today is in the first days of a month and the request is ambiguous, the + user most likely means the month that just ended. Confirm which month before + doing the work. +- A review run for an incomplete (current, still-running) month is fine, but say + in the note that it is partial. +- The CLI reads timesheets from Joplin with `--joplin`. Config (token, project + map) is already set up; do not ask for it. + +## What a month is here + +A calendar month, **strict day filter**: only days that actually fall in the +month count. ISO weeks do not align with months, so a week that straddles the +boundary (e.g. the week of Apr 27 with days in both April and May) is included +**only for its in-month days**. The out-of-month days of a straddling week +belong to the other month's review. + +Consequence: a straddling week whose in-month days have no logged entries (e.g. +for May, the week of Apr 27 only reaches into May 1-3, a Friday-to-Sunday with a +public holiday and no entries) contributes nothing and drops out entirely. Do +not pull its review in. + +## Steps + +### 1. Resolve the month and find its week notes + +- Resolve the target month to its first and last calendar day, relative to + today. Convert any relative expression to an absolute month (e.g. with today + 2026-05-30, "last month" = April 2026, "this month" = May 2026). +- Week notes live in `Work / Timesheets / `, titled `YYYY - WNN`. List + them: + + ``` + find_notes_in_notebook("Work/Timesheets/") + ``` + + A month near a year boundary (January, December) can pull weeks from **two** + year notebooks; list both when relevant. +- For each candidate week note, read its first heading + `# Week of - Review` to get the week's Monday. The week spans + Monday..Monday+6. **Include the week if that span intersects the target + month** (week-Monday <= month-last-day AND week-Sunday >= month-first-day). +- For a **straddling week** (Monday before the 1st, or Sunday after the last + day), only the in-month days count (see "What a month is here"). Check whether + those in-month days actually have logged entries: + - If they do, include the week but treat only the in-month days as this + month's work. Read the day tables for those days to see what was worked, and + use the weekly Summary for context; do not attribute the out-of-month days' + work to this month. + - If the in-month days have no entries, drop the week entirely. +- Record the list of weeks that contribute days to this month (e.g. W19-W22) for + the title and caveats. + +### 2. Read the weekly review sections (primary source) + +For each included week note, read the **review block**: everything from the +`# Week of YYYY-MM-DD - Review` heading down to (not including) the first day +heading (`# - ...`). Use `get_note(note_id, force_full=true)` and take +that top block. It holds the three subsections the weekly skill writes: + +- `## Summary` — the narrative of own work, grouped by theme, with rough + per-theme times and a meetings line. This is the spine of the month narrative. +- `## Reviews` — work that was only reviewing other people's MRs, with a rough + total. Sum these across the month for the review-load figure. +- `## Loose ends` — open checklist items, recurring unclosed stories, carry-over. + This is the spine of the stuck/recurring-threads inspection. + +The weekly reviews already carry the substance and the user's voice. Draw the +narrative from them; do **not** re-derive everything from the raw day tables. +The weekly review section is the source of truth for what the week was about. + +Carry over the Joplin note links (`[label](:/)`) from the weekly sections +when you reference the same ticket; do not invent new ids. + +### 3. Get per-week totals (cross-check, long-week detection) + +Run, once per included week, using that week's Monday date: + +```sh +uv run timesheets summary -w -ss --joplin # per-day + week total +``` + +Use this to compute the month total and to spot long weeks. The `-ss` output +gives a per-day breakdown, so for a **straddling week** sum only the in-month +days rather than the whole-week total. **Cross-check against the total stated in +the week's `## Summary`.** The CLI total is occasionally garbage from data-entry +typos in the raw tables (a week can show a nonsense 100h+). When the CLI total +and the week note's stated total diverge wildly, trust the week note and flag +the week in Caveats. Never sum hours by hand from the raw tables. + +### 4. Write the month narrative + +Higher altitude than a weekly review. The reader should come away knowing what +the month was about and where the big threads landed, not the day-to-day. + +- **Lead with the shape of the month**: one short paragraph. What were the one + or two centers of gravity? Was it focused on a flagship effort, or fragmented + across many small things? Did a release, a customer, or an interruption + dominate a stretch? +- **Group own work by major project/theme**, most time first. For each, give a + few plain sentences: what it was, how it progressed across the month's weeks, + and where it ended the month (landed / merged / still in flight / handed off). + Merge a theme that appears in several weekly summaries into one month-level + thread rather than repeating it per week. +- **Recurring / continuous work** in a tighter list: bug-fixing load, the areas + that came up repeatedly (specific subsystems), customer/incoming work, MCP/AI, + security/ISMS, etc. Mirror the "Recurring areas" / "Continuous work" split in + the year-review note when there is enough material. +- **Meetings**: name the noteworthy ones (brainstorms, retros, growth-path, + customer/technical meetings, trade fairs). Fold dailies and Factry Flow into a + one-line catch-all. Pull these from the weekly summaries' meetings lines. +- Reference tickets by **paraphrase + id in brackets**, same convention as the + weekly skill, and only link ids that a weekly section already linked. At month + scale, reference fewer tickets than a weekly review would; lead with threads, + not ticket numbers. + +### 5. Write the inspections section + +This is the point of the monthly view: patterns visible only across the whole +month. Cover these three lenses (and only these unless the user asks for more): + +1. **Time allocation.** + - Own work vs reviewing other people's MRs: sum the weekly `## Reviews` + totals and express the review load as a rough share of the month. A heavy + review month is worth calling out (it is real, valuable work, but it is a + large time sink and the user tracks it separately from own work). + - The split across major projects/themes for the month. + - How fragmented the month was: many small bugs and heavy context-switching + vs sustained focus on one or two threads. The weekly summaries say this + directly ("fragmented week", "no single theme", "one theme dominated"); + aggregate that judgement. + +2. **Stuck / recurring threads.** + - Tickets and loose ends that appear in **multiple** weeks' `## Loose ends` + or recurring-story lists and never closed within the month. + - Repeated rework: rebases of the same big branch, repeated rounds of fixing + the same failing tests or de-flaking the same suite (e.g. Cypress). + - Threads that opened early in the month and were still open at month end. + - These are candidates the user may want to push to close or escalate. + +3. **Long weeks (only).** + - Flag weeks that clearly ran over 40h and say what drove them (evening trade + fairs, late stress-test or customer work, a release crunch). + - **Do not flag short or low-hour weeks as reduced output or a concern.** The + user always works full weeks. A week that logs under 40h almost always + means vacation or time off that was simply not entered in the timesheet, + not less work done. At most mention a low-logged week once, in Caveats, as + a data-entry gap, never in the workload inspection as a productivity + signal. + +Keep inspections concrete and tied to the data. If a lens has nothing real for +this month, say so in a line rather than padding. + +### 6. Voice + +Write it the way the user writes, not the way an assistant writes. The reference +is the user's **`Express Guide`** OpenTelemetry note (in `Knowledge / +OpenTelemetry`): read it before drafting and match its register. + +How the user actually writes: + +- **Plain and matter-of-fact.** States what a thing is and what happened, e.g. + "ArgoCD is gitops CD for Kubernetes, it reconciles the live cluster against + the git repo". Defines with "X is Y", gives concrete examples in parentheses + with "e.g.". No drama. +- **Full sentences, normal capitalization, English.** No Dutch, no + lowercase-everything, no `gwn`/`da`/`ge` (that is only how the rough + free-text is drafted, not how finished notes read). +- **Light first person where natural** ("I changed the GC to be less + aggressive", "I'm explaining them here"). +- **Bold for the key term** that starts a thread or definition, the way the + Express Guide bolds **Counter**, **resource**, etc. +- `->` for results/consequences is fine. **No em dashes**; use commas, + parentheses, colons, `->`, or new sentences. + +Avoid the AI tells the user does not use: + +- No journalistic punch verbs or set-piece phrasing: not "blew up", "the spine + of the month", "rides with it", "pivoted hard", "exploded". +- No editorializing flourishes: not "worth keeping visible", "risks drifting", + "bit-rot risk". State the fact and, if needed, the plain consequence. +- No balanced "not X, but Y" rhythm or rule-of-three lists for effect. +- Keep the altitude high (what the thread was and where it landed), but the + prose flat and concrete. Exact config values and internal symbol names stay + out (the story logs hold those); `centre of gravity` is the user's own phrase + and is fine. + +### 7. Confirm, then write the note + +- **Show the full draft to the user first and ask for confirmation.** This is + LLM-generated prose going into a durable note; do not write blindly. Apply any + edits the user asks for. +- Write it as a note in the `Work / Self-Reviews` notebook. Title convention, + mirroring the year-review note: `YYYY - Review (Wxx-Wyy)`, e.g. + `2026 - May Review (W18-W22)`. +- **Before creating, search for an existing note for this month** + (`find_notes_in_notebook("Work/Self-Reviews")`). If one exists, update it with + `edit_note` rather than creating a duplicate. The Joplin tools cannot delete + notes, so a wrongly-created duplicate can only be blanked, not removed; check + first. Only create a new note with `create_note` when none exists. +- After writing, re-fetch the note (or report the diff) so the user can verify. + +## Output structure + +```markdown +# Review (Wxx-Wyy) + +Synthesized from the weekly review sections of the Wxx-Wyy timesheet notes. + +## Shape of the month + + + +## Major threads + + + +## Recurring & continuous work + + + +## Inspections + +**Time allocation** — +**Stuck / recurring threads** — +**Long weeks** — say so> + +## Caveats + + +``` + +Adapt the headings to the material; this is a shape, not a rigid template. Match +the depth of the year-review note: enough to be useful, not a per-ticket ledger. + +## Edge cases + +- **Missing or empty week note.** If an included week has no review section + (e.g. it was never reviewed, or is a near-empty stub), note it in Caveats and + work from what is there. Do not fabricate a week's content. If most of the + month's weeks lack review sections, tell the user the monthly review will be + thin and suggest running the weekly reviews first. +- **Straddling weeks** count only for their in-month days (see "What a month is + here"). If the in-month days have no entries, drop the week. Use the per-day + CLI breakdown to attribute hours. +- **Unreliable CLI totals.** Prefer the week note's stated total over a wildly + divergent CLI total; flag it in Caveats. +- **Low-logged weeks are not short weeks.** See step 5, lens 3: treat them as + unlogged-vacation data gaps, never as reduced output. +- **Never touch the week notes or the checkin notes.** This skill only reads the + weekly review sections and writes a new note in `Work / Self-Reviews`. Checkin + notes in `Work / Meetings / Checkins` are the user's own and are off-limits. +- Do not modify the day tables in any week note.