Skip to content

chore(repo): add FxA review skills and update PR template#20217

Open
vbudhram wants to merge 1 commit intomainfrom
add-fxa-skills
Open

chore(repo): add FxA review skills and update PR template#20217
vbudhram wants to merge 1 commit intomainfrom
add-fxa-skills

Conversation

@vbudhram
Copy link
Contributor

@vbudhram vbudhram commented Mar 18, 2026

Because

  • Want to add some claude skills for code simplicification and reviews

This pull request

  • Adds new skills for these
  • The skills are based on Anthropics code simplification skill but trained on our repo

Issue that this pull request solves

Closes: https://mozilla-hub.atlassian.net/browse/FXA-13306

Checklist

  • My commit is GPG signed.
  • If applicable, I have modified or added tests which pass locally.
  • I have added necessary documentation (if appropriate).
  • I have verified that my changes render correctly in RTL (if appropriate).

@vbudhram vbudhram marked this pull request as ready for review March 18, 2026 20:19
@vbudhram vbudhram requested a review from a team as a code owner March 18, 2026 20:19
Copilot AI review requested due to automatic review settings March 18, 2026 20:19
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new .claude skills intended to help with FXA-specific simplification and PR/commit review, and updates the GitHub PR template to prompt for self-review and review guidance.

Changes:

  • Update .github/PULL_REQUEST_TEMPLATE.md to add an “Author has self-reviewed” checkbox and a “How to review” section.
  • Add new Claude skills: fxa-simplify, fxa-review, and fxa-review-quick.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
.github/PULL_REQUEST_TEMPLATE.md Adds self-review checkbox and a placeholder “How to review” section.
.claude/skills/fxa-simplify/SKILL.md New skill describing FXA-specific code simplification conventions and process.
.claude/skills/fxa-review/SKILL.md New “thorough review” skill with parallel specialist-agent workflow.
.claude/skills/fxa-review-quick/SKILL.md New “quick review” skill with a single-pass checklist workflow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- [ ] If applicable, I have modified or added tests which pass locally.
- [ ] I have added necessary documentation (if appropriate).
- [ ] I have verified that my changes render correctly in RTL (if appropriate).
- [ ] Author has self-reviewed this PR.
Comment on lines +23 to +25
## How to review

-
@@ -0,0 +1,119 @@
---
name: fxa-simplify
description: Simplifies and refines code in the FXA monorepo using project-specific conventions. Use when asked to simplify, clean up, or refine recently written code. Focuses on recently modified code unless instructed otherwise.
description: Thorough FXA-specific commit review using parallel specialist agents. Covers security, TypeScript, logic/bugs, test quality, and architecture. Agents explore call sites, git history, and monorepo conventions.
allowed-tools: Bash, Read, Grep, Glob, Agent
argument-hint: [commit-ref]
user-invocable: true
Comment on lines +1 to +7
---
name: fxa-review-quick
description: Fast single-pass FXA-specific commit review covering security, conventions, logic/bugs, tests, and migrations. No subagents — runs directly in the main context.
allowed-tools: Bash, Read, Grep, Glob
argument-hint: [commit-ref]
user-invocable: true
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good feedback

Comment on lines +1 to +7
---
name: fxa-review-quick
description: Fast single-pass FXA-specific commit review covering security, conventions, logic/bugs, tests, and migrations. No subagents — runs directly in the main context.
allowed-tools: Bash, Read, Grep, Glob
argument-hint: [commit-ref]
user-invocable: true
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good feedback


Evaluate the diff through these lenses, in order of priority:

**1. Security**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have a security skill. Maybe update that one instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out that skills can't invoke other skills, but they can reference similar ones. There is a lot of overlap between the two but I'll make this reference the other one.


## Step 2: Read Changed Files

Use Read and Grep to examine the changed files and their surrounding context. Look at imports, callers, and related types to understand the full picture before judging.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this. I think all skills with this should be prefixed with review- since this clearly about code review.


Use Read and Grep to examine the changed files and their surrounding context. Look at imports, callers, and related types to understand the full picture before judging.

## Step 3: Review
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be nice to have each sub section be its own skill. That way people can use them in more general ways too. For example apply them to a file that hasn't been changed yet. I'm not entirely sure about this, but I also think this will be faster if context: fork is used since each can be done with an agent thus parallelizing the process.

- Over-mocked tests that only test mock wiring

**5. Database Migrations**
- Edits to existing published migration files — CRITICAL, never allowed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also should be making sure the test db patches are aligned with the current test db state (ie /fxa-shared/test/db/models/**/*.sql). Personally I'd like to just do away with those at some point, but not sure exactly when that will happen.


## Verdict

Recommendation: APPROVE, REQUEST CHANGES, or NEEDS DISCUSSION.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this part.


## Guidelines

- Be pragmatic, not pedantic. Flag real problems, not style preferences.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add something about watch out for ai slop?


---

**Agent 1 — FXA Security Review**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essentially same comments as above. I think these would be better as sub skills, and there is probably overlap with existing skills.


Tell this agent it is a senior TypeScript engineer familiar with FXA's mixed JS/TS codebase. It should:

- Flag `any` usage — suggest `unknown`, interfaces, or generics instead. Note: `any` is permitted in auth-server during migration but should not be introduced in new code unnecessarily
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think there's cases where for tests it's okay. @nshirley thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there are arguments for and against allowing any in tests. Using any can provide some flexibility and freedom in writing tests, and restricting it can sometimes make tests more difficult to write and read.

A few thoughts on both sides:

Allowing it can:

  • make it easier to test runtime inputs and validation (e.g. deliberately passing malformed or malicious data)
  • be useful when mocking third-party libraries or complex objects where strict typing adds noise but not value

Disallowing it can:

  • prevent hiding incorrect assumptions in mocks
  • avoid tests passing shapes that would never exist in real code
  • preserve the contracts afforded by TypeScript, making refactors safer

Also, using satisfies more for mocks and fixtures could be really valuable here!

A good principle is: use any in tests only when the looseness is part of the test case, not just a shortcut.

Sorry, long way of saying — I mostly agree with this rule for the agent: flag it and suggest better types or more explicit casting where possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment I have here, is I have noticed that Claude loves to set the Integration type to any, when we have an established pattern to create an integration subset, e.g. CompleteResetPasswordIntegration. Maybe we need a note for that at least to use type sub sets?

- Check mock type safety — mocks should be typed against real interfaces where possible
- Flag missing return types on exported functions
- Look for simplification: optional chaining, nullish coalescing, early returns, destructuring
- Check import style: `@fxa/<domain>/<package>` for cross-package, relative within package
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also comment that we shouldn't be using require in TS files.

- Check mock quality: tests that only assert output matches what the mock returns (tautological)
- Verify interaction assertions: `.toHaveBeenCalledWith()` on mocked dependencies, not just checking return values
- Flag `jest.clearAllMocks()` in `beforeEach` — unnecessary, `clearMocks: true` is global
- Check for shared mutable state between tests, missing `await`, `setTimeout` in tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also have something about using jest.useFakeTimers and jest.setSystemTime instead of using setTimeout directly or mocking Date.now...


---

**Agent 5 — FXA Architecture Review**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we incorporate the check-smells skill here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have it reference the skill here

- Check migration direction compliance:
- Mocha → Jest (no new Mocha tests)
- `proxyquire` → `jest.mock()`
- Callbacks → async/await
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't consider this architecture.

- Sequential patch numbering has no gaps
- Index changes separate from schema changes
- Check cross-package boundary violations: relative imports across package boundaries instead of `@fxa/*` aliases
- Flag colliding exports: new exports that duplicate existing ones elsewhere in the monorepo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also check for circular/bi-directional dependencies. Very important with library code for architectural cleanliness.


## 1. Preserve Functionality

Never change what the code does — only how it does it. All original features, outputs, and behaviors must remain intact.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like if we are having AI do this, especially to existing code (there's no diff check on this skill), we should make sure there's test coverage to ensure that it really isn't the input output behavior of the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't noticed an issue of it introducing different behaviors but I've also run the /fxa-review skill and tests before pushing it out.

### Imports
- Use `@fxa/<domain>/<package>` path aliases for cross-package imports (e.g., `@fxa/accounts/errors`, `@fxa/shared/cloud-tasks`)
- Use relative imports within a package — auth-server ESLint enforces this (`@typescript-eslint/no-restricted-imports` blocks `fxa-auth-server/**`)
- `require()` is acceptable in auth-server (mixed JS/TS codebase, `@typescript-eslint/no-var-requires: off`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it acceptable in TS files though?

### Naming & Structure
- Consistent naming: `camelCase` for variables/functions, `PascalCase` for classes/types/React components
- Auth-server factory pattern: modules often export `(log, config, db) => { ... }` or class constructors
- TypeDI `Container.set()`/`Container.get()` for dependency injection in auth-server
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand how this would be applied? Like what would it changed based on the guidelines here and the line above?

- TypeDI `Container.set()`/`Container.get()` for dependency injection in auth-server

### Config
- Config is Convict-based (`config/index.ts`, ~2900 lines) — access via `config.get('key')` or `config.getProperties()`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is ~2900 lines? Also we have a ticket to remove convict...


## 6. FXA-Specific Guardrails

- **Never edit published DB migration files** — migrations are append-only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this kind of stuff belongs in our main claude md.

- `console.log` instead of the `log` object (mozlog format)
- Cross-package imports using relative paths instead of `@fxa/<domain>/<package>` aliases
- Auth-server code importing from `fxa-auth-server/**` (ESLint blocks this)
- New code added to legacy packages (`fxa-content-server`, `fxa-payments-server`) — should be in `fxa-settings` or SubPlat 3.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also anything in fxa-shared should be in libs/.

- Hardcoded values that should come from Convict config
- `require()` vs `import` — CJS in auth-server is fine, ESM in libs/settings
- Missing MPL-2.0 license header on new files

Copy link
Contributor

@LZoog LZoog Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add somewhere that:

  1. Using non-semantic elements to replicate native HTML controls instead of using the appropriate built-in elements (e.g., <ul>/<li>, <button>, <select>)
  2. React code that directly manipulates the DOM. There are edge cases where this is OK but it should be questioned (something about following best React practices)
  3. UI modifications that are not also reflected in Storybook updates

As Dan has sort of said, maybe some of these things should be pulled out and put into CLAUDE.md so they're done right the first time too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add this here, I think pulling into the CLAUDE.md is ok but I think having another discussion on improvements to the file/structure would be helpful. For example, I think we should have a smaller CLAUDE.md file and have references to domain specific things like React, Playwright etc.

- Hapi route handlers that catch and re-throw instead of letting the error pipeline handle it

**4. Tests**
- New source files without co-located `*.spec.ts`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably say code in fxa-settings follows a *.test.* convention


**4. Tests**
- New source files without co-located `*.spec.ts`
- Hardcoded translation strings in assertions — should assert localization occurred, not exact values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so specific, I think we have only a couple of tests that do this in the entire repo so not sure if it's worth having hmm

- model: opus
- description: FXA security review

Tell this agent it is a senior security engineer with deep knowledge of FXA's authentication and payments platform. It should:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not saying to remove, but I wonder how useful this actually is to tell the agent that it possesses deep knowledge of the system. I get how telling it that it's a senior security engineer would purposefully bias it how we want it though.

- Index changes separate from schema changes
- Check cross-package boundary violations: relative imports across package boundaries instead of `@fxa/*` aliases
- Flag colliding exports: new exports that duplicate existing ones elsewhere in the monorepo

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also add something about following best React and Tailwind practices?

- Flag `jest.clearAllMocks()` in `beforeEach` — unnecessary, `clearMocks: true` is global
- Check for shared mutable state between tests, missing `await`, `setTimeout` in tests
- Flag over-mocking: mocking internal functions in the same package instead of at system boundaries

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One other thing that would be nice is to make sure we don't introduce new open handle warnings. I know the migration has been setup to use --force-exit, but it'd be nice to fix whatever is causing those errors and not introduce new ones

Oh, and having it keep an eye out for act() warnings in React tests.

@vbudhram
Copy link
Contributor Author

Thanks for the review! I think I've covered all the requested changes. My goal here is that it is used as a first past before all human reviews are requested. It definately won't be perfect, but hopefully provides more value than not.

@vbudhram vbudhram self-assigned this Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants