diff --git a/docs/rfc/0011-github-releases.mdx b/docs/rfc/0011-github-releases.mdx
new file mode 100644
index 000000000..a746ca44f
--- /dev/null
+++ b/docs/rfc/0011-github-releases.mdx
@@ -0,0 +1,70 @@
+# RFC 0011: Auto-create versions from GitHub releases
+
+| Category | Status | Created | Author |
+| --- | --- | --- | --- |
+| Integrations | Draft | 2026-04-20 | Aditya Choudhari |
+
+**Issue:** [#993](https://github.com/ctrlplanedev/ctrlplane/issues/993)
+
+## Problem
+
+How do we know which Ctrlplane deployment a GitHub release belongs to?
+
+`owner/repo` alone fails for monorepos (e.g. `ctrlplanedev/deployments` produces releases for `wandb`, `shared-tenant`, `k8s`, etc.). Naming-convention approaches (`/v`) fight existing tools — release-please emits `-v`, changesets emits `@`, semantic-release emits `v`.
+
+## Proposal
+
+A single CEL selector on deployment metadata.
+
+```
+git/release-selector: "repository.full_name == 'ctrlplanedev/deployments' && changedPaths.exists(p, p.startsWith('wandb/'))"
+```
+
+### Flow
+
+1. `release` webhook hits `apps/api/src/routes/github/release.ts`.
+2. Verify signature, resolve installation.
+3. Build CEL context.
+4. For every deployment with `git/release-selector` in metadata, evaluate.
+5. Match → create deployment version with `release.tag_name` as the version.
+
+### CEL context
+
+```
+action: string
+release: ReleaseObject // webhook payload
+repository: RepositoryObject // webhook payload (topics, custom_properties included)
+sender: User // webhook payload
+
+previousTag: string | null // compare API
+changedPaths: string[] // compare API
+commits: { sha, message, author }[] // compare API
+```
+
+Only the bottom block requires an API call (`GET /repos/{o}/{r}/compare/{prev}...{tag}`).
+
+### Metadata keys
+
+| Key | Required | Purpose |
+| --- | --- | --- |
+| `git/release-selector` | yes | CEL returning bool |
+
+No `git/repo` key — repo check lives inside the selector.
+
+### GitHub App permissions
+
+- Metadata: Read
+- Contents: Read
+- Events: `Release`, `Installation`, `Installation repositories`
+
+### Error handling
+
+- Selector throws → log, skip deployment.
+- Compare API fails → evaluate without enriched fields (selectors referencing them evaluate false).
+- Zero matches → log + 200.
+
+## Out of scope (v1)
+
+- Selector prefilter / indexing
+- Draft / prerelease handling beyond what selectors express
+- Backfilling historical releases