From 3143d91311822dff0e67fb8a576b985e0db66aac Mon Sep 17 00:00:00 2001 From: Paolo Dettori Date: Fri, 13 Mar 2026 14:25:49 -0400 Subject: [PATCH 1/2] feat: add pre-commit hooks, linting, and Claude Code setup - Extend .pre-commit-config.yaml with local DCO commit-msg hook - Add `make fmt` target (ruff format) - Create CLAUDE.md with repo overview, commands, and conventions - Add .claude/settings.json with allowed Bash permissions - Add scripts/hooks/commit-msg to enforce DCO sign-off and block Co-Authored-By AI attribution (use Assisted-By instead) Pre-commit install: `pre-commit install --hook-type pre-commit --hook-type commit-msg` Assisted-By: Claude (Anthropic AI) Signed-off-by: Paolo Dettori --- .claude/settings.json | 17 +++++++++++ .pre-commit-config.yaml | 8 ++++++ CLAUDE.md | 62 ++++++++++++++++++++++++++++++++++++++++ Makefile | 5 +++- scripts/hooks/commit-msg | 22 ++++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 .claude/settings.json create mode 100644 CLAUDE.md create mode 100755 scripts/hooks/commit-msg diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..585497f --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,17 @@ +{ + "permissions": { + "allow": [ + "Bash(git status:*)", + "Bash(git log:*)", + "Bash(git diff:*)", + "Bash(git branch:*)", + "Bash(ls:*)", + "Bash(find:*)", + "Bash(make lint:*)", + "Bash(make fmt:*)", + "Bash(pre-commit run:*)", + "Bash(uv run pytest:*)", + "Bash(uv run ruff:*)" + ] + } +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 023a9bf..c0f23a3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,3 +17,11 @@ repos: args: [ --fix ] # Run the formatter. - id: ruff-format + +- repo: local + hooks: + - id: commit-msg-dco + name: DCO sign-off check + language: script + entry: scripts/hooks/commit-msg + stages: [commit-msg] diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2380de2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,62 @@ +# plugins-adapter + +## Overview + +An Envoy external processor (ext-proc) for configuring and invoking guardrails +in an Envoy-based gateway like [MCP Gateway](https://github.com/kagenti/mcp-gateway). +Intercepts gRPC traffic and applies configurable plugins (e.g., NeMo Guardrails). + +## Repository Structure + +``` +plugins-adapter/ +├── src/ # Core server implementation (ext-proc gRPC server) +├── plugins/ # Plugin implementations +│ └── examples/ # Example plugins (nemocheck, etc.) +├── tests/ # Unit tests (pytest) +├── docs/ # Architecture, build, deployment docs +├── resources/ # Kubernetes manifests and config +├── proto-build.sh # Protobuf code generation script +├── ext-proc.yaml # Envoy ExtProc deployment manifest +└── filter.yaml # Envoy HTTP filter config +``` + +## Key Commands + +| Task | Command | +|------|---------| +| Lint | `make lint` | +| Format | `make fmt` | +| Test | `uv run pytest tests/ -v` | +| Build image | `make build PLUGIN_DEPS=nemocheck` | +| Deploy to Kind | `make all PLUGIN_DEPS=nemocheck` | +| Build protobufs | `uv sync --group proto && ./proto-build.sh` | +| Run locally | `make dev-run-nemocheck` | + +## Code Style + +- Python 3.11+ with `uv` package manager +- Linter/formatter: `ruff` (config in `pyproject.toml`) +- Pre-commit hooks: `pre-commit install` +- Sign-off required: `git commit -s` + +## Plugin Development + +Plugins live in `plugins/`. Each plugin implements the `cpex` interface. +See `plugins/examples/` for reference implementations. + +Config in `resources/config/config.yaml`: +```yaml +plugins: + - name: my_plugin + path: ./plugins/my_plugin + enabled: true +``` + +## DCO Sign-Off (Mandatory) + +All commits must include a `Signed-off-by` trailer: + +```sh +git commit -s -m "feat: add feature" +``` diff --git a/Makefile b/Makefile index be8c1ee..b6a0482 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build load all deploy exec log lint +.PHONY: build load all deploy exec log lint fmt .IGNORE: delete @@ -51,6 +51,9 @@ deploy: lint: pre-commit run --all-files +fmt: + uv run ruff format . + redeploy: delete deploy push_image_quay: build diff --git a/scripts/hooks/commit-msg b/scripts/hooks/commit-msg new file mode 100755 index 0000000..0cc3c50 --- /dev/null +++ b/scripts/hooks/commit-msg @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# commit-msg hook: enforce DCO sign-off and block Co-Authored-By AI attribution +set -euo pipefail + +COMMIT_MSG_FILE="$1" +COMMIT_MSG=$(cat "$COMMIT_MSG_FILE") + +# Check for DCO sign-off +if ! grep -qE "^Signed-off-by: .+ <.+@.+>" "$COMMIT_MSG_FILE"; then + echo "ERROR: Commit message missing Signed-off-by trailer (DCO required)." + echo " Use: git commit -s" + exit 1 +fi + +# Block Co-Authored-By for AI (use Assisted-By instead) +if grep -qiE "^Co-[Aa]uthored-[Bb]y:.*claude|^Co-[Aa]uthored-[Bb]y:.*anthropic|^Co-[Aa]uthored-[Bb]y:.*openai|^Co-[Aa]uthored-[Bb]y:.*chatgpt" "$COMMIT_MSG_FILE"; then + echo "ERROR: Use 'Assisted-By' instead of 'Co-Authored-By' for AI attribution." + echo " Replace with: Assisted-By: Claude (Anthropic AI) " + exit 1 +fi + +exit 0 From fa7563b9d8cfea9f91395fc001fd73f6909ec6a7 Mon Sep 17 00:00:00 2001 From: Paolo Dettori Date: Fri, 13 Mar 2026 15:04:55 -0400 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20remove=20redundant=20fmt=20target=20?= =?UTF-8?q?=E2=80=94=20pre-commit=20already=20runs=20ruff-format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit make lint runs pre-commit --all-files which includes ruff-format (via the ruff-pre-commit hook). A separate make fmt target is redundant. Addresses review comment from evaline-ju on PR #70. Assisted-By: Claude (Anthropic AI) Signed-off-by: Paolo Dettori --- CLAUDE.md | 3 +-- Makefile | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 2380de2..f645ce3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,8 +25,7 @@ plugins-adapter/ | Task | Command | |------|---------| -| Lint | `make lint` | -| Format | `make fmt` | +| Lint + Format | `make lint` | | Test | `uv run pytest tests/ -v` | | Build image | `make build PLUGIN_DEPS=nemocheck` | | Deploy to Kind | `make all PLUGIN_DEPS=nemocheck` | diff --git a/Makefile b/Makefile index b6a0482..be8c1ee 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build load all deploy exec log lint fmt +.PHONY: build load all deploy exec log lint .IGNORE: delete @@ -51,9 +51,6 @@ deploy: lint: pre-commit run --all-files -fmt: - uv run ruff format . - redeploy: delete deploy push_image_quay: build