@groupby/ai-dev 0.5.16 → 0.5.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/package.json +1 -1
  2. package/teams/firstspirit-caas/mcp/jira-tools.py +2122 -0
  3. package/teams/firstspirit-caas/mcp/test_bamboo_artifacts.py +315 -0
  4. package/teams/firstspirit-caas/mcp/test_jira_links.py +192 -0
  5. package/teams/firstspirit-caas/mcp/test_update_jira_ticket.py +161 -0
  6. package/teams/firstspirit-caas/resources/mcp-setup.md +57 -0
  7. package/teams/firstspirit-caas/skills/chronicle/SKILL.md +105 -0
  8. package/teams/firstspirit-caas/skills/create-jira-ticket/SKILL.md +183 -0
  9. package/teams/firstspirit-caas/skills/get-jira-ticket/SKILL.md +125 -0
  10. package/teams/firstspirit-caas/skills/handle-red-cve-plan/SKILL.md +316 -0
  11. package/teams/firstspirit-caas/skills/handle-red-cve-plan/references/suppression.md +79 -0
  12. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/gen_suppression.py +116 -0
  13. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/parse_json_report.py +183 -0
  14. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/parse_report.py +255 -0
  15. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/test_gen_suppression.py +171 -0
  16. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/test_parse_json_report.py +244 -0
  17. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/test_parse_report.py +464 -0
  18. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/testdata/sample-report.html +39 -0
  19. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/testdata/sample-report.json +76 -0
  20. package/teams/firstspirit-caas/skills/handle-weekly-cve-plans/SKILL.md +238 -0
  21. package/teams/firstspirit-caas/skills/retrospect/SKILL.md +94 -0
  22. package/teams/firstspirit-caas/skills/retrospect/extract_prompts.py +392 -0
  23. package/teams/firstspirit-caas/skills/review/SKILL.md +131 -0
  24. package/teams/firstspirit-caas/skills/review-finalize/SKILL.md +103 -0
  25. package/teams/firstspirit-caas/skills/specify/SKILL.md +239 -0
  26. package/teams/firstspirit-caas/skills/summarise-for-jira-comment/SKILL.md +162 -0
  27. package/teams/firstspirit-caas/skills/write-releasenotes/SKILL.md +177 -0
@@ -0,0 +1,238 @@
1
+ ---
2
+ name: handle-weekly-cve-plans
3
+ description: Use when the user asks to check, triage, or fix the weekly CVE Bamboo plans across the known service repos — phrases like "handle the weekly CVE plans", "check the weekly sonatype builds for CVE reds", "run the weekly CVE sweep", "fix this week's dependency-check reds". Assumes it is invoked from a folder containing the target repos. Distinct from handle-red-cve-plan, which fixes one repo from one Bamboo URL.
4
+ ---
5
+
6
+ # handle-weekly-cve-plans
7
+
8
+ One-shot orchestrator. Checks a fixed set of weekly Bamboo plans, finds the ones that are red
9
+ **because of CVEs**, and fans out one `handle-red-cve-plan` subagent per affected repo. All
10
+ remediation logic lives in `handle-red-cve-plan`; this skill only **routes, summarizes, and
11
+ gates the final push**. Runs the detection, ticket handling, and dispatch autonomously. It
12
+ stops for the user only twice: **immediately** when a target repo is blocked (tracked edits, or
13
+ an ambiguous ticket branch — a per-repo decision at dispatch, step 5.2), and the **push question** at the end
14
+ (step 7). Clean repos never wait on a blocked one.
15
+
16
+ ## Parameters
17
+
18
+ - **existing ticket** (optional) — a JIRA key (e.g. `PX-1234`) named at invocation ("handle
19
+ the weekly CVE plans PX-1234"). When supplied, that ticket is used as the tracking ticket and
20
+ **no new ticket is created**. When omitted, the skill creates one (step 3).
21
+
22
+ ## When NOT to use
23
+
24
+ - A single repo / single Bamboo URL → use `handle-red-cve-plan` directly.
25
+ - A local JSON dependency-check report in hand → use `handle-cve`.
26
+
27
+ ## Plan table (source of truth)
28
+
29
+ Repo name = expected sub-directory name under the invocation folder.
30
+
31
+ | Repo | Bamboo plan URL |
32
+ |---|---|
33
+ | caas-connect | https://ci.e-spirit.de/browse/CAASCAASCONNECT-WEEKLYMASTERBUILDUSINGSONATYPEOSS/latest |
34
+ | caas-fsm | https://ci.e-spirit.de/browse/CAASCAASFSM-WEEKLYMASTERBUILDUSINGSONATYPEOSS/latest |
35
+ | caas-platform | https://ci.e-spirit.de/browse/CAASCAASPLATFORM-WEEKLYCVECHECKUSINGSONATYPEOSS/latest |
36
+ | caas-platform-mcp | https://ci.e-spirit.de/browse/CAASCAASPLATFORMMCP-WEEKLYCVECHECKUSINGSONATYPEOSS/latest |
37
+ | navigation-service-fsm | https://ci.e-spirit.de/browse/NAVNAVIGATIONSERVICEFSM-WEEKLYMASTERBUILDUSINGSONATYPEOSS/latest |
38
+ | navigation-service-micronaut | https://ci.e-spirit.de/browse/NAVNAVIGATIONSERVICEMICRONAUT-WEEKLYCVECHECKUSINGSONATYPEOSS/latest |
39
+ | videomanagementpro | https://ci.e-spirit.de/browse/VIDVIDEOMANAGEMENTPRO-WEEKLYMASTERBUILDUSINGSONATYPEOSS/latest |
40
+ | smartsearch-connect | https://ci.e-spirit.de/browse/ZTSMARTSEARCHCONNECT-WEEKLYMASTERBUILDUSINGSONATYPEOSS/latest |
41
+ | haupia | https://ci.e-spirit.de/browse/SMASE-WDCS/latest |
42
+
43
+ Every plan is a Sonatype-OSS build → every dispatched subagent gets `useSonatype`.
44
+
45
+ ## Workflow
46
+
47
+ ### 1. Locate the repos
48
+ For each repo name, resolve its directory:
49
+ - Direct sub-directory of the invocation folder matching the name → use it.
50
+ - Miss → search the invocation folder and one level up.
51
+ - Still missing → collect the misses and **ask the user** for the path(s) before dispatching.
52
+ Repos the user cannot supply are recorded as `skipped: not found` and do not block the rest.
53
+
54
+ ### 2. Detect CVE-red plans (main thread, per plan)
55
+ Resolve each plan's latest build, then classify from state + log — **do not** download or
56
+ parse the dependency-check report artifact:
57
+
58
+ ```
59
+ get_bamboo_build(<PLAN>-latest)
60
+ state != Failed -> skip: green/ok
61
+ state == Failed:
62
+ get_bamboo_build_log(<build_key>)
63
+ log contains the marker line
64
+ "One or more dependencies were identified with vulnerabilities
65
+ that have a CVSS score greater than '7.0': CVE-..., CVE-..."
66
+ -> DISPATCH (capture the listed CVE ids for the report)
67
+ else -> skip: red, non-CVE reason
68
+ ```
69
+
70
+ The first `get_bamboo_build` failing on auth → **hard stop** (token/config problem): report and
71
+ dispatch nothing. A per-plan error after that (one build/log unreadable) is **isolated** — mark
72
+ that plan `skipped: <reason>` and continue with the others.
73
+
74
+ ### 3. Ensure a tracking ticket
75
+ Only if step 2 produced **at least one** dispatch target. No targets → skip this step entirely
76
+ (create no ticket).
77
+
78
+ - **User named an existing ticket at invocation** → use that key as `<TICKET>`. Create nothing,
79
+ add no label, do not transition it — leave the user's ticket as-is.
80
+ - **No ticket named** → create, label, and transition a new ticket. All of the following is
81
+ **pre-approved by the skill invocation** — do not pause for separate confirmations; print
82
+ each user-visible action (the create fields, and each `from -> to` status move) as you do it.
83
+
84
+ 1. **Create.** Call `mcp__plugin_planetexpress_jira-tools__create_jira_ticket`:
85
+ - `project_key`: `PX`
86
+ - `issue_type`: `Escaped Bug`
87
+ - `summary`: `Handle Weekly CVEs <date>` (today's date, `YYYY-MM-DD`)
88
+ - `labels`: `SIZE_XS`
89
+ - `description` (Jira wiki markup): one row per dispatch target — repo name, the CVE ids
90
+ from the log marker, and a link to that repo's Bamboo plan (the plan URL from the table).
91
+ E.g. `* [caas-connect|<plan-url>] — CVE-2026-54428, CVE-2026-54399`.
92
+ - Capture the returned key as `<TICKET>`.
93
+
94
+ 2. **Transition** through this target-status sequence, in order:
95
+ `Backlog → Committed → Specify → In Implementation` (the workflow's "Implement" state).
96
+ Status names and available transitions are **state-dependent — never hardcode ids**. For
97
+ each target in the sequence:
98
+ - If the ticket is already in that status, skip it.
99
+ - Otherwise call `mcp__plugin_planetexpress_jira-tools__transition_jira_ticket` with
100
+ `status` = the target name (it matches case-insensitively on target status or transition
101
+ name, one hop per call).
102
+ - If that errors because the target isn't directly reachable, the error lists the
103
+ transitions that *are* available — call `get_jira_transitions`, take the single hop that
104
+ advances toward the sequence, then retry the target. Repeat until the target is reached.
105
+ - Stop the walk at the first target that cannot be reached even via an intermediate hop:
106
+ report how far it got (`<TICKET>` reached status X) and continue to dispatch — a
107
+ not-fully-transitioned ticket does not block the CVE work.
108
+
109
+ `<TICKET>` (named or created) is passed to every subagent in step 5.
110
+
111
+ ### 4. Pre-flight cleanliness check (main thread, per dispatch target)
112
+ A blocker (tracked edits, or an ambiguous ticket branch) is **knowable up front with plain git** —
113
+ detect it here, in the main thread, before spending a subagent on it. A subagent cannot prompt
114
+ the user, and parallel subagents hand control back only after **all** finish; leaving this check
115
+ inside the subagent means a blocker surfaces (as `failed`) only once every other repo's build is
116
+ done. Catch it first instead.
117
+
118
+ For each target from step 2, run in the main thread (no build, seconds each):
119
+
120
+ ```
121
+ git -C <repo> fetch origin
122
+ git -C <repo> symbolic-ref refs/remotes/origin/HEAD # derive <default> (never assume master)
123
+ git -C <repo> status --porcelain -uno # tracked edits only; untracked files ignored (never blocking)
124
+ git -C <repo> branch --show-current # current branch
125
+ git -C <repo> branch -a --list "*<TICKET>*" # ticket-branch matches
126
+ ```
127
+
128
+ Classify each target. Two things are **not** blockers, because the subagent handles them itself:
129
+ - **Untracked files** — not touched by a branch switch or by the subagent, so a stray
130
+ unstaged/untracked file is irrelevant. Only *tracked* modifications (staged or unstaged edits
131
+ to tracked files) count as dirty.
132
+ - **The current branch** — `handle-red-cve-plan` step 4 switches off the latest default branch
133
+ (reusing the ticket branch if one exists, else creating one off `origin/<default>`) from
134
+ whatever branch is checked out. A clean tree on an unrelated branch is safe to switch away
135
+ from — no WIP is lost (committed work stays on its branch).
136
+
137
+ - **clean** — no tracked modifications (empty `status --porcelain -uno`) **and** at most one
138
+ branch matches `<TICKET>`. Dispatch as-is (step 5.1). Untracked files and the current branch
139
+ identity are irrelevant — dispatch anyway.
140
+ - **blocked** — tracked edits, **or** more than one branch matches `<TICKET>` (a genuine
141
+ ambiguity the subagent cannot resolve — `handle-red-cve-plan` step 4 hard-stops on it, so catch
142
+ it here before wasting a dispatch). Needs a user decision (step 5.2). Capture the blocking
143
+ evidence — the `status --porcelain -uno` lines and/or the matching branch list — to show the
144
+ user.
145
+
146
+ ### 5. Dispatch
147
+
148
+ **5.1 — Dispatch every clean target first, in the background.** Spawn all clean-target
149
+ subagents with `run_in_background: true` **before** raising any blocked repo, so their builds
150
+ start immediately and run while blocked repos are being resolved. A clean repo never waits on a
151
+ blocked one. Use the `general-purpose` agent type; prefix the description with `[opus]` per repo
152
+ convention.
153
+
154
+ **5.2 — Then resolve each blocked target interactively (main thread).** Only after the clean
155
+ targets are dispatched, raise the blocked ones — one `AskUserQuestion` per blocked repo, showing
156
+ its captured blocking evidence from step 4. The remedies depend on **why** it blocked:
157
+
158
+ **Blocked by tracked edits (dirty tree).** Offer three remedies:
159
+
160
+ - **Stash** — `git -C <repo> stash push -m "handle-weekly-cve pre-flight <date>"` parks the
161
+ tracked edits (no `-u`; untracked files are left in place, they never blocked). **Never pop it
162
+ automatically** — the subagent works on its own branch off the default; the stash stays parked
163
+ for the user to `git stash pop` manually later. Report the stash ref in step 6 so it is not
164
+ silently buried. Then dispatch the repo (background, same as 5.1).
165
+ - **Discard** — destructive. State exactly what is deleted before running:
166
+ `git -C <repo> switch <default> && git -C <repo> reset --hard origin/<default> && git -C <repo> clean -fd`.
167
+ Then dispatch (background).
168
+ - **Skip** — leave the repo entirely untouched; record `skipped: dirty tree (user chose skip)`
169
+ and do not dispatch.
170
+
171
+ **Blocked by an ambiguous ticket branch (>1 branch matches `<TICKET>`).** A tree remedy does not
172
+ apply, and `handle-red-cve-plan` has no parameter to pick a branch — it hard-stops on ambiguity.
173
+ Offer two remedies:
174
+
175
+ - **Skip** — record `skipped: multiple <TICKET> branches (<list>)` and do not dispatch.
176
+ - **Resolve manually** — the user deletes/renames the stray branch(es) so exactly one matches,
177
+ confirms, then re-run the step-4 check for this repo only; once a single branch matches it is
178
+ **clean** — dispatch it (background). Do **not** delete branches automatically.
179
+
180
+ Each subagent prompt (clean or resolved) must:
181
+ - State the absolute repo path and instruct it to `cd` there first (that path is its working
182
+ directory for the whole run — `handle-red-cve-plan` operates on the current directory).
183
+ - Instruct it to invoke the `handle-red-cve-plan` skill for that plan's Bamboo URL **with
184
+ `useSonatype`** and the tracking ticket **`<TICKET>`**, running fully autonomously (no
185
+ confirmation stops).
186
+ - Require it to return a single structured result and nothing else:
187
+ - `repo` — the repo name
188
+ - `outcome` — one of `pr` | `unpushed-commit` | `nothing-to-do` | `failed`
189
+ - `link` — PR URL (for `pr`) or commit SHA + default-branch name (for `unpushed-commit`)
190
+ - `detail` — one line: CVEs bumped/suppressed, or the failure/hard-stop reason
191
+
192
+ A subagent that dies or hard-stops → its repo is `failed` with the reason. It never blocks the
193
+ other subagents or the final report. (The pre-flight guard in `handle-red-cve-plan` step 4
194
+ remains a backstop: if a tree goes dirty between the check and dispatch, that subagent still
195
+ `failed`s rather than committing over it.)
196
+
197
+ ### 6. Report
198
+ Lead with the tracking ticket (`<TICKET>` — created or reused). Then print a summary table
199
+ `repo | outcome | link/SHA/reason`, then group:
200
+ - **PRs opened** (`pr`, Path B) — with URLs.
201
+ - **Unpushed commits on default branch** (`unpushed-commit`, Path A suppressions-only) — repo,
202
+ SHA, branch. These are the only ones that still need pushing.
203
+ - **Pre-flight resolutions** — any repo that was stashed, discarded, or skipped in step 5.2.
204
+ - **Parked stashes (restore manually)** — every repo where the user chose **Stash**: repo +
205
+ stash ref/message. These are loose ends the user must `git stash pop` themselves — surface them
206
+ explicitly so nothing is buried.
207
+ - **Skipped** — green, non-CVE red, not-found (with which), or user-skipped blocks (dirty tree
208
+ or ambiguous ticket branch).
209
+ - **Failed** — repo + reason.
210
+
211
+ ### 7. Push gate (only stop)
212
+ Path B branches are already pushed and PR'd by the subagent — nothing to do. Only the Path A
213
+ `unpushed-commit` repos have local commits sitting on their default branch. Finish by asking
214
+ the user whether to push those. On **yes**: for each such repo, push the exact commit that was
215
+ reported (its default branch) and confirm each. On **no**: leave them local and stop.
216
+
217
+ Restate any **parked stashes** from step 6 alongside the push gate — they still need a manual
218
+ `git stash pop` and are easy to forget.
219
+
220
+ ## Hard stops (report, dispatch nothing)
221
+
222
+ | Situation | Behaviour |
223
+ |---|---|
224
+ | Very first `get_bamboo_build` fails on auth | Token/config problem — report and stop before dispatching |
225
+ | User cannot supply any repo path and asks to abort | Report what was found and stop |
226
+ | Ticket creation fails (step 3, no existing ticket named) | Report and stop — do not dispatch subagents without a tracking ticket |
227
+
228
+ ## Constraints
229
+
230
+ - Never merge PRs (subagent opens them; merge is the user's call).
231
+ - Never push Path B branches (already pushed).
232
+ - Never push a Path A commit before the user answers the push gate.
233
+ - Never edit repo files in the main thread — all remediation happens inside subagents via
234
+ `handle-red-cve-plan`. The **only** main-thread git mutations allowed are the user-chosen
235
+ pre-flight remedies in step 5.2 (stash / discard), and only for the specific blocked repo the
236
+ user picked them for.
237
+ - Never auto-pop a stash created in step 5.2 — park it, report it, leave restoration to the user.
238
+ - Do not download/parse the OWASP report in the main thread; detection is log-based only.
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: retrospect
3
+ description: Use when the user asks to review, retrospect, or post-mortem the current Claude Code session — phrases like "retrospect this session", "what went wrong this session", "analyse my prompts", "session retrospective", "/retrospect". Triggers on requests to look back over a session's prompts and find what could be improved in the harness.
4
+ ---
5
+
6
+ # Retrospect
7
+
8
+ ## Overview
9
+
10
+ Analyses a Claude Code session transcript and produces a structured HTML report listing **every** prompt the user sent, what each one led to, which ones went suboptimally (highlighted red), and — for the problematic ones — a **class-level** improvement to the harness so the same *type* of problem is avoided or reduced in future.
11
+
12
+ **Core principle:** Completeness is mechanical, judgment is yours. A bundled script enumerates every prompt from the transcript (you can never drop or summarise one). Your job is only to judge each prompt and write improvements that generalise — never improvements that would fire only on the one exact situation.
13
+
14
+ ## When to Use
15
+
16
+ - User asks to retrospect / post-mortem / review the current session.
17
+ - User wants to know what could be improved in their setup based on how the session went.
18
+
19
+ Not for: reviewing a PR or ticket (use `review`), or summarising work for JIRA (use `summarise-for-jira-comment`).
20
+
21
+ ## Workflow
22
+
23
+ The extractor/renderer script `extract_prompts.py` lives in this skill's directory. Run it with `python3`.
24
+
25
+ 1. **Extract** — run `extract_prompts.py extract`. With no `--transcript` it auto-selects the newest `.jsonl` in the current project's transcript dir = the session you are in. Output goes to `.claude/retrospects/` by default; override with `--outdir DIR`. It writes `<stamp>-data.json` and prints `{data_file, analysis_file, html_file, count}` — use those exact paths in the later steps. `count` = N, the number of prompts you must analyse.
26
+ 2. **Read** the `data_file`. It holds `prompts: [{n, text, trace}]` — `trace` has a compact `assistant_summary` and the `tools` used after that prompt.
27
+ 3. **Analyse** every prompt. Build the analysis object (see schema below), keyed by prompt number as a string. Mark only genuinely suboptimal prompts/results as problems; the rest get a short `note`.
28
+ 4. **Write** the analysis object to the printed `analysis_file` path (JSON).
29
+ 5. **Render** — run `extract_prompts.py render --data <data_file> --analysis <analysis_file>`. It prints `{html_file, count, flagged, missing_analysis}`.
30
+ 6. **Verify gate** — `missing_analysis` MUST be `0`. If it is not, you skipped prompts; add the missing keys and re-render. Do not report until it is 0.
31
+ 7. **Report** — present the report as a **clickable link** plus a one-line tally (N prompts, X flagged). Resolve `html_file` to an absolute path and give it as a `file://` markdown link, e.g. `[Open retrospect](file:///abs/path/to/...-retrospect.html)`, so the user can click straight through. Stop. Do not edit CLAUDE.md, skills, or any config — this skill is report-only.
32
+
33
+ ## Analysis JSON Schema
34
+
35
+ Object keyed by prompt number (string). Each value:
36
+
37
+ | Field | When | Meaning |
38
+ |-------|------|---------|
39
+ | `topic` | every prompt, where applicable | Short group label (≤~40 chars). Prompts sharing a `topic` render together as one collapsible group, in first-appearance order. |
40
+ | `problem` | suboptimal prompts only | What went wrong with the prompt or the result it produced. |
41
+ | `suggestion` | with `problem` | The **class-level** improvement (see rule below). |
42
+ | `location` | with `problem` | Where the improvement belongs (see taxonomy below). |
43
+ | `impact` | with `problem` | Integer 1–5, how much value fixing this class would deliver (5 = high). Drives ranking of the top-of-document Suggestions list. |
44
+ | `note` | OK prompts | One short line; why it was fine. Omit `problem`/`suggestion`. |
45
+
46
+ Besides `topic`, a prompt has exactly one of: `{problem, suggestion, location}` OR `{note}`.
47
+
48
+ **Topics / grouping:** assign a `topic` to each prompt so the report clusters related prompts (e.g. all prompts about one feature share `"topic": "Auth refactor"`). Group only where a genuine theme exists — don't force unrelated prompts together. Prompts you leave without a `topic` fall into a trailing "Ungrouped" bucket. Reuse the exact same string to put prompts in the same group.
49
+
50
+ ## Report Layout
51
+
52
+ The rendered HTML gives the user, in this order: a sticky left **table of contents** (Suggestions + every group with its prompts; flagged prompts shown red), a **Suggestions** section at the top listing the **top 10 flagged prompts ranked by `impact`** (each a class-level fix with a link jumping to that prompt; if more than 10 are flagged the rest still show red inside their groups but are not in the headline list), then the prompts as **collapsible topic groups**, **collapsed by default** (each showing its prompt count and a red flag-count badge). A **Collapse/Expand all** button toggles every group; following a Suggestion or TOC link auto-expands the target group. This layout is produced entirely by `render`; you only supply `topic`, `impact`, and the rest of the analysis.
53
+
54
+ **What counts as a problem:** avoidable friction attributable to the agent or the harness setup — wrong turns, rework, misread intent, work thrown away, missing verification. A user changing their mind, reversing scope, or steering mid-task is **not** a problem; it is normal collaboration — give it a `note`. If churn followed a user reversal, attribute the flag (if any) to whatever the agent did prematurely *before* the reversal (e.g. wrote a full spec for a heavyweight option that wasn't yet committed to), not to the user's prompt itself.
55
+
56
+ A clean session can legitimately produce **zero** flags. Do not manufacture problems to fill the report — the generality rule already says a missing suggestion beats a useless one.
57
+
58
+ ## The Generality Rule (the hard part)
59
+
60
+ Every suggestion must target a **class** of problem, not the single instance.
61
+
62
+ **Test each suggestion:** *"Could this ever fire again on a different task, file, or ticket?"* If the honest answer is no — it only ever applies to this exact prompt — it is worthless. Rewrite it broader, or drop the flag entirely (a missing suggestion beats a useless one).
63
+
64
+ | ❌ Too specific (worthless) | ✅ Class-level (keep) |
65
+ |---|---|
66
+ | "Remember HP-1234 needs the `link_jira_issues` MCP call." | "When a ticket references another ticket, check for a linking step before closing — add a linking check to the JIRA workflow." |
67
+ | "Don't forget the `extract_prompts.py` script needs `command-args` stripped." | "When parsing transcripts, treat slash-command wrapper tags as non-content and skip empty turns." |
68
+ | "You should have read foo.py line 42." | "Before claiming a causal 'X is handled by Y', cite file:line — verify before asserting." |
69
+
70
+ A good suggestion describes a *trigger condition* + *behaviour*, both phrased so they recur.
71
+
72
+ ## Target-Location Taxonomy
73
+
74
+ Pick the narrowest location that still catches the whole class:
75
+
76
+ - **global CLAUDE.md** — cross-project habits (verification discipline, citation rules, commit style).
77
+ - **project CLAUDE.md** (or a file it references) — conventions specific to this repo/tech stack.
78
+ - **an editable skill** — name it — a `planetexpress` plugin skill or one of the user's personal `~/.claude/skills/`, when the class fits a workflow there that just needs a guard added.
79
+ - **new skill** — when the class is a reusable technique/workflow with no current home; give it a one-line name + purpose.
80
+
81
+ Prefer fixing an existing artifact over proposing a new skill; new skills are justified only when no existing location fits.
82
+
83
+ **`planetexpress` is the only editable plugin.** Skills in any other plugin — `superpowers:`, `caveman:`, etc. — are installed copies we cannot edit, so they are never a valid fix `location`. The only valid fix targets are: global CLAUDE.md, project CLAUDE.md (or a file it references), the user's personal `~/.claude/skills/`, and the `planetexpress` plugin (this repo).
84
+
85
+ When a problem genuinely originates in a non-editable skill, say so in `problem` (e.g. "the `superpowers:brainstorming` skill let a full spec be written before the approach was confirmed"), but the `suggestion` + `location` must point at one of those editable targets in a way that intercepts the same class: a guard line in global/project CLAUDE.md, or a `planetexpress` (or personal) skill that adds the missing check before/around the third-party skill runs.
86
+
87
+ ## Common Mistakes
88
+
89
+ - **Summarising prompts instead of analysing all N.** The script already enumerated them; the `missing_analysis` gate will catch you. Never report with it > 0.
90
+ - **Instance-level suggestions.** "Do X for this ticket" is noise. Apply the generality test to every one.
91
+ - **Flagging everything.** Most prompts are fine. Red is for genuine friction — wrong turns, rework, misunderstood intent, avoidable back-and-forth.
92
+ - **Editing config.** Report-only. Suggest locations; let the user act.
93
+ - **Inventing prompts or reordering.** Use the script's data verbatim.
94
+ - **Forgetting `impact` on a problem.** Without it the suggestion sorts last and may fall outside the top 10. Always set `impact` (1–5) when you set `problem`.