Say how to keep a PR off main, not just that it belongs on development

AGENTS.md already said every pull request targets development. PR #65 went to main anyway, and the reason is mechanical: the repository's default branch is main, so gh pr create and the web form both pre-select it. A rule that a tool silently defaults away from needs the countermeasure written next to it. The pull request target section now carries the base flag to pass, the command to confirm it took, and the repair — free before the merge, hand-carried work after, since main then holds a change that development, which the next release is cut from, does not. The release skill gains the matching invariant from the other side: step 4 of the release flow is the only way commits are meant to reach main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Seto Elkahfi committed Sep 3, 2026 at 07:34 UTC 92dc037d1605932ee0b8dcf0fc021647e13443e7
2 files changed +19 -1
.agents/AGENTS.md
+17 -1
@@ -26,7 +26,23 @@ from the name alone (e.g. `feature/tool-permission-system`, `fix/glob-mtime-sort
26 a task, ticket, or session id (not `feature/task-q003hm`).
27
28 **IMPORTANT — pull request target:** Always open pull requests against the `development` branch,
29 -never `main`. `main` is release-only; `development` is where day-to-day work integrates.
29 +never `main`. `main` is release-only; `development` is where day-to-day work integrates, and the
30 +release merge (see the `sigit-code-release` skill) is the one thing that ever puts commits on
31 +`main`.
32 +
33 +This rule needs help to hold, because the repository's default branch is `main`: both
34 +`gh pr create` and the GitHub web form pre-select it, so a PR lands on the wrong base unless the
35 +base is passed explicitly. Pass it every time, and check that it took:
36 +
37 +```sh
38 +gh pr create --base development --head <branch>
39 +gh pr view <number> --json baseRefName
40 +```
41 +
42 +Retargeting a PR that was opened against `main` costs nothing before it merges:
43 +`gh pr edit <number> --base development`. After it merges it costs real work — the change sits on
44 +`main` while `development`, which the next release is cut from, does not have it, and someone has
45 +to carry it back by hand. PR #65 went in that way.
46
47 **IMPORTANT — branch off `development`:** Start every working branch from the latest
48 `origin/development`. Exception: when new work *depends on* a feature branch that has not merged
.agents/skills/sigit-code-release/SKILL.md
+2
@@ -42,6 +42,8 @@ Releases are cut from `development` and shipped on `main`. The published tags (`
42 4. Merge `development` into `main` (commit message: `Merge development into main for v<version> release`).
43 5. Tag `v<version>` on that `main` merge commit, then push `main` and the tag.
44
45 +Step 4 is the only way commits are meant to reach `main`. A feature or fix PR targeting `main` breaks that: it puts work on the release branch that `development` does not have, so the next release is cut without it. Such PRs belong on `development` (see the pull request target rule in `AGENTS.md`).
46 +
47 Pushing the `v*.*.*` tag is what fires every release workflow, so create and push it only after the merge into `main` has landed. Do not commit, tag, or push until the user explicitly asks — confirm the version and that they want the release to go out first.
48
49 ## Typical files to inspect