--- name: pr description: "Create a pull request: detect base branch, verify not protected, run lint/pre-commit if configured, push, open PR with a generated description that always carries an Assumptions section. Falls back to push + compare URL without gh." argument-hint: "[base-branch]" --- ## Progress Contract Register these steps as a native task list at Step 1, before beginning. Report progress as "N steps remaining, size class S/M/L" — never wall-clock ETAs. Steps: (1) resolve-base, (2) guard-branch, (3) lint, (4) push, (5) open-pr. ## Arguments - **`[base-branch]`** — explicit base branch for the PR. If omitted, resolve via `git symbolic-ref refs/remotes/origin/HEAD` (strip to branch name); if unset, use `main` if it exists, else `master`. State the resolved base before proceeding. ## Workflow ### Step 1 — Resolve base Determine the base branch using the rule above. Print: `"base branch: (source: )."` ### Step 2 — Guard current branch ← STOP if protected Get the current branch: `git rev-parse --abbrev-ref HEAD`. **REFUSE** if the current branch matches any protected name: `main`, `master`, `staging`, `production`, `qa`, `develop`, or the resolved repo default. Print: `"REFUSED: current branch '' is protected. Check out a feature branch and re-run."` Do not proceed further. ### Step 3 — Lint / pre-commit Check whether the project configures a lint or pre-commit step (look for `.pre-commit-config.yaml`, a `lint` or `check` target in `Makefile`, or a lint command in `CLAUDE.md`). If found, run it. If it fails, report the output and stop — do not push broken code. If no lint config is found, skip silently and note `"no lint config detected."`. ### Step 4 — Push Push the current branch to origin: `git push -u origin `. ### Step 5 — Open PR **With `gh`**: run `gh pr create --base --title --body <body>`. Derive the title from the branch name or the most recent commit subject (≤ 72 chars). PR body template: ``` ## Summary <bullet points from commits on this branch not yet on base> ## Assumptions <content of `## Assumptions` from the plan, or "None beyond the plan" if absent> ## Test plan <bullet list of test files or manual checks run> ``` Carry the `## Assumptions` section verbatim from the plan file used in the preceding `/octo:implement` run (`.claude/plans/` latest by name). The section is **always present**, even when empty — write `"None beyond the plan"` rather than omitting it. No AI attribution in the PR body, title, or any commit message — ever. **Without `gh`**: push (Step 4 is already done), then print: ``` Compare URL: https://github.com/<org>/<repo>/compare/<base>...<current-branch> Open the URL above to create a PR manually. ``` Derive the GitHub org/repo from `git remote get-url origin`. --- ## Shared Conventions - Commits: conventional format `type(scope): brief description` — no AI attribution, no `Co-Authored-By` lines of any kind. - Never push directly to protected branches (protected branches — see the octo guard's list). - Never use `--no-verify` or force-push. - Parallel-first: dispatches that do not consume each other's output MUST go in a single message. Dispatching sequentially what could run concurrently is a defect, not a style choice. Cap ≈10 concurrent lanes; more work than lanes → batch waves. - Reader-first output: lead with the outcome in one sentence; keep the visible reply short and dev-readable — only what changes the reader's next action. Full detail (complete reports, evidence, logs) goes to a file under `.claude/octo/reports/YYYY-MM-DD-<skill>-<slug>.md` with the path given in chat — never dumped into the conversation.