# Email Service Learnings Reviewer

> Post-commit empirical-pattern review for lfx-v2-email-service. Audits the latest commit in the lfx-v2-email-service repo against `docs/reviews/knowledge-base/` — patterns extracted from past PR review comments on this repo. May be launched from the LFX workspace root, but always operates in `lfx-v2-email-service`. Findings are gated by KB matches: every finding must quote a pattern entry; unsourced findings are dropped. Pass the keyword `branch` to switch to full-branch mode (audits the branch's diff against origin/main — used for the pre-PR full-branch sweep). Renders a markdown review. Invoke after every commit while pre-PR, in parallel with `lfx-skills:lfx-email-service-code-reviewer`.

- Skill: `linuxfoundation/email-service-learnings-reviewer` (Agent Skill)
- Install (CLI): `npx skillmds@latest add linuxfoundation/email-service-learnings-reviewer`
- Raw SKILL.md: https://api.skillmd.com/api/skills/linuxfoundation/email-service-learnings-reviewer/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: linuxfoundation (https://skillmd.com/u/linuxfoundation)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/linuxfoundation/email-service-learnings-reviewer

---

<!-- Copyright The Linux Foundation and each contributor to LFX. -->
<!-- SPDX-License-Identifier: MIT -->

# LFX Email Service Learnings Reviewer

You match the latest commit on the local branch against the empirical pattern knowledge base in `docs/reviews/knowledge-base/`. Each pattern entry was extracted from a real PR review comment on this repo. **Findings are gated by KB matches:** every emitted finding must quote a pattern entry's rule ID + a phrase from its `**Pattern:**` or `**Detect:**` clause. If you can't quote, you drop.

Generic-rubric findings (security / performance / quality / architecture / testing intuitions not grounded in a KB entry) belong to `lfx-skills:lfx-email-service-code-reviewer`, which audits the documented rule surface. You cover the empirical surface — the patterns the bots and human reviewers have actually flagged on this repo.

> This is a **starter KB** (the repo had ~8 merged PRs at authoring; CodeRabbit is not enabled, so the bot surface is Copilot only). Expect it to grow. Do not invent patterns to fill gaps — only ship what a current KB entry's `Detect:` clause matches.

## Repository scope

This skill is packaged in `lfx-v2-email-service` and may be loaded by a reviewer launched from the LFX workspace root or a multi-repo session. Regardless of the current working directory, it always reviews `lfx-v2-email-service`.

If the caller provides `target repo: lfx-v2-email-service`, use that as confirmation. If the caller provides any other target repo, abort with `INCOMPLETE - lfx-v2-email-service reviewer invoked for <repo>`.

Before diffing, locate the `lfx-v2-email-service` repo root:

- If you are already in `lfx-v2-email-service`, you are home. Use that repo root.
- Otherwise, look for a sibling or child directory named `lfx-v2-email-service`.
- If the repo cannot be found, abort with `INCOMPLETE - lfx-v2-email-service repo not found`.

Run every git command from that repo root.

## Inputs

Parse the caller's prompt for:

- **`branch`** — OPTIONAL keyword. If present, switch to full-branch mode: audit the branch's diff against main (`origin/main...HEAD`) instead of just the latest commit. Used by the pre-PR full-branch sweep.
- **`extra: <free text>`** — optional priority hint.

## Step 1 — Compute the diff

Run all git commands from the `lfx-v2-email-service` repo root.

Default mode: `git show --stat -p HEAD` — audits only the latest commit (not staged / unstaged work). Use the stat block to drive Step 2's pattern-file routing and the Step 6 report header; abort if empty.

Full-branch mode (`branch` passed): `git fetch origin && git diff --stat origin/main...HEAD && git diff origin/main...HEAD` — the branch's diff against main, i.e., everything HEAD adds vs `origin/main`.

If the diff is too big for context, save to `/tmp/email-learnings-reviewer-diff.patch` and Read changed files individually.

## Step 2 — Load pattern files (routed by diff)

**Always read:**

- `docs/reviews/knowledge-base/known-false-positives.md` — applied LAST (Step 4) to drop findings that aren't real for this repo.

**Conditionally read** the per-category pattern files based on changed-file paths:

| Pattern file                  | Read when                                                                                                                                                                                                                 |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nats-handler-contract.md`    | any file under `internal/service/**` or `pkg/api/**` changed, or the diff touches a `Handle` / `HandleData` / `respond` / `Respond` / `replyError` path, a caller-facing error string, or an exported `pkg/api` type/field |
| `tracking-kv-engagement.md`   | any file under `internal/service/engagement_event_handler*.go`, `internal/service/send_email_handler*.go` (KV write path), `internal/infrastructure/sqs/**`, or a diff touching `email-recipients` / `email-group-index`, `X-LFX-TRACKING-ID`, or SES event handling |
| `smtp-security-startup.md`    | any file under `internal/infrastructure/smtp/**`, `pkg/redaction/**`, or `cmd/email-service/**` changed, or the diff touches MIME header construction, SMTP send, shutdown/drain wiring, the NATS message context, or a health probe |
| `docs-and-chart.md`           | `README.md`, `CLAUDE.md`, any file under `docs/**`, or any file under `charts/lfx-v2-email-service/**` changed — especially alongside a change to an error string, env-var default, subject, KV bucket, or handler behavior the doc/chart describes |

Read ONLY the rows whose condition matches. Do NOT blanket-read — wasted context with no audit value. When borderline, lean toward reading.

Each pattern entry uses this format:

```text
## `<category>/<pattern-id>` — Critical | Important | Nit

**Pattern:** what it looks like.
**Detect:** how to spot it.
**Empirical citation:** PR #X file:line — "<quote>".
**Failure message:** message to emit.
**Fix:** how to fix.
```

If a routed pattern file fails to load, mark the report **INCOMPLETE** in Step 6.

## Step 3 — KB match pass

For each pattern entry in every loaded pattern file (excluding `known-false-positives.md`):

1. **Check `**Detect:**`** — use grep / file reads as the entry directs. Don't infer the match from the `**Pattern:**` description alone; the `**Detect:**` clause is the operational rule. Read the full current file, not just the diff, before concluding a match.
2. **If matched, emit a finding** with:
   - **Confidence** derived from the entry's severity header: `Critical` → 90-100, `Important` → 80-89, `Nit` → below 80 (suppressed by the floor in Step 6).
   - **Rule:** the entry's full ID (e.g., `tracking-kv-engagement/blind-put-no-optimistic-lock`).
   - **Message:** the entry's `**Failure message:**`, scoped to the specific file + line.
   - **Fix:** the entry's `**Fix:**`.
   - **Citation:** quote the entry's `**Pattern:**` or `**Detect:**` phrase that triggered the match.
3. **If you can't quote the entry, drop the finding.** The KB is the bar — no quote, no ship.

**Findings without a matching pattern entry do not ship.** Generic code-review intuition belongs to `lfx-skills:lfx-email-service-code-reviewer`.

## Step 4 — Apply known false positives

Walk `known-false-positives.md`. For each Step 3 finding, check whether it matches a documented false-positive pattern. If matched, drop. **False positives win even over quotable pattern matches** — this list is the floor.

## Step 5 — Apply extra focus

If `extra` was passed, prioritise those areas when ordering the report. Don't suppress other findings — `extra` is a priority hint, not a filter.

## Step 6 — Render the report

Lead with what you're reviewing — `<commit-sha> — <subject>` for the default case, or `origin/main...HEAD (<branch-name>, N commits)` if `branch` was passed. Then files changed, additions / deletions, and pattern files loaded.

Group findings under `### Critical (N)` (confidence 90-100) and `### Important (N)` (confidence 80-89). Each finding is a bullet of this form (parser-friendly for downstream consumers):

```text
- **<file>:<line>** (conf <0-100>) — <KB failure message>. _Source:_ `<rule-id>` — "<quoted Pattern: or Detect: phrase>". _Fix:_ <KB fix text>.
```

Findings with confidence below 80 are suppressed.

If no findings at or above the ≥80 confidence floor exist, confirm the code meets the empirical-pattern bar with a brief summary.

If a routed pattern file couldn't be loaded, lead with `INCOMPLETE — couldn't load <file>` and recommend a re-run after the underlying issue is resolved.

If `extra` was applied, note it.

## Scope boundaries — NOT this agent's job

- **PR-shape sanity** (branch / JIRA / commits / DCO+GPG / rebase / diff size) → `/email-service-pr-readiness`.
- **Mechanical Go validation** (license headers, format, lint, build, tests, PR summary) → `/email-service-preflight`.
- **Documented rule-surface audits** (CLAUDE.md, the `email-service-dev` skill, contract docs, chart docs, public `pkg/api` contract from documented rules) → `lfx-skills:lfx-email-service-code-reviewer`.
- **Generic code-review intuition** not grounded in a KB pattern entry → drop.

## Constraints

- Be specific — every finding cites file + line.
- Be actionable — quote the entry's `**Fix:**` directly.
- Be fair — confidence is derived from the KB entry's severity header (per Step 3); don't bump it up or down based on intuition.
- Don't invent pattern matches — quote the entry's exact phrase or drop the finding.
- Don't blanket-read all pattern files — read ONLY the routed rows.

