@codyswann/lisa 2.9.1 → 2.10.0

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 (35) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/agents/learnings-synthesizer.md +135 -0
  4. package/plugins/lisa/agents/pr-mining-specialist.md +85 -0
  5. package/plugins/lisa/agents/tracker-mining-specialist.md +85 -0
  6. package/plugins/lisa/commands/debrief/apply.md +6 -0
  7. package/plugins/lisa/commands/debrief.md +6 -0
  8. package/plugins/lisa/hooks/enforce-team-first.sh +9 -3
  9. package/plugins/lisa/rules/intent-routing.md +97 -17
  10. package/plugins/lisa/skills/confluence-to-tracker/SKILL.md +14 -0
  11. package/plugins/lisa/skills/debrief/SKILL.md +79 -0
  12. package/plugins/lisa/skills/debrief-apply/SKILL.md +63 -0
  13. package/plugins/lisa/skills/github-to-tracker/SKILL.md +14 -0
  14. package/plugins/lisa/skills/linear-to-tracker/SKILL.md +14 -0
  15. package/plugins/lisa/skills/notion-to-tracker/SKILL.md +14 -0
  16. package/plugins/lisa/skills/prd-backlink/SKILL.md +89 -0
  17. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  22. package/plugins/src/base/agents/learnings-synthesizer.md +135 -0
  23. package/plugins/src/base/agents/pr-mining-specialist.md +85 -0
  24. package/plugins/src/base/agents/tracker-mining-specialist.md +85 -0
  25. package/plugins/src/base/commands/debrief/apply.md +6 -0
  26. package/plugins/src/base/commands/debrief.md +6 -0
  27. package/plugins/src/base/hooks/enforce-team-first.sh +9 -3
  28. package/plugins/src/base/rules/intent-routing.md +97 -17
  29. package/plugins/src/base/skills/confluence-to-tracker/SKILL.md +14 -0
  30. package/plugins/src/base/skills/debrief/SKILL.md +79 -0
  31. package/plugins/src/base/skills/debrief-apply/SKILL.md +63 -0
  32. package/plugins/src/base/skills/github-to-tracker/SKILL.md +14 -0
  33. package/plugins/src/base/skills/linear-to-tracker/SKILL.md +14 -0
  34. package/plugins/src/base/skills/notion-to-tracker/SKILL.md +14 -0
  35. package/plugins/src/base/skills/prd-backlink/SKILL.md +89 -0
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: debrief
3
+ description: "Run the Debrief flow over a shipped initiative. Input: a PRD URL (Notion / Confluence / Linear / GitHub Issue / file), a JIRA epic key, or a GitHub epic issue URL. Output: a triage-ready learnings document covering every work item in the initiative — edge cases, gotchas, process friction, tooling gaps, convention drift — each with structured evidence and a human-disposition field. Persistence is deferred to lisa:debrief-apply."
4
+ allowed-tools: ["Skill", "ToolSearch", "TeamCreate", "Bash", "Read", "Glob", "Grep"]
5
+ ---
6
+
7
+ # Debrief: $ARGUMENTS
8
+
9
+ Walk the original Plan for `$ARGUMENTS`, mine the completed work items and their PRs, and produce a triage-ready learnings document for human review.
10
+
11
+ ## Orchestration: agent team
12
+
13
+ If you are NOT already operating inside an agent team (no prior `TeamCreate` in this session, not spawned via `Agent` with `team_name`), the very first thing you do is create the team. Two tool calls only, in this exact order:
14
+
15
+ 1. `ToolSearch` with `query: "select:TeamCreate"` — `TeamCreate` is a deferred tool whose schema must be loaded before it can be invoked. A cold call returns `InputValidationError` and tempts a fallback to direct `Agent` calls, which bypasses the team.
16
+ 2. `TeamCreate` — actually create the team.
17
+
18
+ Until `TeamCreate` returns successfully, do NOT call any of: `Agent`, `TaskCreate`, `Skill`, MCP tools (Atlassian / Linear / GitHub / Notion), `Read`, `Write`, `Edit`, `Bash`, `Grep`, `Glob`. Resolving the work-item set, fetching tickets, walking PRs — all of those are tasks for the team you are about to create, not for the lead session before the team exists.
19
+
20
+ If you ARE already inside an agent team (e.g., a teammate invoked this skill via the Skill tool), do NOT call `TeamCreate` — the harness rejects double-creates. Continue within the existing team.
21
+
22
+ ## Input
23
+
24
+ `$ARGUMENTS` is one of:
25
+
26
+ | Input shape | Resolution |
27
+ |-------------|------------|
28
+ | Notion / Confluence / Linear / GitHub Issue PRD URL | Fetch the PRD; read its `## Tickets` (or equivalent) back-link section written by the Plan flow |
29
+ | File path to a PRD markdown | Read the file; parse its `## Tickets` section |
30
+ | JIRA epic key (e.g. `SE-1234`) or epic URL | Fetch the epic; list its child issues (Stories, Tasks, Bugs) |
31
+ | GitHub epic issue URL or `<org>/<repo>#<n>` | Fetch the epic issue; list its sub-issues / linked items |
32
+
33
+ If the PRD has no `## Tickets` section AND the input is not an epic, stop and report — the Plan flow's PRD back-link step (`lisa:prd-backlink`) was likely skipped. Suggest re-running Plan to populate the section, or pass the epic key directly.
34
+
35
+ ## Gate
36
+
37
+ Run before mining begins:
38
+
39
+ 1. **All work items terminal.** Every linked work item must be in a terminal state (Done / Closed / Cancelled equivalent for the tracker). If any item is still open, stop and list the unfinished items — Debrief is post-shipping by definition.
40
+ 2. **PR coverage.** Every Done item that was implementable (Story / Task / Bug; not Spike) must have at least one merged PR linked. Items missing a PR are recorded as **anomalies** to surface in the report rather than silently excluded — a Done item with no PR is itself a learning ("how did this ship?").
41
+ 3. **Headless safety.** In headless / `-p` / scheduled mode, do not block on missing input — fail fast with a clear error listing what was needed.
42
+
43
+ ## Flow
44
+
45
+ Execute the **Debrief** flow as defined in the `intent-routing` rule (loaded via the lisa plugin). The rule contains the canonical step sequence (gate, mining, synthesis, output, hand-off). This skill does NOT restate flow steps — change them in the rule, propagate everywhere.
46
+
47
+ The flow's mining step runs `tracker-mining-specialist` and `pr-mining-specialist` in parallel as separate tasks within the team. Both must complete before `learnings-synthesizer` runs. Express this with `blockedBy` so the synthesizer task is automatically gated on the two mining tasks.
48
+
49
+ ## Exhaustiveness expectation
50
+
51
+ Debrief is deliberately exhaustive — the human, not the agent, decides what is worth keeping. Specialists should err toward surfacing more candidates, not fewer. A candidate that the synthesizer rates low confidence is still a row in the triage doc; only outright duplicates are dropped.
52
+
53
+ ## Output
54
+
55
+ A markdown triage document at `./debrief/<initiative-slug>-<YYYY-MM-DD>.md` (or wherever the project's debrief output directory is configured) containing:
56
+
57
+ 1. **Header** — initiative name, source PRD/epic link, work-item count, PR count, generation date, gate results.
58
+ 2. **Anomalies** — work items missing PRs, items with abnormal status-transition timing, PRs with no review comments at all (signal-of-absence is a learning), etc.
59
+ 3. **Candidate learnings** — one row per candidate, grouped by category (Edge case / Recurring gotcha / Process friction / Tooling gap / Convention drift). Each row has:
60
+ - `Summary` — one sentence
61
+ - `Category`
62
+ - `Evidence` — links to the source ticket comment / PR comment / commit / test file (multiple allowed)
63
+ - `Recommended persistence destination` — the agent's best guess for where this should land if accepted (e.g., "Edge Case Brainstorm checklist → Navigation & URL state", "PROJECT_RULES.md", "memory: project_*.md", "new tooling-gap ticket")
64
+ - `Disposition` — empty checkbox-style field the human will fill: `[ ] Accept` / `[ ] Reject` / `[ ] Defer` plus a free-text reason
65
+ 4. **Source map** — appendix listing every work item and PR walked, so the human can verify completeness.
66
+
67
+ The skill's terminal output is the path to the triage document and a one-line summary of counts per category. Persistence does not happen here — that is `lisa:debrief-apply`'s job.
68
+
69
+ ## Hand-off
70
+
71
+ After producing the triage document, print:
72
+
73
+ ```text
74
+ Triage document written to: <path>
75
+ Counts: <n> edge cases, <n> gotchas, <n> friction, <n> tooling gaps, <n> convention drift; <n> anomalies
76
+ Next: human triage. When done, run `/lisa:debrief:apply <path>` to persist accepted learnings.
77
+ ```
78
+
79
+ Then stop. Debrief never persists learnings on its own.
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: debrief-apply
3
+ description: "Apply human-marked dispositions from a Debrief triage document. Reads the triage doc produced by lisa:debrief, parses each row's disposition (Accept / Reject / Defer), and routes Accepted items to their persistence destination. Deterministic and idempotent — safe to re-run if dispositions are added incrementally."
4
+ allowed-tools: ["Skill", "Bash", "Read", "Edit", "Write", "Glob", "Grep"]
5
+ ---
6
+
7
+ # Debrief Apply: $ARGUMENTS
8
+
9
+ Read the triage document at `$ARGUMENTS` and persist every Accepted candidate learning to its destination.
10
+
11
+ This skill is intentionally **single-agent** — there is no team. Routing is deterministic given the disposition column. Spawning sub-agents would only add latency.
12
+
13
+ ## Input
14
+
15
+ A path or URL to a Debrief triage document produced by `lisa:debrief`. The document is expected to follow the structure that skill produces — a header, an anomalies section, candidate-learning rows grouped by category, and a source-map appendix.
16
+
17
+ ## Pre-flight
18
+
19
+ 1. **Verify the doc exists and parses.** If the file cannot be read or the expected sections are missing, stop and report — do not guess.
20
+ 2. **Confirm dispositions exist.** If every row is unmarked, stop and ask the human to triage first. A pristine doc is a no-op, not an error to silently swallow.
21
+ 3. **Identify the destination map.** Read the project's `.lisa.config.json` (or stack defaults) for: edge-case checklist file (default: `plugins/src/base/rules/intent-routing.md`'s Edge Case Brainstorm sub-flow), project-rules file (default: `.claude/rules/PROJECT_RULES.md`), memory directory (per the auto-memory system path), tracker for new tickets.
22
+
23
+ ## Routing rules
24
+
25
+ For every row marked **Accept**:
26
+
27
+ | Category | Destination | Action |
28
+ |----------|-------------|--------|
29
+ | Edge case | Edge Case Brainstorm checklist in `intent-routing.md` | Append the new pattern + question to the matching group (Navigation, Data, Failure, Input, Auth, or a new group if none fit). Use the row's `Summary` and `Evidence` link as a citation comment. |
30
+ | Recurring gotcha | Memory file (`project_*.md`) | Write a new memory entry with `type: project`, structured as: rule, **Why:**, **How to apply:**. Add an index line to `MEMORY.md`. |
31
+ | Process friction | Project rules file | Append a one-line guideline to `PROJECT_RULES.md` under an appropriate heading (or create one). |
32
+ | Tooling gap | Configured tracker | Create a new ticket via `lisa:tracker-write` with `issue_type: Task`, summary derived from the row's `Summary`, description citing the evidence and the originating debrief doc. Label appropriately (`type:tooling`, `lifecycle-improvement`, etc.). |
33
+ | Convention drift | `CLAUDE.md` (project) or `PROJECT_RULES.md` | Append the convention as a one-paragraph note under the relevant section. If no relevant section exists, create one. |
34
+
35
+ For every row marked **Reject** or **Defer**: no action. Defer is a no-op for `apply` but worth surfacing in the run summary — the human may want to revisit at the next debrief.
36
+
37
+ ## Idempotency
38
+
39
+ `apply` is safe to re-run. Each Accepted row carries an evidence link that doubles as a fingerprint — before writing, check whether the destination already cites that fingerprint. If it does, skip the write and note the row as `already-applied` in the run summary. This lets the human triage a doc incrementally (mark a few, run apply, mark more, run apply again) without producing duplicates.
40
+
41
+ ## Updating the triage doc
42
+
43
+ After each Accepted row is persisted, replace its `[ ] Accept` checkbox with `[x] Applied — <one-line summary of what was written>`. This makes the triage doc itself the audit log of what was acted on. If a write fails (e.g., tracker is unreachable), mark the row `[!] Apply failed — <reason>` and continue with the rest. Never abort the whole run because one row failed.
44
+
45
+ ## Output
46
+
47
+ A run summary printed to the user:
48
+
49
+ ```text
50
+ Applied <n> learnings:
51
+ <n> edge cases → intent-routing.md
52
+ <n> gotchas → memory
53
+ <n> friction → PROJECT_RULES.md
54
+ <n> tooling gaps → <tracker> (<key1>, <key2>, ...)
55
+ <n> convention drift → CLAUDE.md
56
+ Skipped:
57
+ <n> rejected, <n> deferred, <n> already-applied
58
+ Failed:
59
+ <n> (see <path> for details)
60
+ Triage doc updated in place: <path>
61
+ ```
62
+
63
+ If anything is written to a tracker, suggest the human commit the local file changes (memory, rules, intent-routing) when ready — `apply` does not commit.
@@ -252,6 +252,20 @@ After all tickets are created, present a summary table to the user:
252
252
  - Blockers list with recommendations and alternatives
253
253
  - Cross-PRD dependencies
254
254
 
255
+ ### Phase 7: PRD Back-link
256
+
257
+ > **Mode guard**: In `dry_run: true` mode, skip this phase entirely — no tickets exist to link.
258
+
259
+ After Phase 6, invoke the `lisa:prd-backlink` skill to write a `## Tickets` section back into the source GitHub Issue PRD body. The section becomes the canonical anchor for the **Debrief** flow once the initiative ships.
260
+
261
+ Invoke `lisa:prd-backlink` with:
262
+
263
+ - `source_type: "github"`
264
+ - `source_ref`: the original GitHub Issue URL or `<org>/<repo>#<n>` token
265
+ - `tickets`: the full list created in Phases 3–5, each entry as `{ key, title, type, url, parent_key }`
266
+
267
+ If `lisa:prd-backlink` fails (permission denied, GitHub unreachable, issue locked), surface the error in the Phase 6 report rather than aborting — the tickets are already created. Recommend the user re-run `lisa:prd-backlink` standalone once the source is reachable.
268
+
255
269
  ## Handling Ambiguities and Blockers
256
270
 
257
271
  When you encounter something the PRD + comments + codebase can't resolve:
@@ -252,6 +252,20 @@ After all tickets are created, present a summary table to the user:
252
252
  - Blockers list with recommendations and alternatives
253
253
  - Cross-PRD dependencies
254
254
 
255
+ ### Phase 7: PRD Back-link
256
+
257
+ > **Mode guard**: In `dry_run: true` mode, skip this phase entirely — no tickets exist to link.
258
+
259
+ After Phase 6, invoke the `lisa:prd-backlink` skill to write a `## Tickets` section back into the source Linear project (or its description). The section becomes the canonical anchor for the **Debrief** flow once the initiative ships.
260
+
261
+ Invoke `lisa:prd-backlink` with:
262
+
263
+ - `source_type: "linear"`
264
+ - `source_ref`: the original Linear project URL
265
+ - `tickets`: the full list created in Phases 3–5, each entry as `{ key, title, type, url, parent_key }`
266
+
267
+ If `lisa:prd-backlink` fails (permission denied, Linear unreachable), surface the error in the Phase 6 report rather than aborting — the tickets are already created. Recommend the user re-run `lisa:prd-backlink` standalone once the source is reachable.
268
+
255
269
  ## Handling Ambiguities and Blockers
256
270
 
257
271
  When you encounter something the PRD + comments + codebase can't resolve:
@@ -264,6 +264,20 @@ After all tickets are created, present a summary table to the user:
264
264
  - Blockers list with recommendations and alternatives
265
265
  - Cross-PRD dependencies
266
266
 
267
+ ### Phase 7: PRD Back-link
268
+
269
+ > **Mode guard**: In `dry_run: true` mode, skip this phase entirely — no tickets exist to link.
270
+
271
+ After Phase 6, invoke the `lisa:prd-backlink` skill to write a `## Tickets` section back into the source PRD. The section becomes the canonical anchor for the **Debrief** flow once the initiative ships, and gives any human reading the PRD months later a one-click path to every work item created from it.
272
+
273
+ Invoke `lisa:prd-backlink` with:
274
+
275
+ - `source_type: "notion"`
276
+ - `source_ref`: the original PRD URL
277
+ - `tickets`: the full list created in Phases 3–5, each entry as `{ key, title, type, url, parent_key }`
278
+
279
+ If `lisa:prd-backlink` fails (PRD permission denied, Notion unreachable, source mutated mid-run), surface the error in the Phase 6 report rather than aborting — the tickets are already created and their value to the team is not blocked by the back-link write. Recommend the user re-run `lisa:prd-backlink` standalone once the source is reachable again.
280
+
267
281
  ## Handling Ambiguities and Blockers
268
282
 
269
283
  When you encounter something the PRD + comments + codebase can't resolve:
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: prd-backlink
3
+ description: "Update a source PRD with a `## Tickets` section linking back to every work item created from it. Vendor-aware on the source side (Notion / Confluence / Linear / GitHub Issue / file) and tracker-agnostic on the ticket side. Idempotent — regenerates the section on each run rather than appending, so re-planning never accumulates stale links. Invoked by the *-to-tracker skills at the end of their pipeline and standalone if a PRD's Tickets section needs to be refreshed."
4
+ allowed-tools: ["Skill", "Bash", "Read", "Edit", "Write", "Glob", "Grep"]
5
+ ---
6
+
7
+ # PRD Back-link
8
+
9
+ Write or update the `## Tickets` section of a source PRD so it links to every work item created from that PRD. The Debrief flow (and a human reading the PRD months later) uses this section as the canonical work-item set for the initiative.
10
+
11
+ ## Input
12
+
13
+ Pass `$ARGUMENTS` as a single JSON-style block:
14
+
15
+ ```json
16
+ {
17
+ "source_type": "notion" | "confluence" | "linear" | "github" | "file",
18
+ "source_ref": "<URL, page id, project id, issue ref, or absolute file path>",
19
+ "tickets": [
20
+ { "key": "<tracker-key>", "title": "<summary>", "type": "Epic|Story|Task|Sub-task|Bug|Spike", "url": "<link>", "parent_key": "<key or null>" }
21
+ ],
22
+ "section_heading": "## Tickets" // optional override; default "## Tickets"
23
+ }
24
+ ```
25
+
26
+ ## Behaviour
27
+
28
+ 1. **Fetch the current PRD content** using the source's native read tool:
29
+ - `notion` → `notion-fetch`
30
+ - `confluence` → `getConfluencePage`
31
+ - `linear` → Linear MCP project / issue read
32
+ - `github` → `gh issue view`
33
+ - `file` → `Read` tool on the absolute path
34
+ 2. **Locate the existing section.** Search for `section_heading` (default `## Tickets`). If present, you will replace it. If not, you will append a new section just before any closing footer / sign-off / signature block, otherwise at the end.
35
+ 3. **Render the section.** Use the format below. Group by Epic. Within an Epic, group by Story. Sub-tasks nest under their Story. Bugs and Spikes that are not under a Story go in a flat list at the bottom.
36
+ 4. **Write the updated PRD back** using the source's native write tool:
37
+ - `notion` → `notion-update-page`
38
+ - `confluence` → `updateConfluencePage`
39
+ - `linear` → Linear MCP update
40
+ - `github` → `gh issue edit --body`
41
+ - `file` → `Edit` (preferred) or `Write` (full rewrite if needed)
42
+ 5. **Return** the rendered section (so the caller can include it in its own report) and the source URL of the updated PRD.
43
+
44
+ ## Format
45
+
46
+ The rendered section must be deterministic — same inputs produce identical output bytes. This is what makes idempotency reliable.
47
+
48
+ ```markdown
49
+ ## Tickets
50
+
51
+ _Generated by `lisa:prd-backlink`. Regenerated on every Plan run; do not edit by hand._
52
+
53
+ ### <Epic key>: <Epic title>
54
+
55
+ - [<Epic key>](<url>) — Epic
56
+ - [<Story key>](<url>) — Story: <title>
57
+ - [<Sub-task key>](<url>) — Sub-task: <title>
58
+ - [<Sub-task key>](<url>) — Sub-task: <title>
59
+ - [<Story key>](<url>) — Story: <title>
60
+
61
+ ### <Epic key>: <Epic title>
62
+ ...
63
+
64
+ ### Unparented items
65
+
66
+ - [<Bug key>](<url>) — Bug: <title>
67
+ - [<Spike key>](<url>) — Spike: <title>
68
+ ```
69
+
70
+ If the input contains zero items, write the section header with a single line: `_No tickets created — Plan flow may not have completed._` Do not omit the section; presence-of-section is itself a signal to Debrief.
71
+
72
+ ## Idempotency
73
+
74
+ Rendering rules:
75
+ - Sort epics by key (lexical). Sort stories within an epic by key. Sort sub-tasks within a story by key. Sort the unparented list by `(type, key)`.
76
+ - The line `_Generated by ..._` is fixed text — does not include a timestamp. A timestamp would defeat the diff-equality check Debrief relies on.
77
+
78
+ ## Failures
79
+
80
+ - **Source unreachable / permission denied.** Stop and report. Do not silently swallow.
81
+ - **Section already present but in a non-standard format** (e.g., user hand-edited it). Replace it anyway — the warning line `_do not edit by hand_` is the contract. Note in the run output that an existing section was overwritten.
82
+ - **Source is a Notion database URL, a Confluence space URL, or any other non-page input.** Stop — back-linking only makes sense against a single PRD page, not a queue. Direct the caller to pass the specific page.
83
+
84
+ ## Output
85
+
86
+ ```text
87
+ PRD back-link updated: <source_url>
88
+ Section: ## Tickets — <n> epics, <n> stories, <n> sub-tasks, <n> unparented (<bugs/spikes>)
89
+ ```
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: learnings-synthesizer
3
+ description: "Learnings synthesizer for the Debrief flow. Consumes the parallel outputs of tracker-mining-specialist and pr-mining-specialist, deduplicates, categorizes each candidate into one of {edge case, recurring gotcha, process friction, tooling gap, convention drift}, and produces the human-triage document. Exhaustive — surfaces every candidate, even low-confidence ones, because the human decides what to keep."
4
+ skills: []
5
+ ---
6
+
7
+ # Learnings Synthesizer Agent
8
+
9
+ You are a learnings synthesizer. Your job is to combine the parallel mining outputs into a single triage-ready document the human will mark up. You do not gather raw evidence yourself; you wait for the two miners to finish and then reconcile.
10
+
11
+ ## Scope
12
+
13
+ You answer one question: **For every signal the miners surfaced, what category of learning is it, and how should the human triage it?**
14
+
15
+ What you do NOT decide:
16
+ - Whether a signal is "worth keeping". That is the human's call. Surface it; let them mark Reject if they disagree.
17
+ - Whether the spec was correct. That is `spec-conformance-specialist`.
18
+ - What gets persisted where. That is `lisa:debrief-apply`, after the human triages.
19
+
20
+ You **categorize** and **dedupe**. That is it.
21
+
22
+ ## Inputs
23
+
24
+ You receive two structured reports from the team lead:
25
+ - `tracker_findings.md` produced by `tracker-mining-specialist`
26
+ - `pr_findings.md` produced by `pr-mining-specialist`
27
+
28
+ If either is missing, block and request it. Do not synthesize on partial input.
29
+
30
+ ## Categorization rules
31
+
32
+ Map every finding to exactly one category. When a finding could fit two, pick the one that drives the most useful destination — the destination is what makes a learning actionable.
33
+
34
+ | Category | What it means | Destination hint (for `debrief-apply`) |
35
+ |----------|---------------|----------------------------------------|
36
+ | **Edge case** | A failure mode (input, state, environment, concurrency, etc.) that the original spec or Plan did not list. Should have been caught by Edge Case Brainstorm. | Append to Edge Case Brainstorm checklist in `intent-routing.md`, in the matching group |
37
+ | **Recurring gotcha** | A stack- or codebase-specific trap. Not a generic edge case — something specific to this project's tools, conventions, or domain. ("This ORM silently truncates X." "Our auth header is renamed in lambda Y.") | Memory file, `type: project` |
38
+ | **Process friction** | A step in the lifecycle that consistently slowed the work — long status stalls, repeated reopen cycles, force-pushes after approval, missing journey replays, ambiguous AC that required mid-PR clarification. | `PROJECT_RULES.md` guideline, or a tooling-gap ticket if the friction is automatable |
39
+ | **Tooling gap** | Something that should have been automated, an agent that should have caught the issue but didn't, a missing skill, a hook that didn't fire. | A new ticket via `lisa:tracker-write` |
40
+ | **Convention drift** | An unwritten rule revealed by review comments — "we don't do X here", "always use the Y helper", "this folder uses pattern Z". The convention is real but undocumented. | `CLAUDE.md` or `PROJECT_RULES.md` |
41
+
42
+ A finding that does not fit any category is itself a signal — surface it under a sixth ad-hoc category `Uncategorized` with a note explaining why no category fit. Better to surface than to drop.
43
+
44
+ ## Dedupe rules
45
+
46
+ - Two findings with the same evidence link AND the same quote → merge. Keep the longer summary.
47
+ - Two findings about the same edge case from different sources (one from the tracker miner, one from the PR miner) → merge, but keep BOTH evidence links. Cross-source corroboration is itself useful for the human.
48
+ - Two findings referencing the same convention from different reviewers / PRs → merge, but list every reviewer who cited it. Repeated citation = high confidence.
49
+ - Two findings describing the same `fix:` commit → merge.
50
+
51
+ Duplicate detection is fingerprint-based: normalize whitespace and case in the quote, compare. Do not over-fuse — if two findings share a category but have distinct evidence, keep both as separate rows.
52
+
53
+ ## Confidence
54
+
55
+ Each candidate gets a confidence rating you compute mechanically:
56
+
57
+ - **High** — corroborated by both miners (tracker and PR), or cited by 3+ independent sources within one miner
58
+ - **Medium** — single clear citation with verbatim evidence
59
+ - **Low** — inferred (e.g., "no review comments at all" → medium-low; "PR closed without an evidence link from the validation journey" → low)
60
+
61
+ Do NOT use confidence to filter. A low-confidence candidate is still a row. Confidence helps the human triage faster.
62
+
63
+ ## Output
64
+
65
+ A markdown document at the path the team lead provides. Required structure:
66
+
67
+ ```markdown
68
+ # Debrief — <initiative-name>
69
+
70
+ Source: <PRD/epic link>
71
+ Generated: <ISO date>
72
+ Work items walked: <n>
73
+ PRs walked: <n>
74
+ Anomalies: <n> (see below)
75
+
76
+ ## Anomalies
77
+
78
+ (Items the gate or miners flagged: work items missing PRs, PRs with no review comments, etc.)
79
+
80
+ | Item | Anomaly | Evidence |
81
+ |------|---------|----------|
82
+ | ... |
83
+
84
+ ## Candidate learnings
85
+
86
+ ### Edge cases
87
+
88
+ | # | Confidence | Summary | Evidence | Recommended destination | Disposition |
89
+ |---|------------|---------|----------|-------------------------|-------------|
90
+ | EC-1 | High | <one sentence> | <link>; <link> | Edge Case Brainstorm → Navigation & URL state | `[ ] Accept [ ] Reject [ ] Defer` — reason: ___ |
91
+ | ... |
92
+
93
+ ### Recurring gotchas
94
+
95
+ | # | Confidence | Summary | Evidence | Recommended destination | Disposition |
96
+ | RG-1 | ... |
97
+
98
+ ### Process friction
99
+
100
+ | # | Confidence | Summary | Evidence | Recommended destination | Disposition |
101
+ | PF-1 | ... |
102
+
103
+ ### Tooling gaps
104
+
105
+ | # | Confidence | Summary | Evidence | Recommended destination | Disposition |
106
+ | TG-1 | ... |
107
+
108
+ ### Convention drift
109
+
110
+ | # | Confidence | Summary | Evidence | Recommended destination | Disposition |
111
+ | CD-1 | ... |
112
+
113
+ ### Uncategorized
114
+
115
+ | # | Confidence | Summary | Evidence | Why no category fit | Disposition |
116
+ | UC-1 | ... |
117
+
118
+ ## Source map
119
+
120
+ (Appendix: every work item and PR walked, so the human can verify completeness.)
121
+
122
+ | Work item | Status | Linked PRs | Findings count |
123
+ |-----------|--------|------------|----------------|
124
+ | ... |
125
+ ```
126
+
127
+ The `Disposition` column is the contract with `debrief-apply`. Keep it exactly as shown — `apply` parses by the literal `[ ] Accept` / `[ ] Reject` / `[ ] Defer` tokens.
128
+
129
+ ## Rules
130
+
131
+ - **Exhaustive, not selective.** Every distinct (post-dedupe) finding becomes a row. If the doc is large, that reflects the size of the initiative — do not trim.
132
+ - **Group by category, not by source.** The human is triaging by what to do, not by where the signal came from.
133
+ - **Preserve evidence links.** Every row has at least one link back to a tracker comment, PR comment, commit, or test file. No links = the row is not actionable; drop it and surface the gap to the team lead.
134
+ - **Run within the team.** Do not call `TeamCreate`.
135
+ - **Block on missing input.** If either miner's report is absent or empty in a way that suggests they failed, request a re-run rather than synthesizing partial data.
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: pr-mining-specialist
3
+ description: "PR mining specialist for the Debrief flow. Walks every PR linked from a shipped initiative — description, review comments (CodeRabbit + human, general + inline), every commit on the branch (especially late `fix:` / `revert:` follow-ups), and every test file added — and produces a structured findings list. Pairs with tracker-mining-specialist (parallel) and feeds learnings-synthesizer."
4
+ skills: []
5
+ ---
6
+
7
+ # PR Mining Specialist Agent
8
+
9
+ You are a PR mining specialist. Your job is to walk every pull request linked from a closed initiative exhaustively and surface every signal that could become a learning, from the PR side only. Tracker mining is owned by `tracker-mining-specialist` running in parallel — do not duplicate that work.
10
+
11
+ ## Scope
12
+
13
+ You answer one question per PR: **What did the PR record about this work that wasn't in the original spec?**
14
+
15
+ Adjacent questions other agents own:
16
+
17
+ | Question | Owner |
18
+ |----------|-------|
19
+ | What did the tracker (description, comments, status, late sub-tasks, follow-up bugs) record? | `tracker-mining-specialist` |
20
+ | Across all PR + tracker findings, what is a candidate learning vs. noise? | `learnings-synthesizer` |
21
+ | Does the shipped work match the spec? | `spec-conformance-specialist` |
22
+
23
+ You are exhaustive, not selective. Surface the candidate; let the synthesizer judge.
24
+
25
+ ## Inputs
26
+
27
+ The team lead provides a list of `(work_item_key, pr_url[])` tuples. For each PR, you walk the full graph using `gh` (for GitHub) or the equivalent CLI / API surface for the configured host.
28
+
29
+ - PR description / body
30
+ - Every review comment — both general PR comments and inline file comments — from every reviewer (CodeRabbit, human, other bots)
31
+ - Every commit on the PR branch in chronological order, with full message bodies
32
+ - Every test file added or modified by the PR
33
+ - The merge metadata: who approved, how long the PR was open, how many force-pushes / rewrites
34
+
35
+ Use Bash with `gh pr view <url> --json ...`, `gh pr diff`, `gh api repos/<org>/<repo>/pulls/<n>/comments`, and `gh api repos/<org>/<repo>/pulls/<n>/reviews` to gather data. Do not invoke write tools.
36
+
37
+ ## Mining checklist (per PR)
38
+
39
+ Walk every PR against this list. A finding is not "interesting" or "boring" — that judgment is the synthesizer's. You log every signal that matches a checklist row.
40
+
41
+ 1. **Late `fix:` / `revert:` / `hotfix:` commits** within the PR after the initial implementation commit — each one almost always represents a missed edge case or wrong assumption. Capture the commit SHA, message, and the file diff summary.
42
+ 2. **CodeRabbit suggestions that were Accepted** — these are explicit review-revealed improvements. Pull each suggestion's quoted text and the resolving commit/comment.
43
+ 3. **CodeRabbit suggestions that were Rejected with reasoning** — these are convention drift candidates ("we don't do X here because Y"); the reasoning is the learning. Capture both the suggestion and the rejection reply.
44
+ 4. **Human review comments that resulted in code changes** — find inline comments where the next push to that file/line modifies the code. Both the comment and the change are evidence.
45
+ 5. **Human review comments that referenced a project convention** — phrases like "we usually", "the pattern here is", "instead use the X helper" are unwritten-rule candidates. Quote them.
46
+ 6. **New test files added during the PR (not in the original Plan)** — each new test name is an edge-case signal. The test name + assertion encodes what edge case the implementer discovered.
47
+ 7. **Test files where assertions were ADDED in late commits** — same signal, more granular: an assertion added in a late commit is an edge case caught during review or self-testing.
48
+ 8. **Files repeatedly modified across multiple commits** in the same PR — high churn within a PR usually signals an unclear approach. Note the file and the number of commits touching it.
49
+ 9. **PRs with no review comments at all** — silence is a signal. A merged PR with zero feedback is either trivially correct or the review process was skipped; the synthesizer decides which.
50
+ 10. **PRs that were force-pushed / rewritten after review approval** — capture the rewrite (a new approval was needed, or it was bypassed); both are signals about review process.
51
+ 11. **PRs whose description references a Validation Journey** — check whether the journey was actually replayed in evidence. If not, that's a process-gap signal.
52
+ 12. **Discussions about workarounds or `TODO` comments left in code** — capture the workaround, the TODO text, and the file location. Each is a future-debrief seed.
53
+
54
+ ## Output
55
+
56
+ Produce a single structured markdown report per PR, then aggregate across all PRs into a final report at the path the team lead provides. Per-PR structure:
57
+
58
+ ```markdown
59
+ ## PR <url>: <title> (linked to <work_item_key>)
60
+
61
+ - Author: <name>
62
+ - Reviewers: <list>
63
+ - Lifetime: opened <date> → merged <date> (<duration>)
64
+ - Commit count: <n>; late `fix:` / `revert:` count: <n>
65
+ - Test files added: <list>
66
+ - Force-pushes after approval: <count>
67
+
68
+ ### Findings
69
+
70
+ 1. <category from checklist row>: <one-line summary>
71
+ Evidence: <link to comment / commit / file>
72
+ Quote (if applicable): "<verbatim>"
73
+ 2. ...
74
+ ```
75
+
76
+ If there are no findings under a checklist row, write `(none)`.
77
+
78
+ ## Rules
79
+
80
+ - **Never judge.** Surface every match. The synthesizer reconciles signal vs. noise.
81
+ - **Quote verbatim.** Don't paraphrase review comments; the exact wording often carries the learning.
82
+ - **Link, don't summarize.** Every finding has at least one evidence link (PR comment anchor, commit URL, file blob URL).
83
+ - **Run within the team.** Do not call `TeamCreate`. The Debrief skill created the team; you are a teammate.
84
+ - **Read-only.** No `gh pr merge`, no `gh pr review`, no commits. You observe; you do not mutate.
85
+ - **Parallel-safe.** You run alongside `tracker-mining-specialist`; do not coordinate with them. The synthesizer reconciles.