diff --git a/README.md b/README.md
index a9d5242..ad3260c 100644
--- a/README.md
+++ b/README.md
@@ -102,7 +102,7 @@ npx skills add https://github.com/codebeltnet/agentic --skill dotnet-docfx-diges
| Skill | Description |
|-------|-------------|
| [git-visual-commits](skills/git-visual-commits/SKILL.md) | AI-driven git commit workflow with emoji-first subjects (gitmoji-first), optional conventional prefixes only on explicit request, and three identity modes: bot-attributed (`git bot commit`), human-attributed (`git commit`), and collaborative (`git our commit` — agent analyzes authorship, human picks attribution). Includes commit body by default (opt out with `no-body`), semantic intent splitting, bundled `commit-language.md` validation from the skill resource path rather than repo-root guesses, clarification-before-correction safety, and auto-approval mode (`yolo` / `auto`). The agent does all the work either way. Stack-agnostic. |
-| [git-keep-a-changelog](skills/git-keep-a-changelog/SKILL.md) | Git-aware Keep a Changelog companion that creates or updates `CHANGELOG.md` from the current branch by default. Inspects dependency and version manifests first (mandatory 4a–4b), then reads full commit subjects and bodies plus the net diff, treats the selected branch or range as author-agnostic scope by default so all contributors are included unless explicitly narrowed, infers a release heading from a branch version hint like `v0.3.0/...` when available, must ask a mandatory `Yes / No / Custom` confirmation question before including pending staged, unstaged, or untracked worktree changes in a concrete release draft, now backed by `FORMS.md` so compatible hosts can render a native choice UI while preserving the same text fallback, creates a compliant changelog if the file does not exist yet, writes a required SemVer-aware release highlight, maintains or inserts the Keep a Changelog compare-link footer on both create and update paths, preserves natural prose wrapping, and curates `Added` / `Changed` / `Fixed` style sections instead of dumping raw commit logs. |
+| [git-keep-a-changelog](skills/git-keep-a-changelog/SKILL.md) | Git-aware Keep a Changelog companion that creates or updates `CHANGELOG.md` from the current branch by default. For concrete releases, requires `^..HEAD` so the base commit is included, gates Step 4 on an explicit base-commit inspection report, inspects dependency and version manifests first (mandatory 4a–4b), then reads full commit subjects and bodies plus the net diff, treats the selected branch or range as author-agnostic scope by default so all contributors are included unless explicitly narrowed, infers a release heading from a branch version hint like `v0.3.0/...` when available, must ask a mandatory `Yes / No / Custom` confirmation question before including pending staged, unstaged, or untracked worktree changes in a concrete release draft, now backed by `FORMS.md` so compatible hosts can render a native choice UI while preserving the same text fallback, creates a compliant changelog if the file does not exist yet, writes a required SemVer-aware release highlight, maintains or inserts the Keep a Changelog compare-link footer on both create and update paths, preserves natural prose wrapping, and curates `Added` / `Changed` / `Fixed` style sections instead of dumping raw commit logs. |
| [git-nuget-release-notes](skills/git-nuget-release-notes/SKILL.md) | Git-aware NuGet release-notes companion for .NET repos that keep cumulative `.nuget/{ProjectName}/PackageReleaseNotes.txt` files. Discovers packable `src/` projects, resolves concrete package version and availability, creates missing files when needed, and writes per-package `ALM` / `Breaking Changes` / `New Features` / `Improvements` / `Bug Fixes` style notes from full commit context plus the net diff instead of dumping commit subjects. |
| [git-nuget-readme](skills/git-nuget-readme/SKILL.md) | Git-aware NuGet README companion for .NET repos that advertise a package from `src/`. Resolves the real packable project the README should sell, combines git history with actual package metadata, source capabilities, and relevant tests when feasible, preserves honest badge/docs/contributing sections, and writes a forthcoming, adoption-friendly `README.md` with repo-derived branding, clear value, install, framework-support, and quick-start guidance. |
| [git-visual-squash-summary](skills/git-visual-squash-summary/SKILL.md) | Non-mutating grouped-summary companion to `git-visual-commits`. Turns the full current feature branch into a curated set of compact lowercase-start summary lines for PR or squash-and-merge contexts by default, comparing against the repository base branch rather than a same-named tracking remote, including commits from all authors unless explicitly narrowed, preserving technical identifiers, merging overlap, dropping low-signal noise, retaining dependency and version-pin changes as hard-rule semantic groups before net-effect collapsing, highlighting distinct meaningful efforts, and avoiding changelog-style wording, unsupported claims, yolo prompts, needless commit-range questions, or commit-selection UI for ordinary branch-level squash requests. |
@@ -277,6 +277,7 @@ Writing `CHANGELOG.md` well is harder than it looks. Raw commit subjects are too
- **Keep a Changelog first** — writes `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, and `Security` sections in the expected style
- **Full-commit context** — reads complete commit messages and the net diff before writing
+- **Concrete-release base coverage** — uses `^..HEAD` and reports the base commit first so release-prep, version bumps, and dependency baselines in that commit are not silently skipped
- **Cumulative dependency coverage** — when version manifests changed across the release range, diffs them from base to `HEAD` so the changelog reflects the surviving package/version story instead of only per-commit fragments
- **Whole-branch by default** — treats the selected branch or range as author-agnostic scope, so all contributors' commits are in play unless you explicitly narrow by author
- **Version-aware by branch** — uses a branch prefix like `v0.3.0/...` as the release heading hint when present
diff --git a/scripts/validate-skill-templates.ps1 b/scripts/validate-skill-templates.ps1
index 3cceb19..ec32751 100644
--- a/scripts/validate-skill-templates.ps1
+++ b/scripts/validate-skill-templates.ps1
@@ -996,6 +996,11 @@ Add-ValidationResult -Results $results -Name 'Git keep a changelog skill updates
Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle 'you must ask a direct confirmation question before drafting the changelog entry.'
Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle 'Do not skip this question.'
Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle 'Wait for the user''s explicit response before proceeding to Step 4.'
+ Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle '### Step 3b: Verify Your Approach'
+ Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle '**You must use `^..HEAD`** (with the caret) throughout Step 4.'
+ Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle 'Inspect and report the base commit (concrete releases ONLY'
+ Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle '**Show the full output** in your response (do not summarize or skip lines).'
+ Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle '**Step 4a Confirmation (before proceeding):**'
Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle 'Do not dump commit subjects verbatim into the changelog.'
Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle 'If `CHANGELOG.md` is missing, create it with the standard title,'
Assert-Contains -Name 'git-keep-a-changelog/SKILL.md' -Content $skill -Needle 'Always maintain the Keep a Changelog compare-link footer at the bottom of the file.'
@@ -1016,6 +1021,7 @@ Add-ValidationResult -Results $results -Name 'Git keep a changelog skill updates
Assert-Contains -Name 'git-keep-a-changelog/evals/evals.json' -Content $evals -Needle 'Treats the pending-worktree question as a mandatory gate before Step 4 for a concrete release'
Assert-Contains -Name 'git-keep-a-changelog/evals/evals.json' -Content $evals -Needle 'Does not let user intent bypass the mandatory pending-worktree confirmation gate for a concrete release'
Assert-Contains -Name 'git-keep-a-changelog/evals/evals.json' -Content $evals -Needle 'Inserts the compare-link footer at the bottom when it is missing from an existing changelog'
+ Assert-Contains -Name 'git-keep-a-changelog/evals/evals.json' -Content $evals -Needle 'Uses ^..HEAD with the caret for concrete-release Step 4 commands instead of ..HEAD'
}
Add-ValidationResult -Results $results -Name 'Rendered app worker template leaves no unexpected placeholders' -Action {
diff --git a/skills/git-keep-a-changelog/SKILL.md b/skills/git-keep-a-changelog/SKILL.md
index 5b6efe9..a2340c2 100644
--- a/skills/git-keep-a-changelog/SKILL.md
+++ b/skills/git-keep-a-changelog/SKILL.md
@@ -180,22 +180,62 @@ git diff --stat
git ls-files --others --exclude-standard
```
+### Step 3b: Verify Your Approach
+
+Before proceeding to Step 4, verify your approach:
+
+- If the target is a concrete release (e.g., `## [0.5.9]`): **You must use `^..HEAD`** (with the caret) throughout Step 4. The caret means "include the base commit."
+- If the target is `## [Unreleased]`: Use `..HEAD` (without the caret).
+
+| Syntax | Meaning | Use For |
+|--------|---------|---------|
+| `base^..HEAD` | From base's parent through HEAD (inclusive of base) | Concrete releases (includes foundational changes) |
+| `base..HEAD` | From base through HEAD (exclusive of base) | `[Unreleased]` or historical analysis |
+
+**Never accidentally omit the `^` for concrete releases.** The base commit frequently contains version bumps, release-prep changes, and initial dependency updates that form the foundation of the complete deliverable.
+
### Step 4: Read the full history and net effect
Follow these sub-steps in order. Sub-steps 4b and 4c are mandatory whenever manifests were touched and must run before reading commit bodies.
-**Range extension for concrete releases:** When the changelog target is a concrete version heading (e.g., `## [X.Y.Z]`), use `^..HEAD` throughout Step 4 to include the base commit itself. The base commit frequently contains the initial version bumps or release-prep changes that are part of the complete deliverable. For `## [Unreleased]`, continue using `..HEAD` — no change.
+**Range extension for concrete releases — CRITICAL:** When the changelog target is a concrete version heading (e.g., `## [X.Y.Z]`), **always use `^..HEAD`** (with the caret `^`) throughout Step 4. The `^` means "starting from the parent of base", which includes base itself. Without the `^`, you will silently omit the base commit, losing foundational version bumps, release-prep, and dependency changes.
+
+Example:
+- ❌ `git diff base..HEAD` — skips base commit (wrong for concrete releases)
+- ✅ `git diff base^..HEAD` — includes base commit (required for concrete releases)
+
+For `## [Unreleased]`, continue using `..HEAD` — no caret.
-**4a — Inspect the base commit (concrete releases only).** Before detecting manifest changes or reading commit bodies, inspect the base commit itself:
+**4a — Inspect and report the base commit (concrete releases ONLY — MANDATORY GATE).**
+
+This sub-step is a required checkpoint. Do not proceed past 4a until you have shown the output and analyzed it.
+
+Before detecting manifest changes or reading anything else, inspect the base commit itself:
```bash
git show --format=medium
git diff ^.. --stat
```
-If any dependency or version manifest appears in the output — `Directory.Packages.props`, `Directory.Build.props`, `package.json`, `pnpm-lock.yaml`, `yarn.lock`, `pom.xml`, `build.gradle`, `go.mod`, `go.sum`, or similar — proceed to 4b immediately. Do not skip ahead to reading commit bodies.
+After running these commands:
+
+1. **Show the full output** in your response (do not summarize or skip lines).
+2. **Identify any dependency/version manifests** — Directory.Packages.props, Directory.Build.props, `package.json`, `pom.xml`, `go.mod`, or similar.
+3. **Identify any release-prep files** — CHANGELOG.md, package release notes, version files, or similar.
+4. **Explicitly state:** "Base commit contains [X files changed]: [file list]" and "Manifests found: [yes/no, list if yes]".
+5. **Only after showing and analyzing this output, proceed to 4b.**
+
+If the base commit contains **any** manifest changes or release-prep work, Step 4b and 4c become mandatory (do not skip them). If the base commit is clean, still run 4b to detect manifests across the full range; you may skip 4c only when 4b also finds no manifest changes.
+
+**Step 4a Confirmation (before proceeding):**
+
+You must explicitly confirm what you found in Step 4a before proceeding to 4b–4d. Answer these questions:
+
+1. Did the base commit modify any manifests (dependencies, versions, build config)? (Yes/No)
+2. Did the base commit modify any release-prep files (CHANGELOG, release notes, version files)? (Yes/No)
+3. If YES to either: List the specific files and their changes.
-This reveals what the branch author prepared as the foundation: release prep, version bumps, or initial dependency updates. If the base commit contains manifest changes, treat those as the starting point for the dependency picture established in 4b–4c.
+Only after answering these questions, proceed to 4b.
**4b — Detect manifest changes.** Check which files changed across the full range:
@@ -308,7 +348,7 @@ After updating `CHANGELOG.md`, stop and let the user review the file. Do not com
- Includes a required SemVer-aware release highlight.
- Creates a compliant `CHANGELOG.md` scaffold when the file is missing.
- Reflects the meaning of full commit bodies and the net diff.
-- Inspects the base commit before anything else for concrete releases (4a), then runs base-to-`HEAD` manifest diffs as the first evidence steps (4b–4c) whenever any manifest was touched, capturing the full cumulative dependency/version picture before reading individual commit messages.
+- Inspects the base commit before anything else for concrete releases (4a) and explicitly reports the findings (files changed, manifests detected), then runs base-to-`HEAD` manifest diffs as the first evidence steps (4b–4c) whenever any manifest was touched, capturing the full cumulative dependency/version picture before reading individual commit messages. Always uses `^..HEAD` (with caret) for concrete releases to ensure the base commit is included.
- Includes the base commit in concrete release changelogs by using `^..HEAD`, so foundational version bumps and release-prep changes are never omitted from the release narrative.
- Treats the selected branch or range as author-agnostic scope and includes every contributor's commits unless the user explicitly narrows by author.
- Treats Step 3 as a mandatory confirmation gate for concrete releases and asks the `Yes / No / Custom` question before including pending worktree changes (or skips Step 3 entirely and includes all changes when yolo/auto mode is active).
@@ -319,6 +359,7 @@ After updating `CHANGELOG.md`, stop and let the user review the file. Do not com
## Bad Output Characteristics
+- **CRITICAL — Omitting the base commit from a concrete release changelog.** This is a silently-wrong output that breaks the release narrative. The base commit frequently contains foundational version bumps, release-prep changes, dependency baseline updates, or other changes that are integral to the deliverable. Always use `^..HEAD` for concrete releases, not `..HEAD`. Always run Step 4a first and show the output before proceeding.
- Copying commit subjects line by line into the changelog.
- Omitting the release highlight.
- Failing to classify the release as major, minor, or patch.
@@ -332,4 +373,3 @@ After updating `CHANGELOG.md`, stop and let the user review the file. Do not com
- Filtering the selected branch or range to the current user's or current contributor's commits, or treating "my changes" as the default release scope.
- Understating dependency or version changes because the skill only read individual commit diffs and never inspected the surviving manifest delta from base to `HEAD`.
- Reading commit messages before running manifest diffs, then reporting only the packages mentioned in whichever commits happened to be read first, rather than the full cumulative set from the manifest diff.
-- Omitting the base commit from a concrete release changelog, causing the release narrative to miss foundational version bumps, release prep, or initial dependency updates that form part of the complete deliverable.
diff --git a/skills/git-keep-a-changelog/evals/evals.json b/skills/git-keep-a-changelog/evals/evals.json
index 2d759b9..0db98c6 100644
--- a/skills/git-keep-a-changelog/evals/evals.json
+++ b/skills/git-keep-a-changelog/evals/evals.json
@@ -152,6 +152,19 @@
"Does not underreport package updates because they were spread across separate commits",
"Does not let commit-message version descriptions override manifest diff version facts when the two differ"
]
+ },
+ {
+ "id": 14,
+ "prompt": "My branch is named v0.5.9/release-prep. The base commit includes dependency upgrades and release-prep files, and those changes must be part of the concrete release changelog. Update CHANGELOG.md without omitting the base commit.",
+ "expected_output": "The workflow treats this as a concrete release, uses ^..HEAD throughout Step 4, reports the base commit findings before continuing, and includes base-commit dependency or release-prep changes in the changelog evidence.",
+ "expectations": [
+ "Recognizes the concrete release target from the v0.5.9 branch prefix",
+ "Uses ^..HEAD with the caret for concrete-release Step 4 commands instead of ..HEAD",
+ "Runs Step 4a as a mandatory gate before reading the broader history",
+ "Shows and analyzes the base commit output before proceeding to manifest diffs or commit logs",
+ "Explicitly reports files changed in the base commit and whether manifests were found",
+ "Includes foundational dependency, version, or release-prep changes from the base commit in the changelog evidence"
+ ]
}
]
}