From patchwork Sat Apr 4 21:29:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2149 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775338415; bh=LCznyxnr/oGY8azrkSGHZYYEd25uNgAb0km01hvZD6M=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Hr7kakM21+eEeyZEWRMSyX5esaeJtUIgWAmpVzqJiQGmD14clIq4ZEF96d5kla9U0 e2+sY96JQb3vfhm3JA7ldyPACReM8nErC0qdWD457fVg/SIyD1h9B2Ni/xD0QTPPP6 QYMDJ91IzncJRXtpBWvIuKx1eXAjEWOp9WpGVwyyV3onEi5ffqgjz793QiFGz56SNk 3YPbkU6Im4sNoL79GAkSlJ+UhV/61dYr4s93J2rCuH1OUcbPsyxSDeULRazW0aLBnA +BgKP0KAQAGRSvU9cURsUoqLLpVz2axZ66OnS9GUAP4jzFANW+k6Ua6YUyq9+ndzhN 9S1vRYEp9ZS7g== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 66F346869D for ; Sat, 4 Apr 2026 15:33:35 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 0HtnqMiV5n9X for ; Sat, 4 Apr 2026 15:33:35 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775338415; bh=LCznyxnr/oGY8azrkSGHZYYEd25uNgAb0km01hvZD6M=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Hr7kakM21+eEeyZEWRMSyX5esaeJtUIgWAmpVzqJiQGmD14clIq4ZEF96d5kla9U0 e2+sY96JQb3vfhm3JA7ldyPACReM8nErC0qdWD457fVg/SIyD1h9B2Ni/xD0QTPPP6 QYMDJ91IzncJRXtpBWvIuKx1eXAjEWOp9WpGVwyyV3onEi5ffqgjz793QiFGz56SNk 3YPbkU6Im4sNoL79GAkSlJ+UhV/61dYr4s93J2rCuH1OUcbPsyxSDeULRazW0aLBnA +BgKP0KAQAGRSvU9cURsUoqLLpVz2axZ66OnS9GUAP4jzFANW+k6Ua6YUyq9+ndzhN 9S1vRYEp9ZS7g== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 50FDF64DB2 for ; Sat, 4 Apr 2026 15:33:35 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775338414; bh=8Y0aOSIciOs8SWMCrcVW6Ov2GYbPe+9SMM/2AkuNlOo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gElEaW1M94qjnqSuWhsLrmW7hbS5li3sgGyepVgJkOItR0aINyUcxeFcp8vZYcjru oThRyebEtt2rIX2JyKqXbmVrfj59hQlhdUqEvGl4cSyE3wkbXtPrZzhg/vr2ZH61ir 5tAyToWS5vAUd30RFZHG+oTemGBfuwaaNLKKo+8RYaFq7lxk3FFCTpXhEl1BpzGM23 z84NYnu+muDkvQlviRQ9HBk5ighID0bCqS8OAYv7QMG7YkyJvXMD17eOAcXC2BzI+F YSAUCRUnPeIe7MrKkQJDEq0K6T5Js3V9+xxj694A0OSJraabwbqRilPS2CYAOZF55V JwACw066e7OEw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4642364DB2; Sat, 4 Apr 2026 15:33:34 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id 6w637xOioUWb; Sat, 4 Apr 2026 15:33:34 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775338410; bh=MK52P8Q/GEQfGziW9Be6kOpQP1q0ZmPmyLt5PJ/iAHA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t2mSVujHL0dEqr8/9uOFYflQREKRkkXPIpNhMd6ggyBwZolxx3EqZjFRSRj+dC75P cIfaIr1xq7lyJ8Y/tUeob9zu94MmIb5nyPolnYzkgxNloVlrYWswUR4++YuskvWQLM FHFk91HPHS7JbErvgVlHwm0qTn8UzYFZcMpAZPb96FB1ytErlyxOon6JPfauT7lWGm hvp6rlSt0mN2st1R8C289CrXPe75bdffU2ohkqC7/sKGoyrT09xcUkqU7Vqet8gwrN TuNi7Y9W7Q4dyZlr1ZnvmM5nH+zOBw3EYVNClV6UpMkfWZ3p0Kcwpz2YXum/of/gh6 JdNpvdQmVMK7A== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id D5A4C5E7B4; Sat, 4 Apr 2026 15:33:29 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Sat, 4 Apr 2026 15:29:11 -0600 Message-ID: <20260404213020.372253-36-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260404213020.372253-1-sjg@u-boot.org> References: <20260404213020.372253-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: SZCCJJD75LZJ6CQARUL42OA2LSPF7JJP X-Message-ID-Hash: SZCCJJD75LZJ6CQARUL42OA2LSPF7JJP X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 35/37] patman: Add documentation for AI-assisted patch review List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Document the 'patman review' command and its options in the patman README. Covers series selection, patch application, AI review, Gmail draft creation, voice learning, draft synchronisation and the review workflow. Signed-off-by: Simon Glass --- tools/patman/patman.rst | 207 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) -- 2.43.0 diff --git a/tools/patman/patman.rst b/tools/patman/patman.rst index 87e0984c0d7..4c1dba07e6a 100644 --- a/tools/patman/patman.rst +++ b/tools/patman/patman.rst @@ -1188,3 +1188,210 @@ putting an incorrect tag in a commit may provide a confusing message. There might be a few other features not mentioned in this README. They might be bugs. In particular, tags are case sensitive which is probably a bad thing. + + +AI-assisted patch review +======================== + +Patman can review other people's patches from Patchwork using a Claude +AI agent, and create Gmail draft replies with the review comments. + +Prerequisites +------------- + +Install the required packages:: + + sudo apt install python3-google-auth python3-google-auth-oauthlib \ + python3-google-auth-httplib2 python3-googleapi + pip install claude-agent-sdk + +Setting up Gmail API access +--------------------------- + +1. Go to https://console.cloud.google.com and create (or select) a project. + +2. Enable the **Gmail API**: + + - Navigate to **APIs & Services > Enabled APIs & services** + - Click **Enable APIs and services**, search for "Gmail API", enable it + +3. Configure the **OAuth consent screen**: + + - Navigate to **APIs & Services > OAuth consent screen** + - Set publishing status to **Testing** + - Under **Test users**, add your email address (e.g. sjg@chromium.org) + +4. Create **OAuth client credentials**: + + - Navigate to **APIs & Services > Credentials** + - Click **Create Credentials > OAuth client ID** + - Application type: **Desktop app** + - Download the JSON file + +5. Save the credentials:: + + mkdir -p ~/.config/patman.d + mv ~/Downloads/client_secret_*.json ~/.config/patman.d/client_secret.json + +The first time you create drafts, a browser window opens for OAuth +consent. After authentication, the token is cached in +``~/.config/patman.d/`` and reused for future runs. + +Setting up Patchwork +-------------------- + +Configure an upstream with its Patchwork URL:: + + patman upstream add us https://source.denx.de/u-boot/u-boot.git \ + --patchwork-url https://patchwork.ozlabs.org + patman patchwork set-project U-Boot us + +Basic usage +----------- + +Review a series by Patchwork link:: + + patman review -l 497923 -U us --reviewer 'Your Name ' + +Or search by cover-letter title:: + + patman review -t 'boot/bootm: Disable interrupts' -U us \ + --reviewer 'Your Name ' + +To create Gmail drafts threaded under the original emails:: + + patman review -l 497923 -U us \ + --reviewer 'Your Name ' \ + --create-drafts --gmail-account your@email + +Use ``-n`` with ``--create-drafts`` for a dry run that shows what would +be created without calling the Gmail API. + +Use ``--apply-only`` to download and apply patches without running the +AI review — useful for checking that patches apply cleanly. + +Use ``-f`` / ``--force`` to re-review a series that has already been +reviewed. This deletes the old review records and runs the review +again:: + + patman review -l 497923 -U us -f --reviewer 'Your Name ' + +If the reviewer email (from ``--reviewer`` or git config) differs from +the ``--gmail-account``, patman sets the From header on the draft so +the email is sent with the correct identity. + +How the review works +-------------------- + +For each patch, the AI agent: + +1. Studies all patches in the series to understand the overall design +2. Re-reads the specific patch in detail +3. Examines surrounding source code for context +4. Checks existing comments from other reviewers on Patchwork and + avoids repeating points already made +5. Produces a structured review (GREETING/COMMENT/VERDICT format) + +After all patches are reviewed, a refinement agent makes a second pass +over the drafts to tighten the language, remove cross-patch duplicates +and check voice consistency. Approved reviews without comments are +excluded from refinement to preserve their quoted commit messages. + +A mechanical cleanup step also runs to remove backticks and fix function +quoting style (e.g. ``malloc()`` not ```malloc```). + +Patchwork subcommands +--------------------- + +Remove a patchwork project configuration:: + + patman patchwork rm [remote] + +If no remote is given, the default (no-upstream) entry is deleted. + +Review notes +------------ + +The ``handle-reviews`` workflow produces a ``review-notes.txt`` file +describing how feedback was addressed. Store it in the database so +future versions can reference it:: + + patman series save-notes [notes-file] + +The default filename is ``review-notes.txt``. Display notes from all +previous versions:: + + patman series show-notes + +Settings +-------- + +Add these to your ``~/.patman`` file to avoid repeating flags: + +.. code-block:: ini + + [settings] + signoff: Regards,\nSimon + spelling: British + +The ``signoff`` is appended to reviews that have comments (not to +clean Reviewed-by-only replies). The ``spelling`` setting controls +the spelling convention used in review comments. + +Voice learning +-------------- + +Build a voice profile so AI reviews match your writing style:: + + # From Gmail (searches your sent reviews to the mailing list) + patman review --learn-voice gmail -U us \ + --gmail-account your@email --reviewer 'Your Name ' + + # From Patchwork (scans your comments on recent patches) + patman review --learn-voice patchwork -U us \ + --reviewer 'Your Name ' + +Use ``--voice-count N`` to control how many reviews to collect +(default: 20). The voice profile is saved to +``~/.config/patman.d/voice.md`` and automatically used in subsequent +reviews. + +Syncing drafts +-------------- + +After editing and sending (or deleting) Gmail drafts:: + + patman review --sync --gmail-account your@email \ + --reviewer 'Your Name ' + +This: + +- Detects which drafts have been sent and records the final email + content in the database (for context when reviewing future versions) +- Detects deleted drafts (review not sent) +- Refines the voice profile if the sent text differs from the AI draft +- Detects replies from the patch author or other reviewers +- Generates response drafts when appropriate (e.g. answering + questions, pushing back on objections, or conceding gracefully) + +Review lifecycle +---------------- + +Each review goes through these states: + +- **new**: AI review generated, not yet sent +- **draft**: Gmail draft created +- **sent**: Draft was sent; body updated with actual sent content +- **deleted**: Draft was deleted without sending +- **replied**: Author or another reviewer has replied to our review + +When reviewing a new version of a previously reviewed series, patman +loads the previous review as context for the AI, so it can check +whether earlier issues have been addressed. + +Aliases +------- + +The ``review`` command supports aliases ``r`` and ``rev``:: + + patman r -l 497923 -U us --reviewer 'Your Name '