| name | lfx-self-serve-learnings-review |
| description | Post-commit empirical-pattern review for lfx-self-serve. Audits the latest commit in the lfx-self-serve 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-self-serve`. 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 main — used for the pre-PR full-branch sweep). Renders a markdown review. Invoke after every commit while pre-PR, in parallel with `lfx-self-serve-code-review`. |
LFX Self-Serve 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-self-serve-code-review, which audits the documented rule surface. You cover the empirical surface — the patterns the bots and human reviewers have actually flagged.
Repository scope
This skill is owned by the lfx-self-serve repo
(.claude/skills/lfx-self-serve-learnings-review/), and the reviewer loading
it may be launched from the LFX workspace root or a multi-repo session.
Regardless of the current working directory, it always reviews
lfx-self-serve.
If the caller provides target repo: lfx-self-serve, use that as confirmation.
If the caller provides any other target repo, abort with
INCOMPLETE - lfx-self-serve reviewer invoked for <repo>.
Before diffing, locate the lfx-self-serve repo root:
- If you are already in
lfx-self-serve, you are home. Use that repo root.
- Otherwise, look for a sibling or child directory named
lfx-self-serve.
- If the repo cannot be found, abort with
INCOMPLETE - lfx-self-serve repo not found.
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-self-serve 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/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 codebase.
docs/reviews/knowledge-base/security.md — secrets / sanitization / auth-state leakage / untrusted cookies / untrusted URLs can hit any change.
Conditionally read the per-category pattern files based on changed-file paths:
| Pattern file | Read when |
|---|
typescript-correctness.md | any .ts file changed |
templates-and-accessibility.md | any .component.html changed |
frontend-state-and-timing.md | any .component.ts / .service.ts under apps/lfx-one/src/app/ |
server-request-handling.md | app.config.ts, app/shared/guards/, app/shared/interceptors/, any *.routes.ts, any new file under apps/lfx-one/src/server/routes/, apps/lfx-one/src/server/server.ts, middleware/auth*, or any file under server/controllers/ or server/services/ |
observability-and-logging.md | apps/lfx-one/otel.mjs, apps/lfx-one/src/server/middleware/rate-limit.ts, new route registrations in server.ts, or any file using logger.info / logger.warning / logger.debug |
data-and-snowflake.md | apps/lfx-one/src/server/services/snowflake.service.ts or any file with direct Snowflake SQL |
code-truthiness.md | any JSDoc / inline comments, anything under docs/**, or any new feature module / service / component without a matching *.spec.ts |
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:
## `<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):
- 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.
- 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.,
security/secrets-in-diff).
- 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.
- 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-self-serve-code-review.
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):
- **<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) →
/lfx-self-serve-pr-readiness.
- Documented rule-surface audits (Angular structure, repo rule files, architecture checklists, upstream API contracts, protected files) →
lfx-self-serve-code-review.
- 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.