Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 8 additions & 1 deletion .github/pull-request-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,11 @@

**Related issue(s)**
<!-- If you refer to a particular issue, provide its number, othewise, remove this section.
For example, `Resolves #123`, `Fixes #43`, or `See also #33`. The 3rd option will not automatically close the issue after the merge. -->
For example, `Resolves #123`, `Fixes #43`, or `See also #33`. The 3rd option will not automatically close the issue after the merge. -->

**AI assistance**
<!-- See our AI Usage Policy: https://github.com/asyncapi/generator/blob/master/AI-POLICY.md
Check exactly one box. If this PR was materially AI-assisted, keep the Generated-by line and fill in the tool + version. -->

- [ ] This PR was created with AI assistance — `Generated-by:` <!-- e.g. Generated-by: Claude Code 1.x -->
- [ ] No AI assistance was used
99 changes: 99 additions & 0 deletions .github/workflows/verify-ai-disclosure.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Purpose of this workflow is to enforce the AI Usage Policy (AI-POLICY.md):
# every pull request must declare whether it was AI-assisted, either by providing
# a non-empty `Generated-by:` line or by checking the "No AI assistance" box.
# This verifies that a declaration is PRESENT - it cannot verify its truthfulness.
#
# Why pull_request_target instead of pull_request: the check must be able to post a
# comment on pull requests opened from forks, and the plain `pull_request` event only
# grants a read-only token for forks.
#
# Security: this is hardened against the classic PR-body script-injection vector.
# - No `${{ }}` expression interpolation: the body is read at runtime as a JS value
# via context.payload.pull_request.body, never substituted into code.
# - The body is treated purely as data (regex/string ops); never eval'd, shelled,
# or passed to a `run:` step.
# - pull_request_target is safe because there is NO checkout - PR code is never
# fetched or executed, so the write-scoped token is never exposed to it.
# - The failure comment is static text and does not echo back the PR body.
# - Token is scoped to `pull-requests: write` only.
name: Verify AI disclosure

on:
pull_request_target:
types:
- opened
- edited
- reopened
- synchronize

permissions:
pull-requests: write

jobs:
verify-ai-disclosure:
runs-on: ubuntu-latest
steps:
- name: Check PR body for AI-assistance disclosure
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
script: |
const MARKER = '<!-- ai-disclosure-check -->';
const policyUrl = 'https://github.com/asyncapi/generator/blob/master/AI-POLICY.md';
const body = context.payload.pull_request.body || '';
// Strip HTML comments so example text inside <!-- --> doesn't count as a real declaration.
const stripped = body.replace(/<!--[\s\S]*?-->/g, '');

const noAiChecked = /- \[x\]\s*No AI assistance/i.test(stripped);

// Match only horizontal whitespace after the colon so an empty
// `Generated-by:` line does not swallow the following line as its value.
const values = [...stripped.matchAll(/Generated-by:[ \t]*([^\n]*)/gi)]
.map(m => m[1].replace(/`/g, '').trim())
.filter(v => v.length > 0);
const generatedByValue = values[0] || '';
const hasGeneratedBy = values.length > 0;

const { owner, repo } = context.repo;
const issue_number = context.payload.pull_request.number;

// Find a previous comment from this check so we update/remove it instead of spamming.
const comments = await github.paginate(github.rest.issues.listComments, {
owner, repo, issue_number, per_page: 100,
});
const existing = comments.find(c => (c.body || '').includes(MARKER));

if (noAiChecked || hasGeneratedBy) {
core.info(
hasGeneratedBy
? `AI assistance disclosed: Generated-by: ${generatedByValue}`
: 'Declared: no AI assistance used.'
);
// PR is now compliant - clean up any earlier failure comment.
if (existing) {
await github.rest.issues.deleteComment({ owner, repo, comment_id: existing.id });
}
return;
}

const message = [
MARKER,
'### ⚠️ Missing AI-assistance disclosure',
'',
`Per our [AI Usage Policy](${policyUrl}), every pull request must declare whether generative AI assisted in creating it. Please **edit this PR description** to do one of the following:`,
'',
'- If AI assisted, add a line naming the tool and version, for example:',
' ```',
' Generated-by: Claude Code 1.x',
' ```',
'- If no AI was used, check the **"No AI assistance was used"** box in the PR template.',
'',
'This check re-runs whenever you edit the description, and this comment will disappear once a declaration is present. Note that it confirms a declaration *exists* — it does not verify its accuracy; you remain accountable for everything you submit.',
].join('\n');

if (existing) {
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body: message });
} else {
await github.rest.issues.createComment({ owner, repo, issue_number, body: message });
}

core.setFailed(`Missing AI-assistance disclosure. See ${policyUrl}`);
57 changes: 57 additions & 0 deletions AI-POLICY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# AI Usage Policy

This policy governs the use of generative AI and AI-assisted tooling (LLMs, coding agents, autocomplete assistants, and similar) when contributing to this repository.

> **AI tools are instruments; humans are the only authors.**

You may use AI tools to help you contribute. But the moment you open a pull request or an issue, **you** are the author of every line in it. The tool is not a co-maintainer, it is not accountable, and it cannot be cited as an excuse. This policy exists so that AI accelerates good contributions without lowering the bar for quality, security, or trust.

This is a contributor-facing policy. It is **not** the same as [`AGENTS.md`](AGENTS.md): that file instructs coding agents on *how to write code that fits this repository*, whereas this policy defines *the rules and expectations for humans who use AI to contribute here*.

## When this applies

This policy applies to **any** contribution where a generative AI tool materially assisted in producing the content, including:

- source code, tests, and configuration,
- documentation and template content,
- issue descriptions, and
- review comments.

If you only used AI for spell-checking, search, or to understand existing code, disclosure is not required. If AI generated or substantially shaped the content you are submitting, it is.

## Your responsibilities as a contributor

Before you submit AI-assisted work, you must:

1. **Review it thoroughly.** Read and understand every part of the contribution. If you do not understand it, do not submit it.
2. **Verify quality.** Ensure it meets this project's standards — it builds, tests pass, and it follows the conventions in [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`AGENTS.md`](AGENTS.md).
3. **Remove extraneous changes.** Strip out unrelated edits, dead code, speculative abstractions, and noise the tool introduced. Keep the diff focused.
4. **Be prepared to explain it.** You must be able to justify any part of the contribution if a maintainer asks. "The AI wrote it" is not an answer.
5. **Accept responsibility.** You bear full accountability for the contribution, exactly as if you had written every line by hand.
6. **Check licensing.** Confirm that generated material does not reproduce code under incompatible licenses and does not violate this project's [license](LICENSE).

> Blindly copy-pasting AI output introduces security and stability risks. Maintainers may close such pull requests without review.

## Required disclosure

If a contribution was materially AI-assisted, you **must** disclose it:

- **Pull requests:** include a `Generated-by:` line in the PR description naming the tool and its version, for example:

```
Generated-by: Claude Code 1.x
Generated-by: GitHub Copilot
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

The pull request template carries a dedicated AI-assistance section — fill in the `Generated-by:` line, or check the "no AI assistance" box if it does not apply. A CI check verifies that one of the two is present; it confirms a declaration exists, it does not and cannot verify its truthfulness.

- **Issues:** note in the issue body that AI assisted in drafting it.

Disclosure is a sign of good faith, not an admission of wrongdoing. We welcome AI-assisted contributions that follow this policy.

## Consequences

- Maintainers may **close non-compliant pull requests without review**, including undisclosed AI-generated PRs and PRs the contributor cannot explain.
- **Repeated violations** are treated as a breach of our [Code of Conduct](CODE_OF_CONDUCT.md) and may result in the contributor being blocked.

If you are unsure whether something falls under this policy, ask a maintainer in the `#generator` channel on [AsyncAPI Slack](https://www.asyncapi.com/slack-invite) before submitting.
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ We love your input! We want to make contributing to this project as easy and tra
- [Issues](#issues)
- [Bug Reports and Feature Requests](#bug-reports-and-feature-requests)
- [Pull Requests](#pull-requests)
- [AI-Assisted Contributions](#ai-assisted-contributions)
- [Conventional Commits](#conventional-commits)
- [Maintainer Roles](#maintainer-roles)
- [Triager](#triager)
Expand Down Expand Up @@ -105,6 +106,14 @@ Please use our issues templates that provide you with hints on what information

**Please, make sure you open an issue before starting with a Pull Request, unless it's a typo or a really obvious error.** Pull requests are the best way to propose changes to the specification. Get familiar with our document that explains [Git workflow](https://github.com/asyncapi/community/blob/master/docs/010-contribution-guidelines/git-workflow.md) used in our repositories.

## AI-Assisted Contributions

You may use generative AI and AI-assisted tooling to help you contribute, but you remain the author of and are fully accountable for everything you submit. Before submitting AI-assisted work, review it thoroughly, verify it meets our standards, remove unrelated changes, and confirm it does not violate any licenses.

If a contribution was materially AI-assisted, you **must** disclose it: add a `Generated-by: <tool + version>` line to your pull request description (the PR template includes a dedicated section), or check the "No AI assistance" box. A CI check verifies that one of the two is present.
Comment thread
Adi-204 marked this conversation as resolved.
Outdated

Read the full [AI Usage Policy](AI-POLICY.md) for details, including the functions that are off-limits for automation.

## Conventional Commits

Our repositories follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification. Releasing to GitHub and NPM is done with the support of [semantic-release](https://semantic-release.gitbook.io/semantic-release/).
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ For the development setup, you can follow the detailed guide in [Development gui

Read [CONTRIBUTING](CONTRIBUTING.md) guide.

If you use generative AI or AI-assisted tooling when contributing, read our [AI Usage Policy](AI-POLICY.md) first.

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
Expand Down
Loading