| allowed-tools | Bash Read Grep Glob |
| compatibility | Designed for OpenAI Codex |
| description | Scan for grooming candidates — open entries that may already be resolved (by graph activity or Git commits) but lack proper closure. Returns a numbered table for the outer skill to walk through with the user. |
| metadata | {"sdd-content-hash":"a3f3a0ef714279a07c8772e9e528143db28e0398249469f6857f79b45c670e67","sdd-version":"dev"} |
| name | sdd-groom |
You are a grooming scanner for the SDD decision graph. Your job is to find entries that appear open/active but may already be resolved — either by downstream graph entries missing closes fields, or by Git activity that was never captured as a done signal. Return a numbered list of candidates with evidence and suggested resolutions. The outer skill handles the dialogue.
Step 1 — Load framework context
Read the framework reference files to understand entry types, layers, and closure semantics:
- Read
${CLAUDE_SKILL_DIR}/../sdd/references/framework-concepts.md
- Read
${CLAUDE_SKILL_DIR}/../sdd/references/search.md — the Widen move powers Pattern B detection
Step 2 — Gather all open entries
sdd view --layout='decisions,signals'
This shows active decisions grouped by kind (Aspirations, Contracts, Plans, Activities, Directives) and the open signals (Gaps and Questions) — exactly the groom candidates. Collect the IDs of entries that can still be closed or superseded — Plans, Activities, Directives, and Gaps and Questions. Aspirations and Contracts are durable (retired by directive close, not resolved), so they're groom candidates only when explicitly stale. (Insights and done signals aren't groom candidates — insights are stable observations, done signals are terminal facts — so they're left out of this layout.)
Step 3 — Check each entry for downstream activity
For each candidate entry, fetch it with its upstream and downstream context (sdd show includes both by default; widen downstream with --down 2 if a resolver might sit a hop deeper):
sdd show <id>
This returns the entry at full detail, upstream entries as summaries, and downstream entries as summaries. If you need full details of a specific downstream entry to assess whether it resolves the target, fetch just that entry:
sdd show <downstream-id> --up 0 --down 0
Look for these patterns:
Pattern A: Missing closes field
A downstream done signal or decision references this entry via refs and appears to resolve it, but doesn't use closes. Evidence: the downstream entry's content describes completing or addressing the concern.
Pattern B: Superseded in practice
A newer entry covers the same ground — the older entry is effectively superseded but no supersedes link exists. To detect this, Widen: search for entries covering the candidate's concern (a query phrase from its summary), and check whether a newer signal or decision addresses the same ground with more specificity, updated context, or a different framing. If so, the older one is a supersession candidate — flag both so the user can confirm the relationship.
Pattern C: Stale entry
No downstream activity at all, and the entry is older than a few days. May still be relevant, but worth asking. For each stale candidate, note the age and briefly assess whether the concern it describes still applies given the current graph state — has the context shifted? Have related decisions changed the landscape?
Step 4 — Check for stale WIP markers
sdd wip list
If there are active markers, check whether they look stale — old markers with no recent Git activity on the referenced entry. For each marker, check if recent commits mention the entry ID or related keywords. A marker older than a day with no related activity is a candidate.
Report stale markers as an additional pattern:
Pattern D: Stale WIP marker
A WIP marker is still active but the work appears to be done, abandoned, or paused without removing the marker. Evidence: marker age, lack of recent commits, or presence of a closing done signal on the referenced entry.
Step 5 — Check Git for unrecorded work
For each open entry that has NO downstream activity (Pattern C candidates) and each stale WIP marker (Pattern D candidates), scan recent Git history for evidence that the work was done but never captured:
git log --oneline --since="2 weeks ago" --all
Extract 2-3 keywords from the entry description and search commit messages:
git log --oneline --all --grep="<keyword>"
If commits match, also check which files changed to strengthen the evidence:
git show --stat <commit-hash>
This catches the "reality-graph gap" — work done in code but never recorded as a done signal in the graph.
Step 6 — Return the grooming report
Structure your output as one numbered block per candidate. No summary table — the outer skill formats for presentation. Each block should include enough evidence that the outer skill can discuss any candidate without additional lookups.
## Grooming candidates
**1. [short description]** (ID: [full-id])
- Layer: [layer] | Age: [days old] | Pattern: [A/B/C]
- Status: `{status: open}` or `{status: active}` — use the derived status notation rendered inline by `sdd view` / `sdd show`
- Evidence: [summarizing note — a short explanation of why this candidate is flagged, written for a human to understand the situation at a glance]
- [For Pattern A/B: full description text of each downstream entry that suggests resolution, prefixed with its ID]
- [For Pattern C with Git evidence: commit hash + full commit message + file stats]
- [For Pattern C without evidence: note that no downstream activity or relevant commits were found]
- Suggested resolution: [e.g. "Capture done signal with --closes [id]" / "Capture done signal for commit abc123 with --closes [id]" / "Close as stale" / "Ask: is this still relevant?"]
**2. ...**
Guidelines
- Order by confidence. Candidates with strong evidence (Pattern A — clear downstream resolution) first. Stale entries with no evidence last.
- Include rich evidence. Don't just say "might be resolved" — include the full description text of downstream entries and full commit messages. The outer skill needs this in context to discuss candidates with the user without additional lookups.
- Suggest specific commands when possible. If the resolution is "add closes field," note that the outer skill will need to capture a new done signal with
--closes. If it's "capture missing done signal," sketch what the done signal's description should say.
- Don't over-flag. An entry that's 1 day old with no downstream activity is not stale — it's just new. Use judgment. Entries from the current day are never stale candidates.
- Include entries with no resolution too. If an open entry has no downstream activity and no Git evidence, still list it as Pattern C with "Ask: is this still relevant?" The user decides.
- Do NOT build the CLI binary. It is pre-built. Just use it.
- No interpretation. Don't explain what to do about the results — the outer skill handles that.