Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ drupalorg skill:install

Both methods install a discovery stub into `.claude/skills/drupalorg-cli/`. The stub tells agents to call `drupalorg skill:get` for current instructions, so skills never go stale between releases.

The skills build in Drupal.org's [policy on the use of AI when contributing](https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquette/policy-on-the-use-of-ai-when-contributing-to-drupal): agents are told to read the issue thread before writing code, keep diffs minimal, pass the MR pipeline before handing off, never push to someone else's MR unannounced, and draft the required `AI-Generated: Yes (...)` disclosure for you. You remain responsible for everything you submit.

### Available skills

| Skill | Description |
Expand Down
26 changes: 26 additions & 0 deletions skill-data/drupalorg-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,31 @@ Some Drupal.org projects have migrated their issue queues to GitLab work items
at `git.drupalcode.org`. These projects are detected automatically — `project:issues`
fetches from the GitLab API instead of Drupal.org for them.

## Contribution Policy

Drupal.org's [policy on the use of AI when contributing](https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquette/policy-on-the-use-of-ai-when-contributing-to-drupal)
applies to every change made through this CLI. The user is the contributor and
answers for everything pushed or posted. Non-negotiables for agents:

- **Read the thread first.** Run `issue:show <nid> --with-comments --format=llm`
and `mr:list <nid> --state=all --format=llm` before proposing a change. Respect
prior attempts and settled architectural decisions.
- **Minimal, explainable diffs.** No out-of-scope refactors, no unverified
dependencies. The user must be able to explain every line to a reviewer.
- **Green before hand-off.** Run local checks, push, poll `mr:status`, fix
`mr:logs` failures. Never leave a failing MR for others.
- **Never push to someone else's MR** without their knowledge and a disclosed
comment. Check the `author` field in `mr:list` output.
- **Disclose.** When AI produced entire functions, classes, scaffolding, or long
doc blocks, draft an `AI-Generated: Yes (...)` line for the MR description or
comment and confirm the user added it.
- **The user's own words.** Summaries, comments, and reviews are drafts for the
user to edit and shorten, never text to paste verbatim.
- **Stay responsive.** Remind the user that follow-up feedback needs a human
answer. Drive-by contributions lead to account bans.

The full checklist is in `references/ai-contribution-policy.md`.

### Work item references

`issue:show`, `issue:get-fork`, and `mr:list` all accept a **WorkItemRef** in
Expand Down Expand Up @@ -247,6 +272,7 @@ drupalorg mr:list [nid] --format=llm --no-cache

Detailed workflow guides are in the `references/` directory alongside this file:

- `references/ai-contribution-policy.md` — Drupal.org AI contribution policy checklist (read the thread, verify, disclose)
- `references/work-on-issue.md` — End-to-end GitLab MR workflow ("Work on this issue")
- `references/patch-contribution.md` — Classic patch-based contribution workflow
- `references/gitlab-mr-contribution.md` — GitLab MR contribution workflow reference
128 changes: 128 additions & 0 deletions skill-data/drupalorg-cli/references/ai-contribution-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Drupal.org AI Contribution Policy — Agent Checklist

Drupal.org has a policy on the use of AI when contributing:
https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquette/policy-on-the-use-of-ai-when-contributing-to-drupal

The policy binds the human contributor, not the tool. When an agent drives
`drupalorg`, the user is the contributor and answers for every line pushed and
every word posted. Violations lead to temporary or permanent Drupal.org account
bans. Follow this checklist in every workflow that produces code or text for
Drupal.org.

---

## Before writing anything: read the thread

Dumping code into an issue without reading the discussion is the first pattern
the policy names as unacceptable.

```bash
drupalorg issue:show <nid> --with-comments --format=llm
drupalorg mr:list <nid> --state=all --format=llm
```

`--with-comments` only returns comments for classic Drupal.org issues. For GitLab
work items, read the discussion with `glab` or ask the user to summarize it:

```bash
GITLAB_HOST=git.drupalcode.org glab issue view <nid> --comments --repo project/<name>
```

From that output, report to the user before proposing a change:

- Previous attempts (patches, MRs, closed MRs) and why they stalled.
- Architectural conclusions reached in the comments. Do not reopen them.
- Who authored the existing MR. The `author` field in `mr:list` output tells you.

Do not propose a rewrite of a module or a change of direction based on your own
review. That requires the user to engage the maintainers in the issue first.

---

## While writing: keep the user able to explain every change

"The AI wrote it" is grounds for closing the contribution. The user must be able
to answer a reviewer's question about any line. Work so that stays true:

- **Minimal diff.** Change what the issue asks for. No drive-by refactors,
renames, formatting sweeps, or "improvements" outside scope.
- **No unverified dependencies.** Do not add a Composer package, npm package, or
core service unless you confirmed it exists and the user agreed to the
dependency. Hallucinated packages are a supply-chain risk.
- **Security and licensing.** Flag anything that touches input handling, access
checks, or output escaping so the user reviews it deliberately. Flag code you
suspect reproduces another project verbatim. Everything must be GPL-compatible.
- **Explain as you go.** When presenting a change, state what it does and why in
terms the user can repeat in the issue. If you cannot explain it, do not push it.

---

## Before pushing or uploading: verify

The policy names "posting an MR where automated checks fail and leaving it for
others to fix" as unacceptable. Verification is the user's job, so do it before
the user is asked to stand behind the work.

- Run the project's coding standards and tests locally when available
(`vendor/bin/phpcs`, `vendor/bin/phpunit`, `vendor/bin/phpstan`).
- Push only when local checks pass. After pushing, poll the pipeline and fix
failures before handing off:
```bash
drupalorg mr:status <nid> <mr-iid> --format=llm
drupalorg mr:logs <nid> <mr-iid>
```
- Never push to an MR the user did not author without the author's knowledge.
If `mr:list` shows a different author, stop and ask the user to confirm they
coordinated in the issue. The push must be disclosed in a comment.

---

## When handing off: disclose

Disclosure is mandatory whenever AI generated a significant portion of the
submission: entire functions, classes, architectural scaffolding, or extensive
documentation blocks. Reviewing the output thoroughly does not remove the
obligation. Single-line autocomplete and syntax fixes do not need disclosure.

Draft the disclosure line for the user and tell them where it goes:

1. If the project's issue or MR template has an AI disclosure section, use it.
2. Otherwise append a short, human-written statement to the end of the MR
description, issue summary, or comment:

```
AI-Generated: Yes (Claude Code drafted the FooService::bar() implementation and its tests; I reviewed and ran them locally).
```

Name the tool and what it produced. Keep it to one sentence. `drupalorg` cannot
post comments or edit MR descriptions on Drupal.org, so hand the text to the user
and confirm they added it before marking the issue "Needs review".

---

## Issue summaries, comments, and reviews: the user's own words

Verbose AI prose is a burden on maintainers. Anything the user posts must be:

- **Written in their own words.** Give the user a draft to edit, never text to
paste unchanged. Say so explicitly when you hand it over.
- **Concise.** Cut background the thread already contains. Lead with the
decision or question.
- **Independently verified.** An AI summary of a thread posted to gain issue
credit is a policy violation. Only propose summary updates that add technical
insight the user checked.
- **Attached when long.** When the full generated output is genuinely useful,
attach it as a file instead of pasting it into a comment.

---

## After handing off: stay responsive

A drive-by contribution that ignores follow-up feedback is grounds for a ban,
with or without AI. When you finish a work loop, remind the user that reviewers
may ask questions they must answer themselves, and offer to re-fetch the issue
later:

```bash
drupalorg issue:show <nid> --with-comments --format=llm --no-cache
```
17 changes: 16 additions & 1 deletion skill-data/drupalorg-cli/references/gitlab-mr-contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Reference guide for contributing to Drupal.org issues via GitLab merge requests.

Merge requests fall under Drupal.org's
[AI contribution policy](https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquette/policy-on-the-use-of-ai-when-contributing-to-drupal).
See `ai-contribution-policy.md` in this directory before pushing.

---

## Initial Setup
Expand Down Expand Up @@ -57,8 +61,12 @@ Branch names follow the convention `<nid>-<short_slug>`, e.g. `3001234-fix_cache

## Making Changes

Read the issue thread first (`issue:show <nid> --with-comments --format=llm`)
and check the MR `author` in `mr:list` output. Pushing to an MR the user did
not author requires the author's knowledge and a disclosing comment.

```bash
# Edit files, then stage and commit
# Edit files, run local checks (phpcs, phpunit, phpstan), then stage and commit
git add -p
git commit -m "Issue #<nid> by <username>: <short description>"

Expand All @@ -69,6 +77,13 @@ git push
Pushing to a tracking branch automatically updates the existing MR on GitLab.
No separate MR update step is needed.

When AI generated entire functions, classes, scaffolding, or long documentation
blocks, the MR description needs a disclosure before review is requested:

```
AI-Generated: Yes (Claude Code drafted <what>; I reviewed and tested it).
```

---

## Monitoring the MR
Expand Down
22 changes: 18 additions & 4 deletions skill-data/drupalorg-cli/references/patch-contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
Classic patch contribution flow for Drupal.org issues that still use file
attachments (as opposed to GitLab merge requests).

Patches fall under Drupal.org's
[AI contribution policy](https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquette/policy-on-the-use-of-ai-when-contributing-to-drupal)
the same as merge requests. See `ai-contribution-policy.md` in this directory.

---

## Prepare a Patch

```bash
# 1. Fetch the issue to understand scope and current state
drupalorg issue:show <nid> --format=llm
# 1. Fetch the issue and its comments; read prior attempts before writing code
drupalorg issue:show <nid> --with-comments --format=llm

# 2. Create a local branch named after the issue
drupalorg issue:branch <nid>
Expand All @@ -19,11 +23,21 @@ drupalorg issue:branch <nid>
git add -p
git commit -m "Issue #<nid> by <username>: <short description>"

# 4. Generate the patch (diffs against the upstream tracking branch)
# 4. Run the project's local checks (phpcs, phpunit) and fix failures

# 5. Generate the patch (diffs against the upstream tracking branch)
drupalorg issue:patch [nid]
# Writes: <cleanTitle>-<nid>-<commentCount+1>.patch to the git repo root

# 5. Upload the patch file to the issue on drupal.org
# 6. Upload the patch file to the issue on drupal.org
```

The comment that carries the patch is written by the user in their own words.
When AI generated entire functions, classes, scaffolding, or long documentation
blocks in the patch, draft a disclosure line for the end of that comment:

```
AI-Generated: Yes (Claude Code drafted <what>; I reviewed and tested it).
```

`issue:patch` auto-detects the NID from the branch name when run without an
Expand Down
33 changes: 28 additions & 5 deletions skill-data/drupalorg-cli/references/work-on-issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
This guide describes the end-to-end workflow for an agent to pick up a Drupal.org
issue, set up the environment, and contribute via GitLab merge request.

Every push made through this workflow falls under Drupal.org's
[AI contribution policy](https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquette/policy-on-the-use-of-ai-when-contributing-to-drupal).
See `ai-contribution-policy.md` in this directory. In short: read the thread
before writing, keep diffs minimal and explainable, never leave a failing MR,
never push to someone else's MR unannounced, and disclose AI-generated code.

---

## Step 1: Verify the Issue Fork
Expand All @@ -25,14 +31,18 @@ whether to wait or open a fresh MR from the main project.

---

## Step 2: Verify Your Working Directory
## Step 2: Verify Your Working Directory and Read the Thread

Confirm your current directory matches the project for this issue.
Confirm your current directory matches the project for this issue, and read the
full discussion before planning any change.

```bash
drupalorg issue:show <nid> --format=llm
drupalorg issue:show <nid> --with-comments --format=llm
```

Note prior attempts and settled architectural decisions from the comments. Code
that ignores them is a policy violation.

The `<project>` field in the LLM output contains the project machine name
(e.g. `drupal`, `commerce`, `views`). Your `git remote get-url origin` should
resolve to a repository under that project name on git.drupal.org or GitLab.
Expand Down Expand Up @@ -93,8 +103,11 @@ drupalorg mr:logs <nid> <mr-iid>

### Make changes and push

Check the `author` field in the `mr:list` output first. Pushing to an MR the
user did not author requires the author's knowledge and a disclosing comment.

```bash
# Edit files as needed, then:
# Edit files as needed, run local checks (phpcs, phpunit, phpstan), then:
git add -p
git commit -m "Issue #<nid> by <username>: <short description>"
git push
Expand All @@ -113,7 +126,17 @@ drupalorg mr:status <nid> <mr-iid> --format=llm
drupalorg mr:logs <nid> <mr-iid>
```

Repeat the loop until the pipeline is green.
Repeat the loop until the pipeline is green. Do not hand off a failing MR.

### Disclose before requesting review

When AI generated entire functions, classes, scaffolding, or long documentation
blocks, the user must add a disclosure to the MR description before setting
"Needs review". Draft it for them:

```
AI-Generated: Yes (Claude Code drafted <what>; I reviewed and tested it).
```

---

Expand Down
21 changes: 18 additions & 3 deletions skill-data/drupalorg-issue-summary-update/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ Report to the user:

Ask: "Would you like me to draft an updated issue summary?"

**[POLICY]** Only proceed when the update adds technical insight the user has
verified. Drupal.org's
[AI contribution policy](https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquette/policy-on-the-use-of-ai-when-contributing-to-drupal)
names AI-generated thread summaries posted to gain issue credit as a violation.
If the current summary already matches the discussion, say so and stop.

---

### Step 2: Draft updated summary
Expand All @@ -64,8 +70,12 @@ If the user agrees, draft an updated issue summary that:
- Updates "Proposed resolution" to reflect the discussion consensus
- Updates "Remaining tasks" to match what is still outstanding
- Keeps "Problem/Motivation" unchanged unless comments clarify the problem itself
- Is shorter than the discussion it summarizes. Cut background the thread already
covers and lead with the decision.

Present the full updated summary text to the user.
Present the full updated summary text to the user as a draft to edit, not text to
paste. Say that explicitly. The policy requires summaries in the contributor's own
words and treats verbose AI prose as a burden on maintainers.

**[PAUSE]** Ask: "Does this look correct? Should I adjust anything before you
paste it into the issue?"
Expand All @@ -78,8 +88,13 @@ Once the summary is approved, instruct the user:

1. Open the issue: `drupalorg issue:link <nid>`
2. Click "Edit" on the issue node
3. Replace the "Summary" (body) field with the updated text
4. Save the issue
3. Rewrite the "Summary" (body) field from the draft in their own words
4. Append a disclosure at the end of the summary, for example:
```
AI-Generated: Yes (Claude Code drafted this summary update from the comment thread; I edited and verified it).
```
Use the issue template's AI disclosure section instead when one exists.
5. Save the issue

Note: drupalorg-cli is read-only and cannot write to Drupal.org directly.

Expand Down
Loading