- name
- openmates:pullrequest
- description
- Create a pull request from dev to main with proper formatting and draft release
- user-invocable
- true
- disable-model-invocation
- false
- argument-hint
- [title]
## Instructions
**IMPORTANT: Only create a PR when the user explicitly asks.**
Codex users invoke this workflow through `/pullrequest`. That command creates
a visible user turn and loads this skill through the `skill` tool. Keep this
file static: execute commands explicitly during the workflow rather than using
Claude command-template shell expansion in `SKILL.md`.
### Step 0 — Summarize Changelog Markdown Before Asking Questions (CRITICAL)
Identify the most recent **merged** `dev` → `main` PR using `--state merged` and
its `mergedAt` value. Read every compact
`docs/releases/daily/YYYY-MM-DD.md` on or after that merge date and every
`docs/releases/weekly/YYYY-Www.md` whose covered date range overlaps the
post-merge period.
Do not refresh or write release-intelligence artifacts yet.
Start with explicit read-only discovery:
```bash
git fetch origin main dev
latest_pr=$(gh pr list --base main --head dev --state merged --limit 1 \
--json number,title,mergedAt,mergeCommit,headRefOid,url)
latest_head=$(printf '%s' "$latest_pr" | jq -r '.[0].headRefOid // empty')
if [ -n "$latest_head" ] && ! git merge-base --is-ancestor "$latest_head" origin/main; then
printf 'Blocked: previous dev PR head %s is not an ancestor of origin/main. Repair merge history before preparing another PR.\n' "$latest_head"
exit 1
fi
repo=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
merge_policy=$(gh api "repos/$repo" \
--jq '[.allow_merge_commit, .allow_squash_merge, .allow_rebase_merge] | @tsv')
expected_merge_policy=$(printf 'true\tfalse\tfalse')
if [ "$merge_policy" != "$expected_merge_policy" ]; then
printf 'Blocked: repository must allow merge commits only; squash and rebase rewrite dev commit ancestry.\n'
exit 1
fi
printf '%s\n' "$latest_pr"
git rev-list --left-right --count origin/main...origin/dev
git diff --stat origin/main...origin/dev
```
This merge-history gate is mandatory. It prevents a squash or rebase promotion
from making previously released `dev` commits appear unreleased and preserves
their exact hashes on `main`. Do not continue by substituting a tree-diff check:
identical trees do not prove that commit ancestry was retained.
Use the merged PR's `mergedAt` date to select the daily Markdown files, then
inspect weekly Markdown files whose stated date range overlaps that boundary.
Read the selected files in full before producing the summary. For the merge-day
file, include only entries supported by commits in `origin/main..origin/dev`;
exclude entries already reachable from the prior PR's merge commit. This keeps
changes made later on the merge day without repeating the prior release.
Before asking any clarifying question, give the user one concise, source-grounded summary with these headings:
- **Released/User-Facing Changes**
- **Bug Fixes**
- **Internal/Platform Work**
- **Disabled Or Unreleased Preparation**
- **Risks And Unclear Decisions**
Use Markdown companions as the primary source. Use `origin/main..origin/dev`, changed files, companion YAML, and full commit messages only as supporting evidence or to resolve ambiguity. Do not claim a feature is released merely because its code is in `dev`.
### Step 1 — Ask Exactly Five Clarifying Questions (CRITICAL)
After presenting the changelog summary, ask exactly five clarifying questions before changing feature availability, reconciling branches, drafting the PR body, or creating the PR.
- Ask one question per assistant message and wait for the user's response before asking the next.
- Label them `Question 1 of 5` through `Question 5 of 5`.
- Include a concrete recommendation in each question using `Recommendation:`
with the evidence-based preferred answer and rationale, plus `Examples:` with
task-specific options or outcomes.
If uncertain, recommend the safest reversible default and state the uncertainty.
- Incorporate answers already provided by the user, but still ask for confirmation when the answer controls release scope or branch history.
- Cover these five decision areas, adapting the wording to the discovered changes: code inclusion versus public release-note treatment; enabled versus disabled feature readiness; `main`-only commit reconciliation; required validation/risk exceptions; and PR narrative/release emphasis.
- For branch reconciliation, inspect the `main`-only commits before making a recommendation. Recommend preserving legitimate fixes and merge history. Ask the user about ambiguous commits or behavioral conflicts rather than guessing.
After the fifth answer, summarize the confirmed decisions and execution plan,
then continue autonomously through the readiness gates and PR creation. Do not
ask for a separate plan approval; the user's explicit `/pullrequest` invocation
and five answers authorize the workflow. Stop only for a failed required gate,
an unclassified feature introduced after the questions, or another concrete
safety/reconciliation decision that the five answers could not cover.
### Step 2 — Resolve Worktree Readiness (CRITICAL)
Before release intelligence or PR drafting, fetch `dev` and run reconciliation readiness against its exact remote commit:
```bash
git fetch origin dev
python3 scripts/sessions.py worktree release-readiness --target origin/dev
```
The gate blocks stale, blocked, orphaned, malformed, unique unresolved, and unclassified worktrees. Do not merge or delete
worktree content manually to bypass it. Run the reported `sessions.py worktree reconcile` action and stop when meaningful unique
work still needs an operator decision.
Recent active work may remain outside this release only after the user explicitly confirms the exclusion. Rerun with one flag
per confirmed session, for example:
```bash
python3 scripts/sessions.py worktree release-readiness \
--target origin/dev \
--exclude-active 253b
```
Record the excluded session IDs in the PR preparation summary, rerun the gate after any cleanup or deploy, and continue only
when it reports `Ready: yes` for the final exact `origin/dev` commit.
### Step 3 — Verify Remote Refs And Main-Only Commits (CRITICAL)
**ALWAYS use remote refs** (`origin/main`, `origin/dev`) — never local refs. Local refs can be stale and produce wildly incorrect commit counts.
```bash
git fetch origin main dev
git rev-list --left-right --count origin/main...origin/dev
git log --format="%h %s%n%b" origin/dev..origin/main
git log --oneline origin/main..origin/dev
```
Confirm the commit count makes sense and classify every `main`-only commit before reconciling branches. If the commits are legitimate fixes or merge history and reconciliation is conflict-free, follow the user's approved strategy. Stop and ask about unexpected commits or behavioral conflicts.
### Step 4 — Refresh Release Intelligence
Before writing the PR body, always refresh the current daily changelog so the last 24 hours are represented:
```bash
today=$(date -u +%F)
python3 scripts/release_intelligence.py daily \
--since "24 hours ago" \
--date "$today" \
--write \
--output "docs/releases/daily/${today}.yml"
```
Use the most recent merged `dev` → `main` PR boundary established in Step 0. Re-read the refreshed daily Markdown companion and update the changelog summary if it materially changed.
```bash
latest_pr_date=$(gh pr list --base main --head dev --state merged --limit 1 --json mergedAt --jq '.[0].mergedAt // empty' | cut -dT -f1)
ls docs/releases/daily/*.md | while read -r file; do
day=$(basename "$file" .md)
if [ -z "$latest_pr_date" ] || [ "$day" = "$latest_pr_date" ] || [ "$day" ">" "$latest_pr_date" ]; then
echo "$file"
fi
done
```
Use the Markdown overview, grouped changes, and newsletter guidance to build the PR body. Keep unreleased/disabled-feature work out of public release/newsletter language, but include it in the PR when it is part of the code diff. Use companion YAML fields such as `sections`, `marketing_candidates`, and `unreleased_progress` only when deeper structured evidence is required.
Apply the same merge-day commit-evidence filter used in Step 0 before adding
items from the refreshed Markdown companion.
### Step 5 — Feature Readiness Gate (CRITICAL)
Before drafting or creating the PR, run and read the deterministic feature readiness report:
```bash
latest_pr_date=$(gh pr list --base main --head dev --state merged --limit 1 --json mergedAt --jq '.[0].mergedAt // empty' | cut -dT -f1)
if [ -n "$latest_pr_date" ]; then
next_daily_date=$(date -u -d "${latest_pr_date} +1 day" +%F)
python3 scripts/release_intelligence.py pr-readiness \
--from-ref origin/main \
--to-ref origin/dev \
--daily-start-date "$next_daily_date" \
--format markdown \
--stdout
else
python3 scripts/release_intelligence.py pr-readiness \
--from-ref origin/main \
--to-ref origin/dev \
--format markdown \
--stdout
fi
```
Use this report to list every changed user-facing or potentially user-facing feature area, especially default-disabled platform features and app/skill/provider work such as projects, tasks, plans, workflows, teams, Revolut Business finance, and code image-to-HTML/image-to-code.
Reconcile this deterministic report with the five confirmed answers. If the report introduces a feature area that the questions did not cover, stop for a focused follow-up decision. Do not silently infer release readiness, draft the final PR body, or run `gh pr create` while any listed feature remains unclassified.
If the user says a feature is not ready, keep the code but deactivate access through the existing feature availability model:
- For platform features, remove any matching `feature_overrides.enabled` entry and/or add a `feature_overrides.disabled` entry in `backend/config/backend_config.yml`.
- For apps, skills, embeds, focus modes, or memory types, set `default_enabled: false` on the relevant `backend/apps/*/app.yml` entry.
- Re-run `python3 scripts/release_intelligence.py pr-readiness --from-ref origin/main --to-ref origin/dev --format markdown --stdout` and show the updated status before continuing.
Continue automatically when the five answers classify every reported feature
and confirm that the remaining accessible features are ready for the PR. Do not
request the same confirmation again at this gate.
### Step 6 — Analyze Remaining Commit Details
Use raw commit history only as supporting evidence or to fill gaps not covered by daily changelogs. Read the **full commit messages** (not just one-liners):
```bash
git log origin/main..origin/dev --format="%h %s%n%b"
```
Group commits into:
- **Features** (`feat:`) — new user-facing functionality
- **Bug Fixes** (`fix:`) — resolved issues
- **Improvements** (`refactor:`, `perf:`, `improve:`) — internal improvements
- **Other** (`docs:`, `chore:`, `build:`, `ci:`, `test:`) — maintenance
### Step 7 — Write PR Description
Write a **human-readable** PR description — not a commit dump. Structure:
```markdown
## Summary
<2-4 sentence overview of what this PR does and why>
## Features
- <grouped by feature area>
## Bug Fixes
- <grouped by fix area>
## Improvements
- <grouped by improvement area>
## Future Release Preparation
- <briefly summarize included code for explicitly unreleased features without claiming availability>
## Other Changes
- <docs, chore, config items>
```
Only include sections that have content. Write for a developer audience — specific and clear.
Apply this guidance when creating or updating a PR description. The public body
describes the included changes, their purpose, and concise factual validation.
Keep production rollout plans, SSH/server operations, manual post-deployment
testing plans, internal approvals, gate waivers/bypass instructions, and agent
coordination in the private task conversation, outside the public description.
Report only validation actually performed; do not imply unrun checks passed.
If validation coverage matters to reviewers, state that a check was not run
without publishing the internal waiver or deployment plan.
### Step 8 — Create the PR
```bash
gh pr create --base main --head dev --title "<short descriptive title>" --body "$(cat <<'EOF'
<PR description>
EOF
)"
```
Present the PR URL to the user.
### Step 9 — Offer Draft Release
After PR creation, ask the user if they want a draft release prepared. If yes, use the `/create-release` skill. Tell the user:
- The PR URL
- That the draft release should be published **after** the PR is merged into `main`
Auf GitHub ansehen