Skip to content

Add session-code-review plugin for backpressure code review#73

Open
jwaldrip wants to merge 3 commits intomainfrom
claude/code-review-backpressure-hook-ZGk6P
Open

Add session-code-review plugin for backpressure code review#73
jwaldrip wants to merge 3 commits intomainfrom
claude/code-review-backpressure-hook-ZGk6P

Conversation

@jwaldrip
Copy link
Collaborator

Summary

Adds a new session-code-review validation plugin that provides automatic code review of changes against REVIEW.md and CLAUDE.md guidelines. The plugin uses agent-based hooks to review changes before session completion and before git commits/pushes, catching issues early in the development workflow.

Changes

  • Added session-code-review plugin with Stop and PreToolUse hooks for automatic code review
  • Implemented /code-review skill for on-demand manual review of branch changes
  • Added comprehensive documentation in README.md and SKILL.md
  • Configured hooks to review against project-defined guidelines in REVIEW.md and CLAUDE.md
  • Registered plugin in marketplace.json

Type of Change

  • New plugin
  • Bug fix
  • Breaking change
  • Documentation

Plugin Changes

Plugin category:

  • Tool - Development tools and utilities
  • Framework - Framework-specific skills
  • Language - Language-specific skills
  • Validation - Linting and validation hooks
  • Discipline - Specialized agents with domain expertise
  • Integration - MCP servers for external services
  • Pattern - Methodologies and workflows
  • Core - Han CLI or core infrastructure

Validation:

  • Plugin structure follows existing patterns
  • Hooks configured with appropriate timeouts and prompts
  • Documentation complete with examples

Testing

  • Plugin structure validated
  • Hook configuration follows established patterns
  • Documentation includes example interactions

Checklist

  • Code follows existing patterns
  • Documentation complete (README.md, SKILL.md)
  • Plugin registered in marketplace.json
  • No new warnings

https://claude.ai/code/session_01FHRTJGN8UmVYoWBmiKrYsH

claude added 2 commits March 14, 2026 18:21
Adds a new validation plugin that uses Claude Code's agent-based hooks
to review session changes against REVIEW.md before allowing completion
or commits. Two hooks provide backpressure:

- Stop hook: reviews all uncommitted changes when Claude finishes
- PreToolUse hook: gates git commit/push with a review check

Includes a /code-review skill for on-demand branch review.

https://claude.ai/code/session_01FHRTJGN8UmVYoWBmiKrYsH
Agent-based hooks can take up to 50 turns of investigation.
120s was too tight for reviewing large diffs.

https://claude.ai/code/session_01FHRTJGN8UmVYoWBmiKrYsH
@railway-app
Copy link

railway-app bot commented Mar 16, 2026

🚅 Deployed to the han-pr-73 environment in han-team-platform

4 services not affected by this PR
  • postgres
  • redis
  • website
  • api

Agent hooks now invoke the /code-review skill instead of duplicating
the review logic inline. Single source of truth for review behavior.

https://claude.ai/code/session_01FHRTJGN8UmVYoWBmiKrYsH
@claude
Copy link

claude bot commented Mar 16, 2026

test comment from agent

@claude
Copy link

claude bot commented Mar 16, 2026

Code Review PR 73 — session-code-review plugin. Please see detailed review notes.

@claude
Copy link

claude bot commented Mar 16, 2026

Han - Claude Code Plugin Marketplace

Project Overview

Han is a curated marketplace of Claude Code plugins built on Bushido principles. The codebase consists of:

  • bushido/ - Core foundation plugin with quality principles
  • jutsu/ - Technique plugins (language/tool skills with validation hooks)
  • do/ - Discipline plugins (specialized agents)
  • hashi/ - Bridge plugins (MCP servers for external integrations)
  • packages/han/ - CLI tool for plugin installation and management

Development Commands

# Build the CLI
cd packages/han && npm run build

# Run tests
cd packages/han && npm test

# Format code (from website directory)
cd website && npx biome format --write .

# Run Playwright tests
cd website && npx playwright test

Plugin Structure

Each plugin follows this structure:

plugin-name/
├── .claude-plugin/
│   ├── plugin.json      # Plugin metadata
│   ├── hooks.json       # Claude Code hooks (optional)
│   └── marketplace.json # Only in root for marketplace listing
├── commands/            # Slash commands (*.md with frontmatter)
└── skills/              # Skills (*.md)

Command Files

Commands require YAML frontmatter:

---
description: Brief description of the command
---

Command content here...

hooks.json Format

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          { "type": "command", "command": "your-command-here" }
        ]
      }
    ]
  }
}

CLI Architecture

The CLI (packages/han/) uses:

  • Commander.js for CLI parsing
  • Ink (React for CLI) for interactive UIs
  • Claude Agent SDK for AI-powered plugin detection

Key files:

  • lib/main.ts - CLI entry point and command definitions
  • lib/install.ts - Plugin installation logic
  • lib/shared.ts - Shared utilities and agent detection
  • lib/plugin-selector.tsx - Interactive plugin selector UI

Versioning

Version bumps happen automatically via GitHub Actions:

  • feat: commits trigger MINOR bumps
  • fix:, refactor:, etc. trigger PATCH bumps
  • ! or BREAKING CHANGE: triggers MAJOR bumps

CI/CD

  • auto-tag-release.yml - Bumps version and creates tags on changes to packages/han/
  • publish-npm.yml - Publishes to npm using trusted publishers (OIDC, no token needed)
  • claudelint.yml - Validates plugin structure (uses claudelint in CI)

Plugin Validation

Use claude plugin validate locally to validate plugins:

# Validate a plugin or marketplace
claude plugin validate .

# Validate a specific path
claude plugin validate /path/to/plugin

Conventions

  • Use npx biome format --write . for formatting
  • Plugin names use short identifiers matching their directory name (e.g., typescript, github, frontend-development)
  • Always include bushido as a dependency in recommendations
  • MCP servers in bridge/service plugins should use HTTP transport with OAuth when available

Plugin Installation

Plugins automatically install the han binary to ~/.claude/bin/han on first session start (via the core plugin's SessionStart hook). This ensures hooks work immediately without any manual setup.

For users who want to use the CLI outside of Claude Code sessions:

# Recommended: Install via curl
curl -fsSL https://han.guru/install.sh | bash

# Or via Homebrew
brew install thebushidocollective/tap/han

# Then install plugins
han plugin install --auto

Within Claude Code, plugins can also be installed via:

/plugin install bushido@han

Installation Scopes

By default, plugins install to user settings (~/.claude/settings.json) which applies across all projects:

# User scope (default) - shared across all projects
han plugin install playwright-mcp

# Project scope - only for current project (.claude/settings.json)
han plugin install typescript --scope project

# Local scope - gitignored project settings (.claude/settings.local.json)
han plugin install --scope local

Scope recommendations:

  • user (default): MCP servers, general-purpose plugins (services, disciplines)
  • project: Project-specific validation hooks (validation plugins with hooks)
  • local: Personal preferences not shared with team

Global installation via Homebrew or install.sh is optional but provides faster execution for frequent CLI usage.

@claude
Copy link

claude bot commented Mar 16, 2026

Code Review — PR #73: session-code-review plugin

Good concept overall — backpressure code review in the session loop rather than post-PR is the right philosophy. A few issues to address before merging.


CRITICAL

1. PreToolUse agent hook fires on every single Bash call

File: plugins/validation/session-code-review/hooks/hooks.json (lines 18-28)

The PreToolUse hook is registered on Bash with type: agent. This spawns a full AI agent for every Bash tool invocation in the session — ls, cat, npm install, everything — just to check if the command contains git commit or git push.

Even if the agent immediately returns the skip result, spawning an agent process still incurs an API round-trip (typically 1-4s). A session with 50 Bash calls adds 1-3 minutes of latency from this hook alone.

The intent ("skip immediately if not a git command") is sound, but an AI agent is the wrong tool for this check. A fast command-type guard hook should precede the agent in the hooks array — it exits 0 immediately for non-git commands without ever spawning an agent, and only the agent hook (second entry) runs when the pattern actually matches.


MODERATE

2. The custom output format may not actually block execution

File: plugins/validation/session-code-review/hooks/hooks.json (lines 9, 25)

The prompts instruct the agent to return a custom JSON shape, but for PreToolUse agent hooks to deny execution, the required format uses hookSpecificOutput with permissionDecision: "deny". Without this, the response is treated as context feedback — the commit/push gate will not actually block anything.

See .claude/rules/hooks/pretooluse-updatedInput.md for the correct structure (and the note about not combining permissionDecision with updatedInput).

For the Stop hook, the blocking mechanism also needs verification — the agent needs to signal Claude Code to continue iterating rather than completing, and the custom shape is not documented as the mechanism for this.

3. Stop hook spawns an agent on every session completion, including clean trees

File: plugins/validation/session-code-review/hooks/hooks.json (lines 7-13)

The prompt checks for an empty diff inside the agent, but the agent still gets fully spawned to make that discovery. A fast command guard (git status --porcelain | grep -q . || exit 0) added as the first hook in the Stop array would avoid the API round-trip on clean trees, which is the common case between substantive changes.


MINOR

4. 300s timeout on PreToolUse hook is very high

File: plugins/validation/session-code-review/hooks/hooks.json (line 26)

A 5-minute timeout on a hook that fires before every Bash call is unexpectedly long. Even a thorough diff review should complete in under 60s. Consider 60-120s and document the rationale if 300s is intentional.

5. README install command missing registry specifier

File: plugins/validation/session-code-review/README.md (line 45)

The han plugin install session-code-review --scope project line is inconsistent with the claude plugin install session-code-review@han line just above it, and with conventions in .claude/rules/plugin-naming.md.


Overall

The skill implementation (SKILL.md) is well-structured and the high-signal-only philosophy is the right call. The two main blockers are:

  1. PreToolUse performance — replace the all-Bash agent hook with a fast command guard that only invokes the expensive review when the command is actually a git commit/push.
  2. Hook output format — update the agent prompts to emit the proper hookSpecificOutput structure so Claude Code actually enforces the block decision.

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@claude
Copy link

claude bot commented Mar 16, 2026

Code Review

Nice concept - bringing backpressure code review into the session rather than as a post-PR comment is genuinely useful. A few issues to address before merging.


CRITICAL

1. PreToolUse agent hook fires on EVERY Bash command

The PreToolUse hook with matcher Bash spawns a full LLM agent for every single bash command, just to check if it happens to be a git commit or git push. This includes file reads, test runs, npm installs - everything. With a 300s timeout budget, this creates massive latency overhead on every Bash call.

The prompt attempts to short-circuit (immediately return ok:true), but an agent still has to spin up, process the prompt, and respond before that short-circuit can happen.

Fix: Use a two-layer approach - a fast command hook to pre-filter, only proceeding to the agent hook when the command is actually a git commit/push. A command hook that parses stdin and exits 0 for non-matching commands would make this essentially free for the 99% case.

2. Uncertain if ok:false correctly blocks PreToolUse from an agent hook

Command hooks block tool execution via non-zero exit code + stdout JSON in hookSpecificOutput format with permissionDecision: deny. The prompts instruct the agent to return ok:false with a reason, but this is not the documented Claude Code format for blocking PreToolUse. If agent hook output is not parsed the same way as command hook stdout, the git commit gate silently does nothing when issues are found - the whole point of the PreToolUse hook fails. This needs validation against the actual Claude Code agent hook protocol.


MODERATE

3. Stop hook runs a 300s-budget agent on every single Stop event

Every time Claude finishes responding - including after a simple question - a full LLM code review agent launches. For sessions with no meaningful changes, this is pure overhead.

Consider wrapping with a command hook that pre-checks for changes before the agent fires. If git diff shows no changes (git diff --quiet), skip the agent entirely. This makes the common case essentially free.

4. Infinite review cycle with no bound

The designed behavior is: Stop -> review finds issues -> Claude continues -> fixes -> Stop -> review again. This is intentional backpressure. However, there is no exit condition if Claude cannot fix the issues (e.g., a REVIEW.md rule requires human judgment, or the fix introduces a different issue). Without a max-iterations guard, this could loop indefinitely.

Consider adding guidance to the Stop hook prompt: if the same issues persist after a previous fix attempt in this session, allow completion to avoid an infinite loop.

5. SKILL.md Step 6 is incompatible with hook invocation context

Step 6 says: If issues were found, ask the user if they would like you to fix them.

When /code-review is called from the Stop or PreToolUse hook agent, there is no interactive user - asking a question blocks indefinitely. The skill should branch on invocation context, or the hook prompts should explicitly instruct the agent to fix issues immediately rather than deferring to step 6.


MINOR

6. Broken documentation URL

README.md line 10 links to https://code.claude.com/docs/en/hooks which does not resolve. The Claude Code docs are at https://docs.anthropic.com/en/docs/claude-code/hooks.

7. Triple diff overlap in SKILL.md

Step 3 gathers three diffs: unstaged (git diff), staged (git diff --cached), and all branch commits (git diff base...HEAD). When on a feature branch with committed changes, the committed work is already included in the branch diff. The overlap creates redundant context and inflates token usage. Consider consolidating or adding a comment explaining why all three are needed.

8. Missing SubagentStop hook

Other validation plugins (e.g., biome) register SubagentStop hooks so changes made by subagents are also validated. If a subagent makes file changes and stops, those changes bypass this review. Worth considering whether this is intentional.


Overall the plugin design is solid and the SKILL.md implementation guidance is clear. The main risks are (1) performance degradation from per-Bash-command agent spawning and (2) the unverified blocking protocol for the PreToolUse hook. Fix those two and this is ready to ship.

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.

2 participants