Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,35 @@ Four layers; dependencies point strictly downward:
4. **Bindings** β€” `bitwarden-uniffi` (Swift/Kotlin) and `bitwarden-wasm-internal`
(TypeScript/JavaScript). Thin bindings only β€” no business logic.

## Code Review

For any code-review task (review PR / review changes / review this code / look at a diff), use the
repo-local **`reviewing-changes`** skill (`.claude/skills/reviewing-changes/SKILL.md`). It detects the
change type and loads the matching checklist (`checklists/*.md`) and reference sheets
(`reference/*.md`) for that kind of change. Treat this skill as the entry point for review work rather
than reviewing ad hoc.

The enforceable review rules live in the path-scoped `.claude/rules/` files (auto-loaded when you
touch matching files): `code-review.md` (cross-cutting power-user rules, with severities), alongside
the topic files `crypto.md`, `rust-conventions.md`, `bindings.md`, and `generated-api-crates.md`.

**Multi-agent review β€” forward the guidelines.** When a review runs in multi-agent mode, the
dispatching agent MUST forward the full contents of this `.claude/CLAUDE.md` and the loaded
`.claude/rules/` files (plus any near-file `README` / crate `CLAUDE.md`) to every review subagent.
Under the `evaluation-standards` gate a style/quality finding is only postable if its rule is written
in a file the subagent has loaded β€” a subagent that never received these rules cannot legitimately
raise them. Do not assume a subagent inherited this context; pass it explicitly.

## Deep-Dive Index

_Forthcoming β€” populated in Phase C._ This section will map each change-area to the `/docs/<page>.md`
deep-dive page the reviewer should read before reviewing that kind of change. The paths below are
placeholders and are NOT live yet:

- crypto / FFI change β†’ `docs/patterns/crypto-safe-module.md` (Phase C)
- state / repository change β†’ `docs/patterns/state-management.md` (Phase C)
- WASM / UniFFI binding change β†’ `docs/patterns/bindings.md` (Phase C)

## References

- [SDK architecture](https://contributing.bitwarden.com/architecture/sdk/) Β·
Expand Down
3 changes: 3 additions & 0 deletions .claude/prompts/review-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Use the `reviewing-changes` skill to review this pull request.

The PR branch is already checked out in the current working directory.
33 changes: 33 additions & 0 deletions .claude/rules/code-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
paths:
- "crates/**/*.rs"
- "bitwarden_license/**/*.rs"
Comment on lines +2 to +4

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ IMPORTANT: Path scope excludes Cargo.toml, so rule 10 never loads for the PRs it targets.

Details and fix

The scope is *.rs only, and .claude/CLAUDE.md states rules "load automatically when you touch matching files". Rule 10 ("Use Cargo weak dependencies (?) for optional / licensed crates") is a manifest rule β€” a dependency or feature-flag PR that touches only Cargo.toml / Cargo.lock will never load this file, which is exactly the case where the OSS/commercial boundary risk shows up.

paths:
  - "crates/**/*.rs"
  - "bitwarden_license/**/*.rs"
  - "**/Cargo.toml"

Also worth noting: .claude/CLAUDE.md describes this file as "cross-cutting power-user rules", which reads broader than the *.rs scope actually delivers.

---

# Code review rules

Enforceable review rules distilled from Bitwarden SDK power-user PR feedback, each tagged with its
severity. Topic-specific rules also live in the sibling rules files (`crypto.md`,
`rust-conventions.md`, `bindings.md`); these complement, not replace, them.

1. `[CRITICAL]` Never use `Vec<u8>` / `String` to carry keys or crypto material; use typed newtypes
(e.g. `SymmetricKey`) so key material cannot be confused with ordinary bytes. (See `crypto.md`
for the key-reference / hazmat rules this builds on.)
2. `[IMPORTANT]` New functionality lives on a `Client` struct via extension traits
(`client.vault() -> VaultClient`), not as standalone statics or free functions.
3. `[CRITICAL]` New crypto operations and FFI exports require pinned test vectors β€” JSON vectors
pinned in code; see the `create-testvectors` skill.
4. `[CRITICAL]` Never re-expose low-level / hazmat crypto through a feature crate's public API (the
crypto crates already must not expose it; this rule covers feature crates re-exporting it
downstream β€” see `crypto.md`).
5. `[IMPORTANT]` All public types need doc comments; do NOT suppress `missing_docs` crate-wide to
silence the warning.
6. `[IMPORTANT]` Use restrictive visibility by default (`pub(crate)` / `pub(super)`); a bare `pub`
must be justified by a real cross-crate consumer.
7. `[CRITICAL]` An IV / nonce must never be passed in from outside; generate it internally at the
point of encryption.
8. `[DEBT]` No untracked `TODO`s β€” every `TODO` must link a Jira ticket.
9. `[SUGGESTED]` Public docs describe usage and interface only, not internals; avoid
over-documentation that restates the implementation.
10. `[IMPORTANT]` Use Cargo weak dependencies (`?`) for optional / licensed crates, so an optional
feature does not implicitly pull a crate across the OSS boundary.
81 changes: 81 additions & 0 deletions .claude/skills/reviewing-changes/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
name: reviewing-changes
description: SDK-specific code review checklist and Rust/crate/crypto/FFI/WASM pattern validation for the Bitwarden internal SDK β€” use this for any review task, even if the user doesn't explicitly ask for a "checklist". Detects change type automatically and loads the right review strategy (feature additions, bug fixes, UI refinements, refactoring, dependency updates, infrastructure). Triggered by "review", "code review", "review this code", "review PR", "review changes", "check this code", code review requests on Rust crate/crypto/FFI/UniFFI/WASM files, or any time someone asks to look at a diff, PR, or code changes in bitwarden/sdk-internal.
---

# Reviewing Changes - Android Additions

This skill provides Android-specific workflow additions that complement the base `bitwarden-code-reviewer` agent standards.
Comment on lines +6 to +8

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ IMPORTANT: Skill body directs Android review, but the description makes it auto-activate on every SDK review the moment this merges.

Details and fix

The frontmatter description advertises "Rust/crate/crypto/FFI/WASM pattern validation" and triggers on any review task, while the body it loads says this is an Android skill and closes with "Android patterns: Validate MVVM, Hilt DI, Compose conventions, Kotlin idioms" (line 81). Step 2 keys change-type detection off *Screen.kt, ViewModel, libs.versions.toml, and build.gradle.kts β€” none of which exist here.

The commit message explains the Android flavor is intentional for Phase A, but that context is not in any file the reviewer loads, and .claude/CLAUDE.md now points every review task at this skill. Between this merge and Phase B, CI reviews of Rust PRs are steered by Kotlin/Compose guidance.

A cheap interim guard, right under the heading:

> **Phase A note:** the checklists and reference sheets below are ported verbatim from the Android
> repo and are being Rust-ified in Phase B. Treat the Android technology names (Compose, Hilt,
> MVVM, `*Screen.kt`, Gradle) as placeholders β€” map each to its SDK equivalent (WASM/UniFFI
> bindings, `Client` extension traits, crate layering, `Cargo.toml`) and do not raise findings that
> reference Android/Kotlin APIs.

Alternatively, narrow the description so the skill does not auto-activate until Phase B lands.


## Instructions

**IMPORTANT**: Work systematically through each step before providing feedback. Each checklist file includes structured thinking guidance for its review passes.

### Step 1: Retrieve Additional Details

Retrieve any additional information linked to the pull request using available tools (JIRA MCP, GitHub API).

If pull request title and message do not provide enough context, request additional details from the reviewer:
- Link a JIRA ticket
- Associate a GitHub issue
- Link to another pull request
- Add more detail to the PR title or body

**Android metadata checks** β€” flag as ❓ if any of these are missing:
- PR includes `*Screen.kt` or Composable changes but has no screenshots
- PR adds new `ViewModel` or `Repository` but has no test plan or test file changes

### Step 2: Detect Change Type with Android Refinements

Use the base change type detection from the agent, with Android-specific refinements:

**Android-specific patterns:**
- **Feature Addition**: New `ViewModel`, new `Repository`, new `@Composable` functions, new `*Screen.kt` files
- **UI Refinement**: Changes only in `*Screen.kt`, `*Composable.kt`, `ui/` package files
- **Infrastructure**: Changes to `.github/workflows/`, `gradle/`, `build.gradle.kts`, `libs.versions.toml`
- **Dependency Update**: Changes only to `libs.versions.toml` or `build.gradle.kts` with version bumps

### Step 3: Load Appropriate Checklist

Based on detected type, read the relevant checklist file:

- **Dependency Update** β†’ `checklists/dependency-update.md` (expedited review)
- **Bug Fix** β†’ `checklists/bug-fix.md` (focused review)
- **Feature Addition** β†’ `checklists/feature-addition.md` (comprehensive review)
- **UI Refinement** β†’ `checklists/ui-refinement.md` (design-focused review)
- **Refactoring** β†’ `checklists/refactoring.md` (pattern-focused review)
- **Infrastructure** β†’ `checklists/infrastructure.md` (tooling-focused review)

The checklist provides:
- Multi-pass review strategy
- Type-specific focus areas
- What to check and what to skip
- Structured thinking guidance

### Step 4: Execute Review Following Checklist

Follow the checklist's multi-pass strategy, thinking through each pass systematically.

### Step 5: Consult Android Reference Materials As Needed

Load reference files only when needed for specific questions:

- **Re-reviews** β†’ invoke `reviewing-incremental-changes` agent skill; scope to changed lines only, do not flag new issues in unchanged code

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ DEBT: reviewing-incremental-changes is not available in this repo's review setup, so the re-review instruction silently no-ops.

Details and fix

The skills exposed to the SDK reviewer come from bitwarden-code-review, bitwarden-security-engineer, and claude-config-validator, plus repo-local .claude/skills/ β€” none of them provide reviewing-incremental-changes. Same for bitwarden-code-reviewer (line 8) and the evaluation-standards gate cited in the .claude/CLAUDE.md addition; those names come from the Android setup.

Since the "scope to changed lines only, do not flag new issues in unchanged code" guidance is the valuable part, inlining it here rather than delegating to an unavailable skill would make it actually take effect.

- **Issue prioritization** β†’ `reference/priority-framework.md` (Critical vs Suggested vs Optional)
- **Phrasing feedback** β†’ `reference/review-psychology.md` (questions vs commands, I-statements)
- **Architecture questions** β†’ `reference/architectural-patterns.md` (MVVM, Hilt DI, module org, error handling)
- **Security questions (quick reference)** β†’ `reference/security-patterns.md` (common patterns and anti-patterns)
- **Security questions (comprehensive)** β†’ (SDK `/docs` deep-dive β€” populated in Phase C; not yet present)
- **Testing questions** β†’ `reference/testing-patterns.md` (unit tests, mocking, null safety)
- **UI questions** β†’ `reference/ui-patterns.md` (Compose patterns, theming)
- **Style questions (project-specific)** β†’ `reference/style-patterns.md` (Kotlin rules enforced in review)
- **Style questions (general)** β†’ (SDK `/docs` deep-dive β€” populated in Phase C; not yet present)

## Core Principles

- **Priority order**: Security β†’ Correctness β†’ Breaking Changes β†’ Performance β†’ Maintainability
- **Appropriate depth**: Match review rigor to change complexity and risk
- **Specific references**: Always use `file:line_number` format for precise location
- **Actionable feedback**: Say what to do and why, not just what's wrong
- **Efficient reviews**: Use multi-pass strategy, skip what's not relevant
- **Android patterns**: Validate MVVM, Hilt DI, Compose conventions, Kotlin idioms
137 changes: 137 additions & 0 deletions .claude/skills/reviewing-changes/checklists/bug-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Bug Fix Review Checklist

## Multi-Pass Strategy

### First Pass: Understand the Bug

**1. Understand root cause:**
- What was the broken behavior?
- What caused it?
- How does this fix address the root cause?

**2. Assess scope:**
- How many files changed?
- Is this a targeted fix or broader refactoring?
- Does this affect multiple features?

**3. Check for side effects:**
- Could this break other features?
- Are there edge cases not considered?

### Second Pass: Verify the Fix

**4. Code changes:**
- Does the fix make sense?
- Is it the simplest solution?
- Any unnecessary changes included?

**5. Testing:**
- Is there a regression test?
- Does test verify the bug is fixed?
- Are edge cases covered?

**6. Related code:**
- Same pattern in other places that might have same bug?
- Should other similar code be fixed too?

## What to CHECK

βœ… **Root Cause Analysis**
- Does the fix address the root cause or just symptoms?
- Is the explanation in PR/commit clear?

βœ… **Regression Testing**
- Is there a new test that would fail without this fix?
- Does test cover the reported bug scenario?
- Are related edge cases tested?

βœ… **Side Effects**
- Could this break existing functionality?
- Are there similar code paths that need checking?
- Does this change behavior in unexpected ways?

βœ… **Fix Scope**
- Is the fix appropriately scoped (not too broad, not too narrow)?
- Are all instances of the bug fixed?
- Any related bugs discovered during investigation?

## What to SKIP

❌ **Full Architecture Review** - Unless fix reveals architectural problems
❌ **Comprehensive Testing Review** - Focus on regression tests, not entire test suite
❌ **Major Refactoring Suggestions** - Unless directly related to preventing similar bugs

## Red Flags

🚩 **No test for the bug** - How will we prevent regression?
🚩 **Fix doesn't match root cause** - Is this fixing symptoms?
🚩 **Broad changes beyond the bug** - Should this be split into separate PRs?
🚩 **Similar patterns elsewhere** - Should those be fixed too?

## Key Questions to Ask

Use `reference/review-psychology.md` for phrasing:

- "Can we add a test that would fail without this fix?"
- "I see this pattern in [other file] - does it have the same issue?"
- "Is this fixing the root cause or masking the symptom?"
- "Could this change affect [related feature]?"

## Prioritizing Findings

Use `reference/priority-framework.md` to classify findings as Critical/Important/Suggested/Optional.

## Output Format

See `examples/review-outputs.md` for the required output format and inline comment structure.

## Example Review

```markdown
**Overall Assessment:** APPROVE

See inline comments for suggested improvements.
```

**Inline comment examples:**

```
**data/auth/BiometricRepository.kt:120** - SUGGESTED: Extract null handling

<details>
<summary>Details</summary>

Root cause analysis: BiometricPrompt result was nullable but code assumed non-null, causing crash on cancellation (PM-12345).

Consider extracting null handling pattern:

\```kotlin
private fun handleBiometricResult(result: BiometricPrompt.AuthenticationResult?): AuthResult {
return result?.let { AuthResult.Success(it) } ?: AuthResult.Cancelled
}
\```

This pattern could be reused if we add other biometric auth points.
</details>
```

```
**app/auth/BiometricViewModel.kt:89** - SUGGESTED: Add regression test

<details>
<summary>Details</summary>

Add test for cancellation scenario to prevent regression:

\```kotlin
@Test
fun `when biometric cancelled then returns cancelled state`() = runTest {
coEvery { repository.authenticate() } returns Result.failure(CancelledException())
viewModel.onBiometricAuth()
assertEquals(AuthState.Cancelled, viewModel.state.value)
}
\```

This prevents regression of the bug just fixed.
</details>
```
Loading
Loading