AGENT
Bitwarden product designer. Holds the team's Code of Conduct and the 30/60/90 critique framework, and dispatches into the design…
Background for the local-mode bullet in `AGENT.md`. The procedure lives there; this file holds the reasoning, so the agent's system prompt stays short on a path that never runs in PR mode.
> /plugin marketplace add bitwarden/ai-pluginsHow it fires
How this agent gets triggered: by you, by Claude, or both.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Background for the local-mode bullet in `AGENT.md`. The procedure lives there; this file holds the reasoning, so the agent's system prompt stays short on a path that never runs in PR mode.
Background for the local-mode bullet in `AGENT.md`. The procedure lives there; this file holds the reasoning, so the agent's system prompt stays short on a path that never runs in PR mode.
On the default path nothing is interpolated, so a repository whose default branch is named something like `main$(id)` cannot turn the base ref into a shell payload. Resolving it to a name first would put attacker-influenceable text into a command string for no gain. `origin/HEAD` also resolves to the remote's default branch, so it never compares against a stale local `main`.
A caller-supplied `BASE:` ref is the one exception, and the next section is what holds it.
`origin/HEAD` is the right default and the wrong answer on a branch cut from a release branch such as `rc` or `hotfix-rc`. The three-dot diff takes the merge base with trunk, so every already-merged commit the release branch carries lands in the review and the scope covers work that is not in the change. `BASE:` exists for that case, and only that case: a pull request's base is the one GitHub records and `gh pr diff` already uses it.
The default costs nothing at the shell, because `origin/HEAD` is a literal in the agent's own text. A caller-supplied ref is not, so it is the one value on this path that reaches a command string from outside. Two things hold it: the `^[A-Za-z0-9][A-Za-z0-9._/-]*$` pattern, and the fact that it is checked on both sides of the delegation. The leading character class is the load-bearing half — `Bash(git diff:*)` is a prefix rule, so it matches `git diff --output=… …` just as readily as a ref, and a value beginning with `-` is handed to git as a flag. The rest of the class keeps whitespace, shell metacharacters, and git's own `@{…}` revision syntax out.
The command turn checks it because it is the turn that reads `$ARGUMENTS`. The agent re-checks it because the command turn is not its only caller — an agent reached directly, or through a prompt someone else composed, gets the same control either way.
`--base origin/rc` and `--base rc` both pass the pattern, and the docs and the abort advice point at the first. Two reasons, and the second is the same one that picked `origin/HEAD` as the default above.
A bare `rc` resolves only against `refs/heads/rc`, a local branch. The checkout that actually hits this abort is the one that has no such branch: `actions/checkout`, or any clone where someone ran `git checkout -b feat/x origin/rc` and never made a local `rc`. Telling that caller to run `git fetch origin rc` does not help them, because a fetch writes `refs/remotes/origin/rc` and leaves `refs/heads/rc` absent, so the next run aborts on the identical message. Interpolating the supplied ref into the advice is worse when it is already `origin/rc`, since `git fetch origin origin/rc` fails with `couldn't find remote ref`. That is why the advice names the bare branch in the fetch and the remote-tracking ref in the re-run, rather than echoing back whatever was supplied.
The second reason is staleness. When a bare `rc` does resolve, it resolves to a local branch that can sit behind the remote, which is exactly the failure the first section gives for not resolving `origin/HEAD` to a name. A review scoped against a stale base reports a verdict over the wrong set of commits, quietly, which is the outcome this whole path is built to refuse.
Two ways it fails, and both land on No Verdict.
A ref that fails the pattern is rejected before any command runs. A ref that passes it can still fail to resolve — a release branch nobody fetched is the ordinary case — and `git diff` exits non-zero. Neither computed the scope the caller named.
What makes the abort necessary is what the alternatives review instead. Falling back to `origin/HEAD` is safe at the shell and wrong at the review: the caller named a base precisely because the default resolves the wrong scope for them, so it reproduces the sweep-in this parameter was added to prevent. Falling through to the pending-changes path is wrong the same way and reads worse, because a dirty tree makes it succeed — the agent reviews uncommitted edits and reports a verdict, and nothing in that verdict says the branch-against-`rc` comparison never happened. Both produce a confident answer to a question nobody asked. Unknown scope is No Verdict, the same as an unidentifiable pull request.
An empty result is the one outcome that is not a failure of the ref. The ref resolved; the branch simply holds nothing ahead of it. That falls back like the default does.
A three-dot diff compares commits and ignores the working tree, so it exits 0 and prints nothing whenever the branch is level with its base — which is exactly the state of a developer asking for their pending edits to be reviewed. Four agents reviewing an empty diff report clean, and that verdict is worse than no verdict.
`git diff HEAD` shows tracked edits and lists no untracked files, so a branch whose changes are entirely new files produces an empty diff and is still reviewable. `git status --porcelain` finds those files, but it emits status codes and paths — not content. Reporting a verdict over a list of filenames is the same failure as reporting one over an empty diff, so the paths it marks `??` have to actually be read.
`--untracked-files=all` is part of the command, not a refinement of it. In the default `--untracked-files=normal` mode git reports a wholly untracked directory as one collapsed `?? some-new-dir/` entry rather than the files inside it, and `Read` errors on a directory. Without the flag the all-new-files case yields nothing readable, falls through to the abort, a
A curated collection of plugins for AI-assisted development at Bitwarden. Enables discovery and distribution of quality-controlled plugins for use with Claude Code.
Bitwarden product designer. Holds the team's Code of Conduct and the 30/60/90 critique framework, and dispatches into the design…
Use when analyzing requirements, synthesizing specifications from multiple sources, or conducting product research. Trigger…
Application security engineer specializing in vulnerability triage, threat modeling, and secure code analysis. Use for security…