From: Michal Nowak Date: Tue, 5 May 2026 18:50:10 +0000 (+0200) Subject: Validate Assisted-by trailer format and tool list X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2cac546d08fb82d1be7eed61c6ce33ba744d20e4;p=thirdparty%2Fbind9.git Validate Assisted-by trailer format and tool list CONTRIBUTING.md documents the Assisted-by trailer format as Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2] and excludes basic development tools (git, compilers, meson, ninja, editors, clang-format, black, ruff) from the optional tool list. Walk every `Assisted-by:` line in each commit message and emit a `warn()` when: - the line does not match the documented `AGENT:VERSION` shape; - the optional tool list contains basic-tool names. The basic-tool list extends the CONTRIBUTING.md examples with other formatters, generic linters, and build/test runners commonly invoked from `.gitlab-ci.yml`. Specialized analysis tools (coccinelle, clang-tidy, AFL, Coverity, cppcheck, valgrind, sanitizers) are intentionally absent so they remain allowed in the trailer. Use `warn()` rather than `fail()` because the format is human-written and overly strict matching would produce false positives on edge cases. Assisted-by: Claude:claude-opus-4-7 --- diff --git a/dangerfile.py b/dangerfile.py index 2f63c901af5..647bc9767dd 100644 --- a/dangerfile.py +++ b/dangerfile.py @@ -182,6 +182,33 @@ LLM_SIGNED_OFF_BY_RE = re.compile( re.IGNORECASE | re.MULTILINE, ) COAUTHORED_BY_RE = re.compile(r"^Co-Authored-By:.*$", re.IGNORECASE | re.MULTILINE) +# CONTRIBUTING.md documents the trailer format as +# `Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]`. Match every +# `Assisted-by:` line, then check it against the expected shape. +ASSISTED_BY_RE = re.compile(r"^Assisted-by:.*$", re.IGNORECASE | re.MULTILINE) +ASSISTED_BY_VALID_RE = re.compile( + r"^Assisted-by:\s+\S+:\S+(?:\s+\S+)*\s*$", re.IGNORECASE +) +# Basic development tools that CONTRIBUTING.md excludes from the optional +# `[TOOL ...]` portion of the Assisted-by trailer. Combines the examples +# given in CONTRIBUTING.md (git, compilers, meson, ninja, editors, +# clang-format, black, ruff) with other formatters, generic linters, and +# build/test runners commonly invoked by .gitlab-ci.yml. Specialized +# analysis tools (coccinelle, clang-tidy, AFL, Coverity, cppcheck, +# valgrind, sanitizers) are intentionally absent. +ASSISTED_BY_BASIC_TOOL_RE = re.compile( + r"\b(" + r"git|" + r"gcc|g\+\+|clang|clang\+\+|cc|" + r"meson|ninja|make|cmake|autoconf|automake|libtool|" + r"vim|emacs|" + r"clang-format|black|ruff|pylint|mypy|flake8|pyflakes|" + r"pytest|danger|" + r"shellcheck|" + r"sphinx" + r")\b", + re.IGNORECASE, +) fixup_error_logged = False for commit in danger.git.commits: message_lines = commit.message.splitlines() @@ -230,6 +257,31 @@ for commit in danger.git.commits: "Origin; AI agents must not add `Signed-off-by` tags. Use the " "`Assisted-by:` trailer instead." ) + for assisted_line in ASSISTED_BY_RE.findall(commit.message): + if not ASSISTED_BY_VALID_RE.match(assisted_line): + warn( + f"Commit {commit.sha} has a malformed `Assisted-by` trailer: " + f"```{assisted_line}```. `CONTRIBUTING.md` documents the " + "format as `Assisted-by: AGENT_NAME:MODEL_VERSION " + "[TOOL1] [TOOL2]` (e.g. " + "`Assisted-by: Claude:claude-opus-4-7 coccinelle`)." + ) + continue + # Split off the optional tool list (everything after AGENT:VERSION). + parts = assisted_line.split(None, 2) + if len(parts) < 3: + continue + basic_tools = ASSISTED_BY_BASIC_TOOL_RE.findall(parts[2]) + if basic_tools: + warn( + f"Commit {commit.sha} lists basic development tool(s) " + f"({', '.join(basic_tools)}) in its `Assisted-by` trailer. " + "Per `CONTRIBUTING.md`, basic dev tools (git, compilers, " + "build systems, editors, formatters, generic linters, " + "etc.) should not be listed. Only specialized analysis " + "tools (e.g. coccinelle, clang-tidy, AFL, Coverity) " + "belong in the trailer." + ) match = MR_TITLE_RE.match(subject) if match and match.group(5) is not None and not is_merge: fail(