diff --git a/plugins/agent-engineering-skills/.codex-plugin/plugin.json b/plugins/agent-engineering-skills/.codex-plugin/plugin.json
index dedd29524..bbdd96473 100644
--- a/plugins/agent-engineering-skills/.codex-plugin/plugin.json
+++ b/plugins/agent-engineering-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "agent-engineering-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Agent-system design, orchestration, scheduling, external-agent, and evaluation workflow skills.",
"author": {
"name": "Gale",
diff --git a/plugins/agent-engineering-skills/pyproject.toml b/plugins/agent-engineering-skills/pyproject.toml
index 39b5bb470..d66c545f0 100644
--- a/plugins/agent-engineering-skills/pyproject.toml
+++ b/plugins/agent-engineering-skills/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "agent-engineering-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
description = "Maintainer-only Python tooling baseline for agent-engineering-skills."
requires-python = ">=3.11"
dependencies = []
diff --git a/plugins/agent-engineering-skills/uv.lock b/plugins/agent-engineering-skills/uv.lock
index ddc06797c..152125509 100644
--- a/plugins/agent-engineering-skills/uv.lock
+++ b/plugins/agent-engineering-skills/uv.lock
@@ -4,7 +4,7 @@ requires-python = ">=3.11"
[[package]]
name = "agent-engineering-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]
diff --git a/plugins/agent-portability-skills/.codex-plugin/plugin.json b/plugins/agent-portability-skills/.codex-plugin/plugin.json
index 7cfbe22b9..c65714a4f 100644
--- a/plugins/agent-portability-skills/.codex-plugin/plugin.json
+++ b/plugins/agent-portability-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "agent-portability-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Skills for agent portability, ACP, A2A, Zed, Hermes, Codex plugin surfaces, and host adapter guidance.",
"author": {
"name": "Gale",
diff --git a/plugins/agent-portability-skills/pyproject.toml b/plugins/agent-portability-skills/pyproject.toml
index 9b1764f4c..179128148 100644
--- a/plugins/agent-portability-skills/pyproject.toml
+++ b/plugins/agent-portability-skills/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "agent-portability-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
description = "Maintainer-only Python tooling baseline for Agent Portability Skills."
requires-python = ">=3.11"
dependencies = []
diff --git a/plugins/agent-portability-skills/uv.lock b/plugins/agent-portability-skills/uv.lock
index ffd32ec78..503b7b457 100644
--- a/plugins/agent-portability-skills/uv.lock
+++ b/plugins/agent-portability-skills/uv.lock
@@ -8,7 +8,7 @@ resolution-markers = [
[[package]]
name = "agent-portability-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]
diff --git a/plugins/agentdeck/.codex-plugin/plugin.json b/plugins/agentdeck/.codex-plugin/plugin.json
index 6ac72af22..3108fc012 100644
--- a/plugins/agentdeck/.codex-plugin/plugin.json
+++ b/plugins/agentdeck/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "agentdeck",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Local Codex runtime utilities for thread, hook, and app-server workflows.",
"author": {
"name": "Gale",
diff --git a/plugins/android-dev-skills/.codex-plugin/plugin.json b/plugins/android-dev-skills/.codex-plugin/plugin.json
index 0f26059c4..7e8b51278 100644
--- a/plugins/android-dev-skills/.codex-plugin/plugin.json
+++ b/plugins/android-dev-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "android-dev-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Android, Kotlin, Java, Gradle, Android Gradle Plugin, testing, lint, UI implementation, and release-readiness workflow skills.",
"author": {
"name": "Gale",
diff --git a/plugins/apple-creator-studio-skills/.codex-plugin/plugin.json b/plugins/apple-creator-studio-skills/.codex-plugin/plugin.json
index 1f67dbf81..c1361aaf0 100644
--- a/plugins/apple-creator-studio-skills/.codex-plugin/plugin.json
+++ b/plugins/apple-creator-studio-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "apple-creator-studio-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Human-facing and Computer Use-aware Apple Creator Studio workflows for Final Cut Pro editing, Motion templates, Compressor delivery, Logic Pro production, MainStage concert preparation, and GarageBand projects.",
"author": {
"name": "Gale",
diff --git a/plugins/apple-dev-skills/.codex-plugin/plugin.json b/plugins/apple-dev-skills/.codex-plugin/plugin.json
index 852ac6f77..cb8c57045 100644
--- a/plugins/apple-dev-skills/.codex-plugin/plugin.json
+++ b/plugins/apple-dev-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "apple-dev-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Apple development workflows for Codex, including macOS privacy permissions, sandbox file access, entitlement diagnosis, virtualization, SwiftPM, Xcode, app extensions, media, provisioning, SwiftUI, AppKit, Safari, security, OpenAPI, and DocC.",
"author": {
"name": "Gale",
diff --git a/plugins/apple-dev-skills/pyproject.toml b/plugins/apple-dev-skills/pyproject.toml
index 9d8aa2f3a..ed51b5276 100644
--- a/plugins/apple-dev-skills/pyproject.toml
+++ b/plugins/apple-dev-skills/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "apple-dev-skills-maintainer"
-version = "9.31.1"
+version = "9.31.2"
description = "Maintainer tooling for the apple-dev-skills repository"
requires-python = ">=3.10"
dependencies = []
diff --git a/plugins/apple-dev-skills/uv.lock b/plugins/apple-dev-skills/uv.lock
index 9fd17523b..0ccf912cd 100644
--- a/plugins/apple-dev-skills/uv.lock
+++ b/plugins/apple-dev-skills/uv.lock
@@ -4,7 +4,7 @@ requires-python = ">=3.10"
[[package]]
name = "apple-dev-skills-maintainer"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]
diff --git a/plugins/cardhop-app/.codex-plugin/plugin.json b/plugins/cardhop-app/.codex-plugin/plugin.json
index 9998b35f9..c7955869c 100644
--- a/plugins/cardhop-app/.codex-plugin/plugin.json
+++ b/plugins/cardhop-app/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "cardhop-app",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Cardhop.app workflow guidance plus a bundled local MCP server for contact capture and updates on macOS.",
"author": {
"name": "Gale",
diff --git a/plugins/cardhop-app/mcp/pyproject.toml b/plugins/cardhop-app/mcp/pyproject.toml
index aa2d68e43..573ac51f1 100644
--- a/plugins/cardhop-app/mcp/pyproject.toml
+++ b/plugins/cardhop-app/mcp/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "cardhop-app-mcp"
-version = "9.31.1"
+version = "9.31.2"
requires-python = ">=3.13"
dependencies = [
"fastmcp>=3.0.2",
diff --git a/plugins/cardhop-app/mcp/uv.lock b/plugins/cardhop-app/mcp/uv.lock
index e9a647ba3..563f73a9b 100644
--- a/plugins/cardhop-app/mcp/uv.lock
+++ b/plugins/cardhop-app/mcp/uv.lock
@@ -141,7 +141,7 @@ wheels = [
[[package]]
name = "cardhop-app-mcp"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
dependencies = [
{ name = "fastmcp" },
diff --git a/plugins/cloud-deployment-skills/.codex-plugin/plugin.json b/plugins/cloud-deployment-skills/.codex-plugin/plugin.json
index dcce4031a..1b15852ba 100644
--- a/plugins/cloud-deployment-skills/.codex-plugin/plugin.json
+++ b/plugins/cloud-deployment-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "cloud-deployment-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Codex skills for routing cloud deployment work through official provider plugins, MCP servers, CLIs, and a reusable Dockerized-service release and deployment contract.",
"author": {
"name": "Gale",
diff --git a/plugins/cloud-inference-skills/.codex-plugin/plugin.json b/plugins/cloud-inference-skills/.codex-plugin/plugin.json
index 05cb55455..420465281 100644
--- a/plugins/cloud-inference-skills/.codex-plugin/plugin.json
+++ b/plugins/cloud-inference-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "cloud-inference-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Cloud AI inference workflow skills for routing model serving, training, conversion, and GPU infrastructure work across Runpod, Hugging Face, AWS, Vast.ai, CoreWeave, and similar providers.",
"author": {
"name": "Gale",
diff --git a/plugins/codebase-understanding-skills/.codex-plugin/plugin.json b/plugins/codebase-understanding-skills/.codex-plugin/plugin.json
index 0ab46c424..dcda113ca 100644
--- a/plugins/codebase-understanding-skills/.codex-plugin/plugin.json
+++ b/plugins/codebase-understanding-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "codebase-understanding-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Code-path exploration, call-site tracing, and evidence-based codebase explanation skills.",
"author": {
"name": "Gale",
diff --git a/plugins/cybersecurity-skills/.codex-plugin/plugin.json b/plugins/cybersecurity-skills/.codex-plugin/plugin.json
index 6cd3042de..f449e0127 100644
--- a/plugins/cybersecurity-skills/.codex-plugin/plugin.json
+++ b/plugins/cybersecurity-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "cybersecurity-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Defensive cybersecurity, isolated Linux and macOS analysis labs, suspicious-content and malware analysis, macOS defense, vulnerability testing, pentesting, and incident response workflows.",
"skills": "./skills/",
"author": {
diff --git a/plugins/documentation-skills/.codex-plugin/plugin.json b/plugins/documentation-skills/.codex-plugin/plugin.json
index 8a1afd5a3..3429f4f11 100644
--- a/plugins/documentation-skills/.codex-plugin/plugin.json
+++ b/plugins/documentation-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "documentation-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Documentation maintenance skills for README, contributor, agent, API, accessibility, architecture, and roadmap surfaces.",
"author": {
"name": "Gale",
diff --git a/plugins/documentation-skills/pyproject.toml b/plugins/documentation-skills/pyproject.toml
index b3367d1b5..3666e1a41 100644
--- a/plugins/documentation-skills/pyproject.toml
+++ b/plugins/documentation-skills/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "documentation-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
description = "Maintainer-only Python tooling baseline for documentation-skills."
requires-python = ">=3.11"
dependencies = []
diff --git a/plugins/documentation-skills/uv.lock b/plugins/documentation-skills/uv.lock
index 96eccb85f..cac7c9671 100644
--- a/plugins/documentation-skills/uv.lock
+++ b/plugins/documentation-skills/uv.lock
@@ -57,7 +57,7 @@ wheels = [
[[package]]
name = "documentation-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]
diff --git a/plugins/dotnet-skills/.codex-plugin/plugin.json b/plugins/dotnet-skills/.codex-plugin/plugin.json
index a2178d5d3..b82500675 100644
--- a/plugins/dotnet-skills/.codex-plugin/plugin.json
+++ b/plugins/dotnet-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "dotnet-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Codex skills for choosing, bootstrapping, building, testing, packaging, diagnosing, and maintaining .NET projects, including F# web applications, with F# and C# as equal first-party languages.",
"author": {
"name": "Gale",
diff --git a/plugins/game-dev-skills/.codex-plugin/plugin.json b/plugins/game-dev-skills/.codex-plugin/plugin.json
index c1b720dbc..9c48e6911 100644
--- a/plugins/game-dev-skills/.codex-plugin/plugin.json
+++ b/plugins/game-dev-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "game-dev-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Apple platform game development workflow skills for native Metal rendering, Game Porting Toolkit routing, MetalFX, GPU asset streaming, neural rendering, frameworks, input, haptics, and profiling.",
"author": {
"name": "Gale",
diff --git a/plugins/messaging-collaboration-skills/.codex-plugin/plugin.json b/plugins/messaging-collaboration-skills/.codex-plugin/plugin.json
index 3df135452..050958fe6 100644
--- a/plugins/messaging-collaboration-skills/.codex-plugin/plugin.json
+++ b/plugins/messaging-collaboration-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "messaging-collaboration-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Codex workflows for chat apps, bots, collaboration, iMessage, Apple notifications and Push to Talk, VoIP, and default communication-app planning.",
"author": {
"name": "Gale",
diff --git a/plugins/model-lab-skills/.codex-plugin/plugin.json b/plugins/model-lab-skills/.codex-plugin/plugin.json
index ee61cf883..0741b10d9 100644
--- a/plugins/model-lab-skills/.codex-plugin/plugin.json
+++ b/plugins/model-lab-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "model-lab-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Reproducible model training, evaluation, intervention, and runtime research workflows.",
"author": {
"name": "Gale"
diff --git a/plugins/network-protocol-skills/.codex-plugin/plugin.json b/plugins/network-protocol-skills/.codex-plugin/plugin.json
index e3433085f..33967a76c 100644
--- a/plugins/network-protocol-skills/.codex-plugin/plugin.json
+++ b/plugins/network-protocol-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "network-protocol-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Codex skills for choosing, planning, implementing, and diagnosing modern application transports and real-time networking protocols, including QUIC, HTTP/3, WebRTC, Media over QUIC, WebTransport-adjacent handoffs, protocol maturity checks, and stack-specific implementation routing.",
"author": {
"name": "Gale",
diff --git a/plugins/professional-skills/.codex-plugin/plugin.json b/plugins/professional-skills/.codex-plugin/plugin.json
index 27bea78bf..744b383f4 100644
--- a/plugins/professional-skills/.codex-plugin/plugin.json
+++ b/plugins/professional-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "professional-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Professional workflow skills for job search, career materials, and external professional services.",
"author": {
"name": "Gale",
diff --git a/plugins/professional-skills/pyproject.toml b/plugins/professional-skills/pyproject.toml
index 37234be66..cce7c5b6e 100644
--- a/plugins/professional-skills/pyproject.toml
+++ b/plugins/professional-skills/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "professional-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
description = "Maintainer-only Python tooling baseline for professional-skills."
requires-python = ">=3.11"
dependencies = []
diff --git a/plugins/professional-skills/uv.lock b/plugins/professional-skills/uv.lock
index 45e227c19..aba20bd35 100644
--- a/plugins/professional-skills/uv.lock
+++ b/plugins/professional-skills/uv.lock
@@ -40,7 +40,7 @@ wheels = [
[[package]]
name = "professional-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]
diff --git a/plugins/python-skills/.codex-plugin/plugin.json b/plugins/python-skills/.codex-plugin/plugin.json
index 3974653f4..17d14508f 100644
--- a/plugins/python-skills/.codex-plugin/plugin.json
+++ b/plugins/python-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "python-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Bundled Python-focused Codex skills for uv bootstrapping, project implementation, diagnostics, packaging, tooling, CI, upgrades, FastAPI service maintenance, FastMCP service maintenance, and testing workflows.",
"author": {
"name": "Gale",
diff --git a/plugins/python-skills/pyproject.toml b/plugins/python-skills/pyproject.toml
index 6f0c8dd13..e740d1b12 100644
--- a/plugins/python-skills/pyproject.toml
+++ b/plugins/python-skills/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "python-skills-maintainer"
-version = "9.31.1"
+version = "9.31.2"
description = "Maintainer tooling for the python-skills repository"
requires-python = ">=3.11"
dependencies = []
diff --git a/plugins/python-skills/uv.lock b/plugins/python-skills/uv.lock
index 128ec9db8..b756de26f 100644
--- a/plugins/python-skills/uv.lock
+++ b/plugins/python-skills/uv.lock
@@ -251,7 +251,7 @@ wheels = [
[[package]]
name = "python-skills-maintainer"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]
diff --git a/plugins/repository-skills/.codex-plugin/plugin.json b/plugins/repository-skills/.codex-plugin/plugin.json
index 39dac93e6..c107b86fd 100644
--- a/plugins/repository-skills/.codex-plugin/plugin.json
+++ b/plugins/repository-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "repository-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Repository operations, GitHub settings, worktree, validation, and release workflow skills.",
"author": {
"name": "Gale",
diff --git a/plugins/repository-skills/pyproject.toml b/plugins/repository-skills/pyproject.toml
index e07191e09..cecd28865 100644
--- a/plugins/repository-skills/pyproject.toml
+++ b/plugins/repository-skills/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "repository-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
description = "Maintainer-only Python tooling baseline for repository-skills."
requires-python = ">=3.11"
dependencies = []
diff --git a/plugins/repository-skills/skills/maintain-project-repo/SKILL.md b/plugins/repository-skills/skills/maintain-project-repo/SKILL.md
index bf31f85fc..69ae21a5a 100644
--- a/plugins/repository-skills/skills/maintain-project-repo/SKILL.md
+++ b/plugins/repository-skills/skills/maintain-project-repo/SKILL.md
@@ -70,7 +70,7 @@ Install or refresh the reusable `maintain-project-repo` toolkit inside a general
- use the selected profile's `sync-shared.sh` for repo-local shared sync tasks
- use the selected profile's `release.sh --mode standard --operation prepare` from a feature branch or worktree when protected `main` owns the final release line
- for remote CI, review bots, deployment, or GitHub indexing, consume the emitted continuation packet and first reuse the live matching host-native continuation while the gate remains pending and healthy; do not delete/recreate it for an unchanged snapshot. Codex uses a same-thread heartbeat and Hermes uses an updated continuable `cronjob` with `deliver="origin"` and `attach_to_session=true`; pause/delete only when the gate resolves, fails, is cancelled, or changes identity
- - on wakeup, run `--operation inspect` first; run `--operation advance` only if the branch, commit, PR, and tag identities still match the continuation packet. Treat pending review-bot status contexts such as CodeRabbit as a wait state, not permission to merge
+ - on wakeup, run `--operation inspect` first; run `--operation advance` only if the branch, commit, PR, and tag identities still match the continuation packet. Treat pending review-bot status contexts such as CodeRabbit as a wait state, not permission to merge, except when CodeRabbit explicitly reports that a quota, usage, rate, or review limit prevented it from producing a review; that diagnostic is non-blocking while every other check, finding, requested change, and comment remains gated
- use `scripts/repo-maintenance/release.sh --mode submodule` only when the repo is checked out as a submodule and the parent pointer update remains a separate follow-up
- treat SemVer tags with prerelease suffixes such as `vX.Y.Z-alpha.N`, `vX.Y.Z-beta.N`, `vX.Y.Z-rc.N`, or preview-style suffixes as GitHub prereleases; the release script passes `--prerelease` for those tags and rejects existing release objects whose prerelease metadata does not match the tag
- before claiming a release, publish, merge, or cleanup step is done, enumerate every local branch still not contained by the local base branch and account for each one as already preserved elsewhere, intentionally still in progress, newly archived, newly merged, or safe to delete
@@ -125,6 +125,7 @@ Install or refresh the reusable `maintain-project-repo` toolkit inside a general
- The generated GitHub Actions wrapper uses Node 24-compatible Actions versions, with `actions/checkout@v6.0.2` as the current validated floor. Newer stable official action versions are allowed and often preferred after checking release notes and running the relevant validation. Apple profiles report the runner-selected Xcode with shell commands instead of using the Node 20-based `maxim-lobanov/setup-xcode@v1` action.
- Standard release mode has bounded `prepare`, `inspect`, and `advance` operations. It never watches or polls remote state: it reuses a live matching host-native continuation while its gate is pending and healthy, creates/updates one only after it fires or becomes stale, resumes with `inspect`, and advances only after identity checks still match the packet. Every scheduled interval is at least five minutes.
- GitHub release creation preserves prerelease metadata for SemVer prerelease tags and fails clearly when an existing GitHub release object disagrees with the tag.
+- GitHub release creation prefers checked-in `docs/releases/vX.Y.Z.md` notes, then `docs/releases/X.Y.Z.md`; it logs and falls back to GitHub-generated notes only when neither file exists.
- Treat branch accounting as a hard completion gate for release and cleanup work, not as follow-up tidying. If `git branch --no-merged ` reports local branches after a merge, account for each branch explicitly before deleting anything or reporting the workflow complete.
- Recommend `bootstrap-swift-package` or `bootstrap-xcode-app-project` when the repo still needs to be created.
- Recommend `sync-swift-package-guidance` or `sync-xcode-project-guidance` when AGENTS alignment is still the missing baseline after `maintain-project-repo` is present.
diff --git a/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/lib/coderabbit.sh b/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/lib/coderabbit.sh
new file mode 100644
index 000000000..0ca7931df
--- /dev/null
+++ b/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/lib/coderabbit.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env sh
+
+# Return success only when CodeRabbit explicitly reports that a review could
+# not be produced because its quota, usage, or review limit was reached.
+coderabbit_review_is_unavailable() {
+ source_name="$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')"
+ message="$(printf '%s' "$2" | tr '[:upper:]' '[:lower:]')"
+
+ case "$source_name" in
+ *coderabbit*)
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+
+ case "$message" in
+ *quota*|*"usage limit"*|*"rate limit"*|*"review limit"*|*"limit reached"*)
+ return 0
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+}
diff --git a/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/lib/common.sh b/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/lib/common.sh
index b92b5ec89..5d740c46f 100755
--- a/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/lib/common.sh
+++ b/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/lib/common.sh
@@ -114,6 +114,38 @@ github_release_is_visible() {
gh release view "$tag_name" >/dev/null 2>&1
}
+checked_in_release_notes_file() {
+ tag_name="$1"
+ version_name="${tag_name#v}"
+
+ for candidate in \
+ "$REPO_ROOT/docs/releases/$tag_name.md" \
+ "$REPO_ROOT/docs/releases/$version_name.md"; do
+ if [ -f "$candidate" ]; then
+ printf '%s\n' "$candidate"
+ return 0
+ fi
+ done
+
+ return 1
+}
+
+create_github_release_from_notes_or_generated() {
+ tag_name="$1"
+ prerelease_flag="${2:-}"
+
+ if notes_file="$(checked_in_release_notes_file "$tag_name")"; then
+ log "Creating GitHub release $tag_name from checked-in notes: $notes_file."
+ # shellcheck disable=SC2086
+ gh release create "$tag_name" --verify-tag --notes-file "$notes_file" $prerelease_flag
+ return 0
+ fi
+
+ log "No checked-in release notes found for $tag_name; using GitHub-generated release notes."
+ # shellcheck disable=SC2086
+ gh release create "$tag_name" --verify-tag --generate-notes $prerelease_flag
+}
+
ensure_git_repo() {
git -C "$REPO_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1 || die "maintain-project-repo must run inside a git worktree rooted at $REPO_ROOT."
}
diff --git a/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/release.sh b/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/release.sh
index 5257bfa48..5999f0de0 100755
--- a/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/release.sh
+++ b/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/release.sh
@@ -4,6 +4,7 @@ set -eu
SELF_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
export REPO_MAINTENANCE_COMMON_DIR="$SELF_DIR/lib"
. "$SELF_DIR/lib/common.sh"
+. "$SELF_DIR/lib/coderabbit.sh"
load_profile_env
load_env_file "$SELF_DIR/config/release.env"
@@ -243,6 +244,37 @@ EOF
PR_NUMBER="$pr_number"
}
+detect_coderabbit_review_unavailable() {
+ pr_number="$1"
+ CODERABBIT_REVIEW_UNAVAILABLE="false"
+ CODERABBIT_UNAVAILABLE_COMMENT_COUNT=0
+
+ review_lines="$(gh pr view "$pr_number" --json comments,reviews --jq '[.comments[]?, (.reviews[]? | select(.state == "COMMENTED"))] | .[] | [(.author.login // ""), (.body // "")] | @tsv' 2>/dev/null || true)"
+ while IFS="$(printf '\t')" read -r source_name message; do
+ [ -n "${source_name:-}" ] || continue
+ if coderabbit_review_is_unavailable "$source_name" "$message"; then
+ CODERABBIT_REVIEW_UNAVAILABLE="true"
+ CODERABBIT_UNAVAILABLE_COMMENT_COUNT=$((CODERABBIT_UNAVAILABLE_COMMENT_COUNT + 1))
+ fi
+ done </dev/null || true)"
+ if [ -n "$repo_name" ] && [ -n "$head_sha" ]; then
+ check_lines="$(gh api "repos/$repo_name/commits/$head_sha/check-runs" --paginate --jq '.check_runs[]? | [(.name // ""), ((.output.title // "") + "\\n" + (.output.summary // "") + "\\n" + (.output.text // ""))] | @tsv' 2>/dev/null || true)"
+ while IFS="$(printf '\t')" read -r source_name message; do
+ [ -n "${source_name:-}" ] || continue
+ if coderabbit_review_is_unavailable "$source_name" "$message"; then
+ CODERABBIT_REVIEW_UNAVAILABLE="true"
+ fi
+ done </dev/null || printf 'UNREADABLE')"
COMMENT_COUNT="$(gh pr view "$pr_number" --json comments,reviews --jq '([.comments[]?, (.reviews[]? | select(.state == "COMMENTED"))] | length)' 2>/dev/null || printf '1')"
+ detect_coderabbit_review_unavailable "$pr_number"
+ if [ "$CODERABBIT_UNAVAILABLE_COMMENT_COUNT" -gt 0 ]; then
+ COMMENT_COUNT=$((COMMENT_COUNT - CODERABBIT_UNAVAILABLE_COMMENT_COUNT))
+ fi
+ EFFECTIVE_CHECK_BUCKETS="$CHECK_BUCKETS"
+ if [ "$CODERABBIT_REVIEW_UNAVAILABLE" = "true" ]; then
+ EFFECTIVE_CHECK_BUCKETS="$(gh pr checks "$pr_number" --json name,bucket --jq 'map(select(.bucket != "pending" or ((.name | ascii_downcase | contains("coderabbit")) | not)) | map(.bucket) | join(",")' 2>/dev/null || printf '%s' "$CHECK_BUCKETS")"
+ log "CodeRabbit reported that review is unavailable because a limit was reached; ignoring only its pending review context and diagnostic comments."
+ fi
if [ "$check_readable" != "true" ] || [ "$REVIEW_DECISION" = "UNREADABLE" ]; then
GATE_PHASE="awaiting-github-state"
elif [ "$check_count" -lt "$minimum_check_count" ]; then
GATE_PHASE="awaiting-github-state"
- elif case ",$CHECK_BUCKETS," in *,fail,*|*,cancel,*) true ;; *) false ;; esac; then
+ elif case ",$EFFECTIVE_CHECK_BUCKETS," in *,fail,*|*,cancel,*) true ;; *) false ;; esac; then
GATE_PHASE="failed-checks"
- elif case ",$CHECK_BUCKETS," in *,pending,*) true ;; *) false ;; esac; then
+ elif case ",$EFFECTIVE_CHECK_BUCKETS," in *,pending,*) true ;; *) false ;; esac; then
GATE_PHASE="awaiting-pr-checks"
elif [ "$REVIEW_DECISION" = "CHANGES_REQUESTED" ]; then
GATE_PHASE="changes-requested"
@@ -372,8 +413,7 @@ create_github_release() {
fi
prerelease_flag="$(github_release_create_prerelease_flag "$RELEASE_TAG")"
- # shellcheck disable=SC2086
- gh release create "$RELEASE_TAG" --verify-tag --generate-notes $prerelease_flag
+ create_github_release_from_notes_or_generated "$RELEASE_TAG" "$prerelease_flag"
log "Created GitHub release $RELEASE_TAG."
if ! github_release_is_visible "$RELEASE_TAG"; then
warn "GitHub release $RELEASE_TAG is not readable in this immediate re-read. Schedule a continuation for at least five minutes rather than polling."
diff --git a/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/release/40-github-release.sh b/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/release/40-github-release.sh
index 30051c401..e78221fe8 100755
--- a/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/release/40-github-release.sh
+++ b/plugins/repository-skills/skills/maintain-project-repo/assets/repo-maintenance/release/40-github-release.sh
@@ -28,8 +28,7 @@ if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
fi
prerelease_flag="$(github_release_create_prerelease_flag "$RELEASE_TAG")"
-# shellcheck disable=SC2086
-gh release create "$RELEASE_TAG" --verify-tag --generate-notes $prerelease_flag
+create_github_release_from_notes_or_generated "$RELEASE_TAG" "$prerelease_flag"
log "Created GitHub release $RELEASE_TAG."
github_release_is_visible "$RELEASE_TAG" || die "GitHub release $RELEASE_TAG is not readable in this immediate re-read. Do not poll; schedule a host-native continuation for at least five minutes, then re-run the release step."
verify_github_release_prerelease_metadata "$RELEASE_TAG"
diff --git a/plugins/repository-skills/skills/maintain-project-repo/references/automation-prompts.md b/plugins/repository-skills/skills/maintain-project-repo/references/automation-prompts.md
index c09595539..42a1f73b2 100644
--- a/plugins/repository-skills/skills/maintain-project-repo/references/automation-prompts.md
+++ b/plugins/repository-skills/skills/maintain-project-repo/references/automation-prompts.md
@@ -7,5 +7,6 @@
- Explain that standard release mode runs from a feature branch or worktree, opens a PR against protected `main`, takes bounded CI/review snapshots through `prepare`, `inspect`, and `advance`, gates on PR comments, merges, fast-forwards local `main`, creates and pushes the tag from that reviewed `main`, creates the GitHub release, accounts for every local branch not contained by `main`, and only then cleans up branches that are proven safe to delete.
- Explain that branch cleanup is gated by commit reachability: do not call work on `main`, merged, recovered, preserved, or safe to clean up until the exact local repository and remote prove it, and do not delete local branches, remote branches, worktrees, archive refs, or temporary rescue refs until any non-base history is merged or explicitly archived.
- Explain that standard release mode uses bounded `prepare`, `inspect`, and `advance` operations. For a remote gate, consume its continuation packet and reuse a live matching host-native wakeup while the gate remains pending and healthy; do not delete/recreate it after an unchanged snapshot. Create/update only after it fires or is stale, and pause/delete it when resolved, failed, cancelled, or identity-drifted. Every scheduled interval is at least five minutes. Run `inspect` first, and run `advance` only when packet identities still match. Codex uses heartbeat; Hermes uses a continuable `cronjob` with `deliver="origin"` and `attach_to_session=true`.
-- Explain that pending review-bot contexts such as CodeRabbit are not a clean merge signal. Codex should wake, inspect the review and comments, address valid findings, and only merge after the review/comment gate is clear.
+- Explain that pending review-bot contexts such as CodeRabbit are not a clean merge signal. Codex should wake, inspect the review and comments, address valid findings, and only merge after the review/comment gate is clear. An explicit CodeRabbit quota, usage, rate, or review-limit diagnostic is the narrow exception: it is non-blocking because no review was produced, while every other CodeRabbit finding, failed check, requested change, or comment remains blocking.
+- Explain that GitHub release creation uses checked-in `docs/releases/vX.Y.Z.md` notes first, then `docs/releases/X.Y.Z.md`; it logs a clear fallback to GitHub-generated notes only when neither file exists.
- Explain that protected branches should require the GitHub Actions check context `validate` for the managed repo-maintenance workflow.
diff --git a/plugins/repository-skills/skills/maintain-project-repo/references/release-modes.md b/plugins/repository-skills/skills/maintain-project-repo/references/release-modes.md
index 50e8af625..b8cc44bad 100644
--- a/plugins/repository-skills/skills/maintain-project-repo/references/release-modes.md
+++ b/plugins/repository-skills/skills/maintain-project-repo/references/release-modes.md
@@ -18,14 +18,14 @@ Run it from a feature branch or worktree. Do not run standard release mode from
- use `--operation inspect` for one PR/check/review snapshot; it emits a continuation packet for unknown or pending remote state
- create one host-native continuation no sooner than five minutes later, then reuse that same matching scheduler item while the gate stays pending and healthy; do not delete/recreate it after an unchanged snapshot. Codex uses heartbeat, Hermes uses an updated continuable `cronjob` with `deliver="origin"` and `attach_to_session=true`
- on wakeup run `inspect` first, then use `--operation advance` only if the packet's branch, commit, PR, and tag identities still match
-- stop with a clear message if CI fails, changes are requested, or unresolved comments remain
+- stop with a clear message if CI fails, changes are requested, or unresolved comments remain; an explicit CodeRabbit quota, usage, rate, or review-limit diagnostic is non-blocking because it produced no review, but all other CodeRabbit contexts and comments still block
- stop on requested changes or comments so the maintainer can address valid concerns, add out-of-scope concerns to `ROADMAP.md`, resolve the threads, push, and rerun the same script
- merge the PR with a merge commit once CI is green and the comment pass is clear
- fast-forward local `main` from `origin/main`
- create the annotated release tag locally from the reviewed local `main`
- push the tag
- perform one immediate tag-visibility re-read; if it is not visible, emit a continuation packet instead of polling
-- create the GitHub release unless skipped, passing `--prerelease` for SemVer prerelease tags such as `vX.Y.Z-alpha.N`, `vX.Y.Z-beta.N`, `vX.Y.Z-rc.N`, or preview-style suffixes
+- create the GitHub release unless skipped, preferring `docs/releases/vX.Y.Z.md` and then `docs/releases/X.Y.Z.md` as its checked-in body; when neither exists, log the fallback and use GitHub-generated notes. Pass `--prerelease` for SemVer prerelease tags such as `vX.Y.Z-alpha.N`, `vX.Y.Z-beta.N`, `vX.Y.Z-rc.N`, or preview-style suffixes
- perform one immediate GitHub-release re-read; if it is not readable, emit a continuation packet instead of polling
- verify the GitHub release object's prerelease metadata matches the release tag before calling release publication complete
- verify `git log origin/main..main` or the repository's equivalent base/remote comparison is empty before claiming the local base branch is synchronized
diff --git a/plugins/repository-skills/skills/maintain-project-repo/scripts/install_maintain_project_repo.py b/plugins/repository-skills/skills/maintain-project-repo/scripts/install_maintain_project_repo.py
index 326c1100c..a1a934d7b 100755
--- a/plugins/repository-skills/skills/maintain-project-repo/scripts/install_maintain_project_repo.py
+++ b/plugins/repository-skills/skills/maintain-project-repo/scripts/install_maintain_project_repo.py
@@ -49,6 +49,7 @@
("repo-maintenance/sync-shared.sh", "scripts/repo-maintenance/sync-shared.sh"),
("repo-maintenance/release.sh", "scripts/repo-maintenance/release.sh"),
("repo-maintenance/lib/common.sh", "scripts/repo-maintenance/lib/common.sh"),
+ ("repo-maintenance/lib/coderabbit.sh", "scripts/repo-maintenance/lib/coderabbit.sh"),
("repo-maintenance/validations/10-toolkit-layout.sh", "scripts/repo-maintenance/validations/10-toolkit-layout.sh"),
("repo-maintenance/validations/20-agents-guidance.sh", "scripts/repo-maintenance/validations/20-agents-guidance.sh"),
("repo-maintenance/validations/30-ci-wrapper.sh", "scripts/repo-maintenance/validations/30-ci-wrapper.sh"),
diff --git a/plugins/repository-skills/skills/maintain-project-repo/tests/test_maintain_project_repo_workflow.py b/plugins/repository-skills/skills/maintain-project-repo/tests/test_maintain_project_repo_workflow.py
index 7e5a798c6..5e9398c89 100644
--- a/plugins/repository-skills/skills/maintain-project-repo/tests/test_maintain_project_repo_workflow.py
+++ b/plugins/repository-skills/skills/maintain-project-repo/tests/test_maintain_project_repo_workflow.py
@@ -250,9 +250,75 @@ def test_release_helpers_preserve_prerelease_github_metadata(self) -> None:
for release_text in (release_script, release_step):
with self.subTest(surface=release_text[:32]):
self.assertIn('prerelease_flag="$(github_release_create_prerelease_flag "$RELEASE_TAG")"', release_text)
- self.assertIn("gh release create \"$RELEASE_TAG\" --verify-tag --generate-notes $prerelease_flag", release_text)
+ self.assertIn('create_github_release_from_notes_or_generated "$RELEASE_TAG" "$prerelease_flag"', release_text)
self.assertIn('verify_github_release_prerelease_metadata "$RELEASE_TAG"', release_text)
+ def test_release_notes_helper_prefers_checked_in_notes_then_falls_back(self) -> None:
+ common_script = ROOT / "skills/maintain-project-repo/assets/repo-maintenance/lib/common.sh"
+ with tempfile.TemporaryDirectory() as tmpdir:
+ repo_root = Path(tmpdir)
+ notes_dir = repo_root / "docs/releases"
+ notes_dir.mkdir(parents=True)
+ tagged_notes = notes_dir / "v1.2.3.md"
+ versioned_notes = notes_dir / "1.2.3.md"
+ tagged_notes.write_text("# Tagged notes\n", encoding="utf-8")
+ versioned_notes.write_text("# Versioned notes\n", encoding="utf-8")
+ fake_bin = repo_root / "bin"
+ fake_bin.mkdir()
+ fake_gh = fake_bin / "gh"
+ fake_gh.write_text('#!/usr/bin/env sh\nprintf "%s\\n" "$*" >> "$GH_LOG"\n', encoding="utf-8")
+ fake_gh.chmod(0o755)
+ log_path = repo_root / "gh.log"
+
+ script = '\n'.join(
+ [
+ f'. "{common_script}"',
+ f'REPO_ROOT="{repo_root}"',
+ 'create_github_release_from_notes_or_generated v1.2.3 ""',
+ ]
+ )
+ env = dict(os.environ, PATH=f"{fake_bin}:{os.environ['PATH']}", GH_LOG=str(log_path))
+ subprocess.run(["sh", "-c", script], check=True, capture_output=True, text=True, env=env)
+ self.assertIn(f"--notes-file {tagged_notes}", log_path.read_text(encoding="utf-8"))
+
+ tagged_notes.unlink()
+ log_path.unlink()
+ subprocess.run(["sh", "-c", script], check=True, capture_output=True, text=True, env=env)
+ self.assertIn(f"--notes-file {versioned_notes}", log_path.read_text(encoding="utf-8"))
+
+ versioned_notes.unlink()
+ log_path.unlink()
+ subprocess.run(["sh", "-c", script], check=True, capture_output=True, text=True, env=env)
+ self.assertIn("--generate-notes", log_path.read_text(encoding="utf-8"))
+
+ def test_coderabbit_review_unavailable_fixtures_are_narrow(self) -> None:
+ helper = ROOT / "skills/maintain-project-repo/assets/repo-maintenance/lib/coderabbit.sh"
+ fixtures = [
+ ("CodeRabbit", "Review unavailable: monthly quota reached.", 0),
+ ("coderabbitai", "Rate limit reached; no review was produced.", 0),
+ ("CodeRabbit", "Found a potential nil dereference.", 1),
+ ("GitHub Actions", "Rate limit reached.", 1),
+ ]
+ for source, message, expected_returncode in fixtures:
+ with self.subTest(source=source, message=message):
+ proc = subprocess.run(
+ ["sh", "-c", f'. "{helper}"; coderabbit_review_is_unavailable "$1" "$2"', "sh", source, message],
+ capture_output=True,
+ text=True,
+ check=False,
+ )
+ self.assertEqual(proc.returncode, expected_returncode, proc.stderr)
+
+ def test_release_gate_only_exempts_explicit_coderabbit_unavailability(self) -> None:
+ release_script = (ROOT / "skills/maintain-project-repo/assets/repo-maintenance/release.sh").read_text(
+ encoding="utf-8"
+ )
+ self.assertIn("detect_coderabbit_review_unavailable", release_script)
+ self.assertIn("repos/$repo_name/commits/$head_sha/check-runs", release_script)
+ self.assertIn("CODERABBIT_UNAVAILABLE_COMMENT_COUNT", release_script)
+ self.assertIn('contains("coderabbit")', release_script)
+ self.assertIn("ignoring only its pending review context and diagnostic comments", release_script)
+
def test_release_env_documents_scheduled_continuation_default(self) -> None:
release_env = (ROOT / "skills/maintain-project-repo/assets/repo-maintenance/config/release.env").read_text(
encoding="utf-8"
diff --git a/plugins/repository-skills/uv.lock b/plugins/repository-skills/uv.lock
index 77f863821..d3ca0bd5a 100644
--- a/plugins/repository-skills/uv.lock
+++ b/plugins/repository-skills/uv.lock
@@ -310,7 +310,7 @@ wheels = [
[[package]]
name = "repository-skills-maintenance"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]
diff --git a/plugins/reverse-engineering-skills/.codex-plugin/plugin.json b/plugins/reverse-engineering-skills/.codex-plugin/plugin.json
index 35df5d1d8..29b3d017c 100644
--- a/plugins/reverse-engineering-skills/.codex-plugin/plugin.json
+++ b/plugins/reverse-engineering-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "reverse-engineering-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Workflow skills for reverse engineering, decompilation, disassembly, symbols, artifact analysis, and exact-build macOS security-control research.",
"skills": "./skills/",
"author": {
diff --git a/plugins/rust-skills/.codex-plugin/plugin.json b/plugins/rust-skills/.codex-plugin/plugin.json
index 8926b7a0c..136fbfccc 100644
--- a/plugins/rust-skills/.codex-plugin/plugin.json
+++ b/plugins/rust-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "rust-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Rust, Cargo, rustup, crate, workspace, CLI, library, package, CI, testing, linting, and formatting workflow skills.",
"skills": "./skills/",
"author": {
diff --git a/plugins/server-side-jvm/.codex-plugin/plugin.json b/plugins/server-side-jvm/.codex-plugin/plugin.json
index a939f76d7..db4a25a0f 100644
--- a/plugins/server-side-jvm/.codex-plugin/plugin.json
+++ b/plugins/server-side-jvm/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "server-side-jvm",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Codex skills for choosing, building, testing, and maintaining server-side JVM backend projects with Java and Scala as equal first-party languages and future Clojure support planned.",
"author": {
"name": "Gale",
diff --git a/plugins/server-side-swift/.codex-plugin/plugin.json b/plugins/server-side-swift/.codex-plugin/plugin.json
index 4f2b8c3fb..16939e30d 100644
--- a/plugins/server-side-swift/.codex-plugin/plugin.json
+++ b/plugins/server-side-swift/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "server-side-swift",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Codex skills for bootstrapping, syncing, building, running, containerizing, deploying, and maintaining server-side Swift services, including Vapor, Leaf-rendered web and HTML email, Hummingbird, hb, persistence, Swift OpenAPI, RPC-fit decisions, SwiftNIO, observability, auth, app sync, Docker, Apple Containerization, Fly.io, and SwiftPM-first workflows.",
"author": {
"name": "Gale",
diff --git a/plugins/spotify/.codex-plugin/plugin.json b/plugins/spotify/.codex-plugin/plugin.json
index fa56c4914..faa0316a0 100644
--- a/plugins/spotify/.codex-plugin/plugin.json
+++ b/plugins/spotify/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "spotify",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Placeholder plugin repository for future Spotify-focused Codex workflows.",
"author": {
"name": "Gale",
diff --git a/plugins/swift-lang/.codex-plugin/plugin.json b/plugins/swift-lang/.codex-plugin/plugin.json
index e6637b428..ce3a03f00 100644
--- a/plugins/swift-lang/.codex-plugin/plugin.json
+++ b/plugins/swift-lang/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "swift-lang",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Shared Swift language and tooling skills for API style, errors, functional pipelines, formatting, source organization, SwiftSyntax, compiler inspection, SourceKit, indexing, SourceKit-LSP, and modernization.",
"skills": "./skills/",
"author": {
diff --git a/plugins/swiftasb-skills/.codex-plugin/plugin.json b/plugins/swiftasb-skills/.codex-plugin/plugin.json
index fa543da3b..20f827a58 100644
--- a/plugins/swiftasb-skills/.codex-plugin/plugin.json
+++ b/plugins/swiftasb-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "swiftasb-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Codex skills for explaining SwiftASB and building SwiftUI, AppKit, and Swift package integrations on top of it.",
"author": {
"name": "Gale",
diff --git a/plugins/things-app/.codex-plugin/plugin.json b/plugins/things-app/.codex-plugin/plugin.json
index e425403f1..7815cfe92 100644
--- a/plugins/things-app/.codex-plugin/plugin.json
+++ b/plugins/things-app/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "things-app",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Things.app skills and a bundled local MCP server for reminders, planning digests, and structured task workflows.",
"author": {
"name": "Gale",
diff --git a/plugins/things-app/mcp/pyproject.toml b/plugins/things-app/mcp/pyproject.toml
index 7328a1265..cbbe7bbba 100644
--- a/plugins/things-app/mcp/pyproject.toml
+++ b/plugins/things-app/mcp/pyproject.toml
@@ -7,7 +7,7 @@ packages = ["app"]
[project]
name = "things-mcp"
-version = "9.31.1"
+version = "9.31.2"
requires-python = ">=3.13"
dependencies = [
"fastmcp>=3.0.2",
diff --git a/plugins/things-app/mcp/uv.lock b/plugins/things-app/mcp/uv.lock
index d61db85bd..fa1fe9af0 100644
--- a/plugins/things-app/mcp/uv.lock
+++ b/plugins/things-app/mcp/uv.lock
@@ -1244,7 +1244,7 @@ wheels = [
[[package]]
name = "things-mcp"
-version = "9.31.1"
+version = "9.31.2"
source = { editable = "." }
dependencies = [
{ name = "fastmcp" },
diff --git a/plugins/things-app/pyproject.toml b/plugins/things-app/pyproject.toml
index 3a20555f6..46b43de77 100644
--- a/plugins/things-app/pyproject.toml
+++ b/plugins/things-app/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "things-app-maintenance"
-version = "9.31.1"
+version = "9.31.2"
description = "Maintainer-only Python tooling baseline for things-app skills and plugin packaging."
requires-python = ">=3.11"
dependencies = []
diff --git a/plugins/things-app/uv.lock b/plugins/things-app/uv.lock
index 1267d3293..ae7a3fdf4 100644
--- a/plugins/things-app/uv.lock
+++ b/plugins/things-app/uv.lock
@@ -120,7 +120,7 @@ wheels = [
[[package]]
name = "things-app-maintenance"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]
diff --git a/plugins/web-dev-skills/.codex-plugin/plugin.json b/plugins/web-dev-skills/.codex-plugin/plugin.json
index b951aafed..fd73ddda9 100644
--- a/plugins/web-dev-skills/.codex-plugin/plugin.json
+++ b/plugins/web-dev-skills/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "web-dev-skills",
- "version": "9.31.1",
+ "version": "9.31.2",
"description": "Codex skills for focused web and Expo native-boundary workflows.",
"author": {
"name": "Gale",
diff --git a/pyproject.toml b/pyproject.toml
index bee094db3..6bd501410 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "socket-maintenance"
-version = "9.31.1"
+version = "9.31.2"
description = "Root uv tooling baseline for the socket superproject."
requires-python = ">=3.11"
dependencies = []
diff --git a/uv.lock b/uv.lock
index 73f25af96..eab9e9079 100644
--- a/uv.lock
+++ b/uv.lock
@@ -286,7 +286,7 @@ wheels = [
[[package]]
name = "socket-maintenance"
-version = "9.31.1"
+version = "9.31.2"
source = { virtual = "." }
[package.dev-dependencies]