Development workflow
New feature
Section titled “New feature”The heaviest case, a new user-visible feature touching both backend and UI, runs this
sequence. Validate the idea with users, design the architecture and the UI, implement,
review, and ship. Each step has a dedicated agent. The order matches the full-stack row
of the Fast paths by change class table in CLAUDE.md.
/voc all <feature> # 1. Voice of the Customer: simulated persona feedback panel ↓threat-model # only if it crosses a trust boundary: auth, uploads, tenancy ↓architect # 2. Architecture review: design questions, ADR ↓ux-design # 3. UI/UX design, if the feature has UI ↓implement # 4. Write the code ↓pre-MR gate batch # 5. regression-check + security-review + rbac-check + perf-check, ↓ # run as ONE parallel batch; apply only what the diff touchesux-review + accessibility # 6. Design-system and WCAG compliance, if UI changed ↓test-scaffold # 7. Generate tests, if coverage doesn't exist ↓changelog # 8. Create the changelog fragment ↓/mr # 9. Open the merge request, with every gate's result recorded ↓/fix-mr # only if the pipeline fails or the MR conflicts/review, a general code review against project conventions, can run at any point before
/mr.
Not every step runs on every feature. The table in CLAUDE.md is the authority on
which gates each kind of change needs. Check it first: a bug fix runs three gates, not
nine. With global-claude-md.example installed in ~/.claude/CLAUDE.md (see
Start a project, step 7),
Claude invokes each agent automatically when its trigger condition is met. Without it,
you invoke agents yourself.
Agent trigger conditions
Section titled “Agent trigger conditions”| Agent | Triggers when… | Model |
|---|---|---|
voc |
Any user-facing feature | opus (+ sonnet sub-agents) |
threat-model |
New subsystem crossing a trust boundary (auth, uploads, tenancy, external input) | opus (+ sonnet sub-agents) |
architect |
Any feature or logic change | opus (+ sonnet sub-agents) |
ux-design |
Any UI feature | opus (+ sonnet sub-agents) |
test-scaffold |
New code lacks test coverage | sonnet (+ sonnet sub-agents) |
ux-review |
UI code changed | sonnet |
accessibility |
UI code changed (WCAG 2.1 AA) | sonnet |
security-review |
Endpoints, auth, or user input changed | opus (+ sonnet sub-agents) |
rbac-check |
Endpoints, views, or permission rules changed | sonnet |
perf-check |
Database queries or serializers changed | sonnet |
regression-check |
Any source code change before MR | opus (+ sonnet sub-agents) |
changelog |
Any branch touching source code | sonnet |
dependency |
Before adding any new package | sonnet (+ sonnet sub-agents) |
docs |
Documentation added or updated | sonnet (+ sonnet sub-agents) |
The pre-MR review gates — regression-check, security-review, rbac-check,
perf-check — are independent reads of the same diff. Run them as one parallel agent
batch, not serially (see the Pre-MR gate batch section in CLAUDE.md).
Bug fix
Section titled “Bug fix”Bug fixes with an identified root cause skip the design phases:
fix the bug → regression-check → test-scaffold (if no coverage) → changelog → /mrsecurity-review and perf-check still apply if the fix touches endpoints or queries.
Documentation change
Section titled “Documentation change”docs agent (for a new page) → /mrDependency bump
Section titled “Dependency bump”dependency → changelog → /mrChore / CI config / lint-only
Section titled “Chore / CI config / lint-only”/mrCode review
Section titled “Code review”The /review command runs a general code review against project conventions. It’s
distinct from the specialized review agents:
| Command/Agent | Focus | When to use |
|---|---|---|
/review |
Code quality, patterns, consistency, naming | Any MR — general quality check |
security-review |
OWASP Top 10, auth, permissions, injection | MRs touching endpoints or auth |
rbac-check |
Auth required, object-level access, role enforcement | MRs touching endpoints or permissions |
ux-review |
Design system compliance | MRs changing UI components |
accessibility |
WCAG 2.1 AA — keyboard, screen-reader, contrast | MRs changing UI components |
regression-check |
Stale mocks, broken tests, permission drift | Before every MR (automated) |
Safety hooks
Section titled “Safety hooks”Two Claude Code hook layers run automatically during development.
Pre-tool safety (.claude/hooks/pre-tool-safety.sh)
Section titled “Pre-tool safety (.claude/hooks/pre-tool-safety.sh)”Runs before Claude edits any file. Configured in .claude/settings.json as a
PreToolUse hook.
| Pattern | Action | Why |
|---|---|---|
Lock files (package-lock.json, yarn.lock, uv.lock, etc.) |
Block | Must be regenerated by the package manager, not hand-edited |
Migration files (migrations/0001_*.py, etc.) |
Block | Editing existing migrations corrupts production databases |
CI config (.gitlab-ci.yml, ci/*.yml) |
Warn | Changes affect all branches — verify before pushing |
Environment files (.env, .env.local) |
Warn | May contain secrets — do not commit |
Post-edit reminders (.claude/hooks/post-edit-checks.sh)
Section titled “Post-edit reminders (.claude/hooks/post-edit-checks.sh)”Runs after Claude edits a file. Shows a reminder to run the relevant agent.
| Pattern | Reminder |
|---|---|
models.py, schema.prisma, *.sql |
Verify migration safety |
views.py, routes/, handlers/, controllers/ |
Use the security-review agent |
permissions.py, auth.*, middleware |
Use the security-review agent |
Customize both files with patterns relevant to your stack. The pre-tool hook uses exit code 2 to block an edit, exit code 0 to allow (with optional warning message).
Duplicate-work gate (scripts/check-issue-collision.sh)
Section titled “Duplicate-work gate (scripts/check-issue-collision.sh)”Runs on git push, first in make pre-push-checks — before the slower code gates,
because finding out you duplicated another session’s issue is cheapest before the
lint/typecheck minutes are spent.
| Condition | Action |
|---|---|
| The branch’s issue already has an open MR from a different branch | Block — override with ALLOW_DUP_MR=1 for deliberate stacked work |
| The issue carries the WIP label but has no MR yet | Warn — a claim without published work is weaker evidence |
| The branch carries no issue number, or the issue is unclaimed | Pass |
wt new does not check the tracker for other sessions working the same issue. It only
refuses when the worktree path already exists or the WIP cap is reached. A plain
git checkout -b feat/<issue>-… skips wt entirely. Push is the one point every branch
passes through, however it was created, so that is where the duplicate check lives. Works
with glab and gh; a no-op if neither is installed.
It reads every page of open MRs, not the first hundred. A gate whose failure mode is a clean pass cannot afford a silent cap: a project that crosses one loses the duplicate check with nothing anywhere saying so. And when the list cannot be read at all — offline, unauthenticated, an unparseable response — it says that out loud instead of passing quietly, because a degradation nobody sees is indistinguishable from a green.