diff --git a/.github/workflows/proposal-numbering.yml b/.github/workflows/proposal-numbering.yml
new file mode 100644
index 0000000..2110a1a
--- /dev/null
+++ b/.github/workflows/proposal-numbering.yml
@@ -0,0 +1,171 @@
+#
+# Copyright Kroxylicious Authors.
+#
+# Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+#
+
+# Automatically checks that proposal files follow the PR-number naming convention (e.g., proposals/092-my-proposal.md for PR #92).
+# When a proposal file doesn't match its PR number, this workflow updates the PR description with instructions to rename it.
+# Once the author fixes the naming, the warning is automatically removed from the PR description.
+
+name: Check Proposal Numbering
+
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+ paths:
+ - 'proposals/*.md'
+
+permissions:
+ pull-requests: write
+ contents: read
+
+jobs:
+ check-numbering:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ with:
+ fetch-depth: 0
+
+ - name: Check proposal file numbering
+ id: check
+ env:
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ run: |
+ # Find all .md files directly in proposals directory (not subdirectories)
+ ALL_PROPOSAL_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '^proposals/[^/]*\.md$' || true)
+
+ # Filter out non-proposal files (README.md and template)
+ PROPOSAL_FILES=""
+ for file in $ALL_PROPOSAL_FILES; do
+ # Skip README.md and the template
+ if [[ "$file" == "proposals/README.md" ]] || [[ "$file" == "proposals/000-template.md" ]]; then
+ continue
+ fi
+ PROPOSAL_FILES="$PROPOSAL_FILES $file"
+ done
+
+ if [ -z "$PROPOSAL_FILES" ]; then
+ echo "No proposal files found in this PR"
+ echo "has_proposal=false" >> $GITHUB_OUTPUT
+ exit 0
+ fi
+
+ echo "has_proposal=true" >> $GITHUB_OUTPUT
+
+ # Expected filename pattern: proposals/0{PR_NUMBER}-*.md
+ EXPECTED_PREFIX=$(printf "proposals/%03d-" $PR_NUMBER)
+
+ INCORRECT_FILES=""
+ for file in $PROPOSAL_FILES; do
+ if [[ ! "$file" =~ ^${EXPECTED_PREFIX} ]]; then
+ if [ -z "$INCORRECT_FILES" ]; then
+ INCORRECT_FILES="$file"
+ else
+ INCORRECT_FILES="$INCORRECT_FILES,$file"
+ fi
+ fi
+ done
+
+ if [ -n "$INCORRECT_FILES" ]; then
+ echo "incorrect=true" >> $GITHUB_OUTPUT
+ echo "files=$INCORRECT_FILES" >> $GITHUB_OUTPUT
+ echo "expected_prefix=$EXPECTED_PREFIX" >> $GITHUB_OUTPUT
+ else
+ echo "incorrect=false" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Update PR description if numbering is incorrect
+ if: steps.check.outputs.incorrect == 'true'
+ uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
+ with:
+ script: |
+ const prNumber = context.payload.pull_request.number;
+ const expectedPrefix = '${{ steps.check.outputs.expected_prefix }}';
+ const incorrectFilesRaw = '${{ steps.check.outputs.files }}';
+
+ // Format files as markdown list
+ const filesList = incorrectFilesRaw.split(',').map(f => `- ${f}`).join('\n');
+
+ const warningSection = [
+ '---',
+ '',
+ '## ⚠️ Proposal File Numbering',
+ '',
+ 'This PR contains proposal files that don\'t follow the expected numbering scheme:',
+ '',
+ filesList,
+ '',
+ `**Expected naming:** ${expectedPrefix}<descriptive-name>.md`,
+ '',
+ `Please rename your proposal file to use PR #${prNumber}:`,
+ '',
+ '```bash',
+ `git mv proposals/000-.md ${expectedPrefix}.md`,
+ '# or rename from current name to correct name',
+ `git commit -m "Rename proposal to use PR number ${prNumber}"`,
+ 'git push',
+ '```',
+ '',
+ 'See [proposals/README.md](https://github.com/kroxylicious/design/blob/main/proposals/README.md) for the complete workflow.',
+ '',
+ ''
+ ].join('\n');
+
+ // Get current PR
+ const { data: pr } = await github.rest.pulls.get({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: prNumber,
+ });
+
+ let currentBody = pr.body || '';
+
+ // Remove existing warning section if present
+ const markerRegex = /---\s*\n\s*##\s*⚠️\s*Proposal File Numbering[\s\S]*?/;
+ currentBody = currentBody.replace(markerRegex, '').trim();
+
+ // Append new warning section
+ const newBody = currentBody + '\n' + warningSection;
+
+ await github.rest.pulls.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: prNumber,
+ body: newBody
+ });
+
+ - name: Remove warning from PR description if numbering is correct
+ if: steps.check.outputs.has_proposal == 'true' && steps.check.outputs.incorrect == 'false'
+ uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
+ with:
+ script: |
+ const prNumber = context.payload.pull_request.number;
+
+ // Get current PR
+ const { data: pr } = await github.rest.pulls.get({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: prNumber,
+ });
+
+ let currentBody = pr.body || '';
+
+ // Check if warning section exists
+ const markerRegex = /---\s*\n\s*##\s*⚠️\s*Proposal File Numbering[\s\S]*?/;
+
+ if (markerRegex.test(currentBody)) {
+ // Remove warning section
+ const newBody = currentBody.replace(markerRegex, '').trim();
+
+ await github.rest.pulls.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: prNumber,
+ body: newBody
+ });
+
+ console.log('Removed numbering warning from PR description - file is now correctly named');
+ }
diff --git a/notify-open-prs.sh b/notify-open-prs.sh
new file mode 100755
index 0000000..f930097
--- /dev/null
+++ b/notify-open-prs.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+#
+# Copyright Kroxylicious Authors.
+#
+# Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+#
+
+# Script to notify authors of open proposal PRs to rebase on main
+# Once they rebase, the workflow will automatically check their proposal numbering
+
+set -e
+
+OPEN_PRS=(70 82 83 85 88 93 94)
+
+COMMENT_BODY="Hi! We've updated the proposal numbering system to use PR numbers as proposal identifiers.
+
+**Action required:** Please rebase your PR on \`main\`.
+
+Once you push, the GitHub workflow will automatically check your proposal file naming and update this PR description with specific instructions if your file needs to be renamed.
+
+See [proposals/README.md](https://github.com/kroxylicious/design/blob/main/proposals/README.md) for the updated workflow."
+
+echo "This script will comment on ${#OPEN_PRS[@]} open proposal PRs"
+echo ""
+read -p "Continue? (y/N) " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ echo "Aborted"
+ exit 1
+fi
+
+for pr in "${OPEN_PRS[@]}"; do
+ echo "Commenting on PR #$pr..."
+ gh pr comment "$pr" --body "$COMMENT_BODY"
+ echo "✓ PR #$pr notified"
+ sleep 2 # Be nice to the API
+done
+
+echo ""
+echo "✓ All open proposal PRs have been notified"
+echo ""
+echo "Once authors rebase, the workflow will automatically:"
+echo " 1. Detect if their proposal file naming is incorrect"
+echo " 2. Update their PR description with the exact command to fix it"
+echo " 3. Remove the warning once they fix the naming"
diff --git a/proposals/000-template.md b/proposals/000-template.md
index 538db1e..0088dc7 100644
--- a/proposals/000-template.md
+++ b/proposals/000-template.md
@@ -1,7 +1,21 @@
-
+
#
+**Proposal**: #
+
Provide a brief summary of the feature you are proposing to add to Kroxylicious.
## Current situation
diff --git a/proposals/README.md b/proposals/README.md
new file mode 100644
index 0000000..48ded65
--- /dev/null
+++ b/proposals/README.md
@@ -0,0 +1,37 @@
+# Kroxylicious Proposals
+
+This directory contains proposals for the Kroxylicious project.
+
+## Creating a New Proposal
+
+1. **Create your proposal file** using a placeholder name based on the [template](./000-template.md):
+ ```
+ proposals/000-.md
+ ```
+
+2. **Commit and open a Pull Request**:
+ - Push your branch and open a PR on GitHub
+ - Note your PR number (e.g., #105)
+
+3. **Rename the file** to use your PR number (three-digit zero-padded):
+ ```bash
+ git mv proposals/000-.md proposals/105-.md
+ git commit -m "Rename proposal to use PR number"
+ git push
+ ```
+
+4. **Announce** your proposal on the [mailing list](https://kroxylicious.io/join-us/mailing-lists/)
+
+When your proposal is **accepted and merged**, the proposal number remains the same as the PR number.
+
+## Finding Proposals
+
+- **All proposals:** Browse the directory listing above
+- **Open proposals:** [View open proposal PRs](https://github.com/kroxylicious/design/pulls?q=is%3Apr+is%3Aopen+label%3Aproposal)
+- **Merged proposals:** Proposal files in this directory (sorted alphabetically)
+
+## Numbering
+
+Proposal numbers match PR numbers, using three-digit zero-padding (e.g., `092-`, `105-`).
+
+Proposals 001-019 predate this system and retain their original numbers.