feat(pm): PM skill pack v1 — /pm:standup /pm:groom /pm:plan /pm:health - #212
Conversation
📝 WalkthroughWalkthroughAdds a read-only PM skill with standup, grooming, planning, and health workflows, supporting read and scoring references, and a script for preparing timestamped PM fixtures in SQLite. ChangesPM skill workflows
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.claude/skills/pm/reference/read-recipe.md:
- Around line 3-13: Update the PM workflow instructions to first resolve the
project associated with the current repository, assert that exactly one project
is found, and retain its identifier for subsequent calls. Apply that project
filter to every relevant item action, including the existing item action="list"
and any list/get calls described later, so results are scoped to the resolved
project.
In @.claude/skills/pm/reference/rubric.md:
- Around line 14-24: Clarify the rubric’s ICE fallback by defining a
deterministic 1–5 Ease mapping and applying ICE per item, not to the whole
table. Specify how mixed estimated and unestimated shortlists are ranked,
including how missing effort affects RICE scores, and ensure displayed scores
never claim a numeric result when a required factor is “?”.
In @.claude/skills/pm/SKILL.md:
- Around line 82-83: Clarify the Bottlenecks step in the PM skill by limiting it
to the read-only handoff inbox data currently supported, removing the undefined
repeated-handoff history and grouping requirement. Preserve the fallback output
“no handoff history” only when the available inbox data contains no handoff
records.
- Around line 63-68: Update the /pm:plan dependency-read recipe in the planning
guidance so it deterministically retrieves each item's open dependencies from
item_dependencies, or explicitly surfaces dependency_ids through the existing
fetch flow. Ensure the Now/Next/Later readiness check uses this dependency data
rather than parent_id from list summaries, while preserving the separate Needs
estimation category.
In `@scripts/pm-fixtures.sh`:
- Around line 24-30: Update the fixture setup around the bd helper to preflight
that every expected FIX-* row exists, run validation and all timestamp updates
within a single SQLite transaction, and fail if any update affects fewer rows
than expected. Only print the success message after the transaction completes
successfully, preserving the existing timestamps and item groups.
- Around line 20-25: The fixture updates in bd must not target rows solely by
FIX-* names, since real items in the selected project may be modified. Use exact
seeded item IDs or add and validate an explicit fixture-only marker before
updating, and adjust the collision guard consistently around the fixture
identity.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4f1a4b84-d276-471e-b7b5-fdd353ea7fd7
📒 Files selected for processing (4)
.claude/skills/pm/SKILL.md.claude/skills/pm/reference/read-recipe.md.claude/skills/pm/reference/rubric.mdscripts/pm-fixtures.sh
| All PM workflows start here. One project only (resolved from the repo). | ||
|
|
||
| ## Base list | ||
|
|
||
| Call `item` with `action="list"`. Add filters as needed: | ||
| - `state_group`: one of `backlog|unstarted|started|completed|cancelled|triage`, | ||
| or a comma-separated set (e.g. `"backlog,unstarted,started"` = all open). | ||
| - `assignee_agent`: matches that agent PLUS unassigned items, open-first. | ||
|
|
||
| The list projection has ONLY: id, name, state, state_group, priority, | ||
| assignee_agent, parent_id, sequence_id, updated_at. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the target file with line numbers and nearby context.
sed -n '1,120p' .claude/skills/pm/reference/read-recipe.md | cat -nRepository: getappz/agentflare
Length of output: 1627
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find related references to project resolution/filtering in the PM skills docs.
rg -n "project|repo|scope|list|detail|filter" .claude/skills/pm -g '*.md'Repository: getappz/agentflare
Length of output: 2644
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show only the target recipe and any sibling files that mention "resolved from the repo".
git ls-files .claude/skills/pm/reference .claude/skills/pm | sed -n '1,200p'
echo '---'
grep -RIn "resolved from the repo\|One project only\|action=\"list\"\|assignee_agent" .claude/skills/pm 2>/dev/null | sed -n '1,200p'Repository: getappz/agentflare
Length of output: 1409
Add the repo-to-project step. The recipe asserts a single project, but it never shows how to resolve that project from the current repo or apply it to item list/get calls.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.claude/skills/pm/reference/read-recipe.md around lines 3 - 13, Update the
PM workflow instructions to first resolve the project associated with the
current repository, assert that exactly one project is found, and retain its
identifier for subsequent calls. Apply that project filter to every relevant
item action, including the existing item action="list" and any list/get calls
described later, so results are scoped to the resolved project.
| Print each score as: `RICE 9.6 — R4 I5 C3 / E? (UNESTIMATED)` with one-line why. | ||
|
|
||
| ## ICE fallback | ||
|
|
||
| When items lack any effort/size signal, use ICE = Impact × Confidence × Ease | ||
| (1–5 each) and label the table "ICE (no effort estimates present)". | ||
|
|
||
| ## Unestimated handling | ||
|
|
||
| Never fail. Score what you can, mark the missing factor `?`, and list all | ||
| UNESTIMATED items separately so the team can add `size:*` labels. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Make the unestimated scoring policy internally consistent.
The rubric does not define how to derive ICE Ease, and its example emits a numeric RICE score with E?, which cannot be calculated. It also leaves unclear whether ICE applies per item or to the whole table. Define the Ease mapping and choose one deterministic policy for mixed estimated/unestimated shortlists; otherwise rankings may be invalid or incomparable.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.claude/skills/pm/reference/rubric.md around lines 14 - 24, Clarify the
rubric’s ICE fallback by defining a deterministic 1–5 Ease mapping and applying
ICE per item, not to the whole table. Specify how mixed estimated and
unestimated shortlists are ranked, including how missing effort affects RICE
scores, and ensure displayed scores never claim a numeric result when a required
factor is “?”.
| 2. Bucket by rank and readiness: | ||
| - **Now**: highest-ranked items that are ready (have an estimate, not blocked | ||
| by an open dependency). Cap to the capacity hint if provided. | ||
| - **Next**: next tier by rank. | ||
| - **Later**: the tail + anything low-confidence. | ||
| 3. Separately list **Needs estimation** (unestimated items) — cannot be planned. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- target excerpt ---'
nl -ba .claude/skills/pm/SKILL.md | sed -n '1,180p'
echo '--- searches ---'
rg -n "/pm:plan|dependency|parent_id|blocked by an open dependency|open dependency|Now|Later|Needs estimation" .claude/skills/pm -SRepository: getappz/agentflare
Length of output: 219
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- target excerpt ---'
sed -n '1,180p' .claude/skills/pm/SKILL.md | cat -n
echo '--- searches ---'
rg -n "/pm:plan|dependency|parent_id|blocked by an open dependency|open dependency|Now|Later|Needs estimation" .claude/skills/pm -SRepository: getappz/agentflare
Length of output: 5867
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- read-recipe excerpt ---'
sed -n '1,220p' .claude/skills/pm/reference/read-recipe.md | cat -n
echo '--- rubric excerpt ---'
sed -n '1,240p' .claude/skills/pm/reference/rubric.md | cat -nRepository: getappz/agentflare
Length of output: 3191
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- repo-wide dependency search ---'
rg -n "dependency|dependencies|blocked by an open dependency|open dependency|parent_id|sequence_id" . -S
echo '--- files mentioning parent_id ---'
rg -n "parent_id" . -SRepository: getappz/agentflare
Length of output: 33036
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- item.rs relevant structs/functions ---'
sed -n '1,240p' crates/agentflare-backend/src/item.rs | cat -n
echo '--- item.rs dependency helpers ---'
sed -n '390,470p' crates/agentflare-backend/src/item.rs | cat -n
echo '--- MCP item read shape ---'
sed -n '1,220p' src/mcp_server/item.rs | cat -nRepository: getappz/agentflare
Length of output: 25461
Define dependency reads for /pm:plan.
/pm:plan needs a deterministic source for “blocked by an open dependency”: the read recipe only exposes parent_id in list summaries, while real dependencies live in item_dependencies and are not returned by item_get. Add the exact query/fetch step or surface dependency_ids so Now/Next/Later bucketing is reproducible.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.claude/skills/pm/SKILL.md around lines 63 - 68, Update the /pm:plan
dependency-read recipe in the planning guidance so it deterministically
retrieves each item's open dependencies from item_dependencies, or explicitly
surfaces dependency_ids through the existing fetch flow. Ensure the
Now/Next/Later readiness check uses this dependency data rather than parent_id
from list summaries, while preserving the separate Needs estimation category.
| 4. Bottlenecks: read `handoff` history (read-only) for items handed off | ||
| repeatedly; if none available, print "no handoff history". |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the referenced file around the cited lines
wc -l .claude/skills/pm/SKILL.md
sed -n '1,170p' .claude/skills/pm/SKILL.md
# Search for handoff-related read operations and any "history" / grouping language
rg -n --no-heading -C 3 '\bhandoff\b|history|read-only|thread|inbox|group|grouping|aggregate|repeated' .claude/skills/pm/SKILL.mdRepository: getappz/agentflare
Length of output: 6107
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search the repo for any defined handoff history/thread read operation or grouping rule
rg -n --no-heading -C 2 '\bhandoff\b|history|thread|group(?:ing)?|aggregate|repeated handoff|handoff history' . \
--glob '!**/.git/**' --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**'
# List files that look like skill/reference docs to inspect if needed
git ls-files '.claude/**' 'README.md' '*reference*' '*handoff*'Repository: getappz/agentflare
Length of output: 50375
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the MCP memory file, then inspect the handoff tool definitions and registrations
wc -l src/memory/mcp.rs
rg -n --no-heading -C 3 '\bhandoff\b|read|list|get|history|tool|register|inbox|memory' src/memory/mcp.rs
# Show the sections around handoff handling and tool registration
sed -n '1,260p' src/memory/mcp.rs
sed -n '260,520p' src/memory/mcp.rsRepository: getappz/agentflare
Length of output: 24908
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect only the handoff handler and the surrounding MCP tool registrations
rg -n --no-heading -C 6 'handle_handoff|handoff.*tool|tool.*handoff|register.*handoff|memory.*handoff' src/memory/mcp.rs
# Print the relevant slices around the matches
sed -n '120,230p' src/memory/mcp.rs
sed -n '380,460p' src/memory/mcp.rsRepository: getappz/agentflare
Length of output: 8831
Define a handoff-history read path. The read-only contract only allows handoff inbox reads, but /pm:health asks for repeated-handoff history and a grouping rule that aren’t defined. Either add the supported history read call and aggregation rule, or limit this step to the inbox data actually available.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.claude/skills/pm/SKILL.md around lines 82 - 83, Clarify the Bottlenecks
step in the PM skill by limiting it to the read-only handoff inbox data
currently supported, removing the undefined repeated-handoff history and
grouping requirement. Preserve the fallback output “no handoff history” only
when the available inbox data contains no handoff records.
| # Guard: refuse if any FIX-* row lives outside this project (name collision). | ||
| STRAY=$(sqlite3 "$DB" "SELECT count(*) FROM items WHERE name LIKE 'FIX-%' AND project_id<>'$PID';") | ||
| [ "$STRAY" = "0" ] || { echo "refusing: $STRAY FIX-* items outside project $PID" >&2; exit 1; } | ||
|
|
||
| now=$(date +%s); day=86400 | ||
| bd() { sqlite3 "$DB" "UPDATE items SET updated_at=$1 WHERE project_id='$PID' AND name IN ($2);"; } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Use a fixture identity stronger than the FIX-* name.
The UPDATE will modify any item in the selected project named FIX-03, FIX-05, etc., including a real item. The cross-project collision guard does not protect real rows inside the selected project. Target the exact seeded item IDs, or require an explicit fixture-only marker and validate it before updating.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/pm-fixtures.sh` around lines 20 - 25, The fixture updates in bd must
not target rows solely by FIX-* names, since real items in the selected project
may be modified. Use exact seeded item IDs or add and validate an explicit
fixture-only marker before updating, and adjust the collision guard consistently
around the fixture identity.
| now=$(date +%s); day=86400 | ||
| bd() { sqlite3 "$DB" "UPDATE items SET updated_at=$1 WHERE project_id='$PID' AND name IN ($2);"; } | ||
| bd $((now-25*day)) "'FIX-08','FIX-09'" # stale backlog >14d | ||
| bd $((now-3*day)) "'FIX-05'" # completed this week | ||
| bd $((now-10*day)) "'FIX-06'" # completed prior week | ||
| bd $((now-20*day)) "'FIX-03'" # started but stuck | ||
| echo "backdated FIX-* items in $DB (project $PID)" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Make fixture preparation atomic and fail on missing rows.
Each bd call uses a separate transaction, so an interruption or later failure can leave only part of the fixture set backdated. Also, an UPDATE matching zero rows still succeeds, so the script can print success with missing fixtures. Preflight the expected rows, verify the affected count, and perform validation plus all updates in one transaction.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/pm-fixtures.sh` around lines 24 - 30, Update the fixture setup around
the bd helper to preflight that every expected FIX-* row exists, run validation
and all timestamp updates within a single SQLite transaction, and fail if any
update affects fewer rows than expected. Only print the success message after
the transaction completes successfully, preserving the existing timestamps and
item groups.
Summary
/pm:standup(activity digest),/pm:groom(backlog scoring + flags),/pm:plan(Now/Next/Later bucketing),/pm:health(velocity/WIP/stuck scorecard)reference/read-recipe.md(item-read procedure) andreference/rubric.md(RICE/ICE scoring)scripts/pm-fixtures.shtest fixtures harness, backdating scoped to FIX-* items onlyTest plan
/pm:standup,/pm:groom,/pm:plan,/pm:healthagainst this repo's linked project and confirm output matches each workflow's specscripts/pm-fixtures.shand verify it only touches FIX-* test itemsSummary by CodeRabbit