Restructure release skill into full-release and scoped-patch flows

Replace the single development-based release flow with two explicit flows under one Git release flow heading: a full release cut from development, and a scoped patch cut from the last tag that merges release/v<version> directly into main (never development -> main) with a scope audit. Remove the older redundant standalone scoped-patch section, and reconcile the release checklist into a two-bullet full/scoped form. Co-Authored-By: siGit Code v1.6.7-acp <noreply@sigit.si>

Seto Elkahfi committed Oct 12, 2026 at 15:14 UTC 53ef5e21cb33dd52080905cb39d133d32d9d5d5a
1 file changed +38 -41
.agents/skills/sigit-code-release/SKILL.md
+38 -41
@@ -43,7 +43,13 @@ Use this skill when preparing a release for this repository.
43
44 ## Git release flow
45
46 -Releases are cut from `development` and shipped on `main`. The published tags (`v1.2.0`, `v1.2.1`) point at the `main`-side merge commit, never at a release branch or at `development`. Follow this order:
46 +Releases are shipped on `main`, and the published tags (`v1.2.0`, `v1.2.1`) point at the
47 +`main`-side merge commit, never at a release branch or at `development`. There are two flows,
48 +and picking the wrong one ships the wrong set of commits. Decide first which this is.
49 +
50 +### Full release (minor/major — ships everything on `development`)
51 +
52 +Cut from `development` when the release is meant to carry all the work that has accumulated there.
53
54 1. Branch `release/v<version>` off `development`.
55 2. Apply the version bump and changelog edits, then commit (e.g. `Release v<version>`).
@@ -51,47 +57,37 @@ Releases are cut from `development` and shipped on `main`. The published tags (`
57 4. Merge `development` into `main` (commit message: `Merge development into main for v<version> release`).
58 5. Tag `v<version>` on that `main` merge commit, then push `main` and the tag.
59
54 -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`).
60 +For a full release, step 4 is the only way commits are meant to reach `main`. A feature or fix
61 +PR targeting `main` breaks that: it puts work on the release branch that `development` does not
62 +have, so the next release is cut without it. Such PRs belong on `development` (see the pull
63 +request target rule in `AGENTS.md`).
64 +
65 +### Scoped patch (hotfix — ships only specific fixes on top of the last tag)
66 +
67 +Use this when the patch must ship **only** a named set of fixes on top of the last released tag,
68 +**not** the unreleased work sitting on `development` (e.g. a patch over `v1.6.7` that must carry
69 +just a winget/Windows hotfix while ACP features stay unreleased). The giveaway is wording like
70 +"scoped patch off `v<prev>`" or "hotfix" — if `development` is far ahead, a `development → main`
71 +merge would drag all of it out under a patch tag, which is wrong.
72 +
73 +1. Branch `release/v<version>` off the **last released tag** (`v<prev>`), not `development`.
74 +2. Cherry-pick (or commit) only the in-scope fixes, then the version bump + changelog, and commit
75 + (e.g. `Release v<version>`).
76 +3. Merge `release/v<version>` back into `development` so the bump and changelog carry forward.
77 +4. Merge `release/v<version>` **directly into `main`** (commit message: `Release v<version>`) —
78 + **never `development → main` for a scoped patch**, since that would pull `development`'s
79 + unreleased work onto `main`.
80 +5. Tag `v<version>` on that `main` merge commit, then push `main` and the tag.
81 +
82 +Before tagging a scoped patch, audit the scope: `git log --oneline v<prev>^{commit}..main` and
83 +`git diff --stat v<prev>^{commit}..main` must show only the intended fixes and the release
84 +metadata files (`Cargo.toml`, `Cargo.lock`, `CHANGELOG.md`), nothing from `development`.
85
86 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.
87
58 -### Scoped patch / hotfix flow (cherry-pick, not branch-off-development)
59 -
60 -The flow above assumes the release ships everything on `development`. A **scoped
61 -patch** is different: the user wants a new version that contains only one or a
62 -few specific merged PRs on top of the **last tag**, deliberately leaving out
63 -other work that has since landed on `development`. "A PR is merged into
64 -`development`" does **not** mean it belongs in a patch — a patch inherits the
65 -*previous tag's* tree, not `development`'s.
66 -
67 -Branching the release off `development` and only bumping the version is the
68 -classic mistake here: it silently drags in every unrelated PR merged since the
69 -last tag. For a scoped patch, never branch off `development`. Instead:
70 -
71 -1. Branch `release/v<version>` off the **previous tag** (`git checkout -b
72 - release/v<version> v<previous>`), not off `development`. The tag already
73 - points at the right `main` merge commit.
74 -2. `git cherry-pick` exactly the wanted commit(s). Prefer the feature/squash
75 - commit (the merge commit's second parent) over the merge commit itself.
76 - Resolve conflicts to keep the scope minimal.
77 -3. Apply the version bump and changelog edits (promote the cherry-picked
78 - `## Unreleased` bullets into the `## <version>` section), then commit `Release
79 - v<version>`.
80 -4. **Audit the scope before going further:** `git log --oneline
81 - v<previous>..release/v<version>` must show only the cherry-picks plus the
82 - release commit, and `git diff --stat v<previous>..release/v<version>` must be
83 - the wanted source/test changes plus the three release-metadata files
84 - (`Cargo.toml`, `Cargo.lock`, `CHANGELOG.md`) — nothing else.
85 -5. Merge `release/v<version>` into `development` (so the version bump and the
86 - promoted changelog entry are not lost), then merge `development` into `main`
87 - and tag `v<version>` on that `main` merge commit, exactly as in the normal
88 - flow. The `development` merge may be a no-op for the cherry-picked source if
89 - it was already there; that is expected.
90 -
91 -Decide up front which case you are in and confirm the exact PR list with the
92 -user. If in doubt about whether a release is "everything on `development`" or a
93 -scoped patch, ask — the two flows start from different base commits and are not
94 -interchangeable.
88 +Decide up front which flow you are in and confirm the exact scope with the user. If in doubt about
89 +whether a release ships everything on `development` or only a scoped set of fixes, ask — the two
90 +flows start from different base commits and are not interchangeable.
91
92 ## Typical files to inspect
93
@@ -117,8 +113,9 @@ interchangeable.
113 - `npm/sigit/package.json` is left at `0.0.0-dev` unless the packaging flow itself changed.
114 - `pypi/pyproject.toml` still uses dynamic versioning unless there is a deliberate packaging change.
115 - Release workflows still derive their version from the tag as expected.
120 -- Git flow followed: bump committed on `release/v<version>`, merged back to `development`, then `development` merged into `main`, with `v<version>` tagged on the `main` merge commit.
121 -- Scope matches intent: for a scoped patch/hotfix, `release/v<version>` is branched off the **previous tag** and carries only the cherry-picked PR(s) plus the release-metadata bump — confirmed with `git log --oneline v<previous>..release/v<version>` and `git diff --stat v<previous>..release/v<version>` — not everything that landed on `development` since the last tag.
116 +- Correct git flow for the release type followed, with `v<version>` tagged on the `main` merge commit either way:
117 + - **Full release:** bump committed on `release/v<version>` (off `development`), merged back to `development`, then `development` merged into `main`.
118 + - **Scoped patch:** `release/v<version>` branched off the last tag `v<prev>`, in-scope fixes + bump committed, merged back to `development`, then `release/v<version>` merged **directly into `main`** (never `development → main`), and the scope audited (`git log --oneline v<prev>^{commit}..main` / `git diff --stat v<prev>^{commit}..main`) to show only the intended fixes plus release metadata.
119 - Release notes or changelog entries match the actual changes.
120 - CI-equivalent local checks pass for the relevant platform or target.
121 - Package names, install commands, and branding stay consistent across npm, PyPI, crates.io, Homebrew, NuGet, Scoop, winget, AUR, and the `.deb`/`.rpm` packages.