log-changes — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited log-changes (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
The changelog records notable changes to the distributed software. Every entry must answer: "Does this change affect someone who uses, upgrades, deploys, or integrates with the project?" If not, omit it.
Format authority: Keep a Changelog 1.1.0 and Semantic Versioning 2.0.0.
Detect the following constants from the project itself - do not ask the user unless detection fails. Inspect, in order: existing CHANGELOG.md entries, project documentation (README.md, CONTRIBUTING.md, docs/), and recent git commit messages.
git remote get-url origin and parse the slug from the URL.https://github.com/OWNER/REPO/issues/NNN, or closing keywords closes/fixes/resolves #NNN in commit/PR bodies.[A-Z]+-[0-9]+ (e.g. ABC-123) or links to *.atlassian.net/browse/....ENG-123 or links to https://linear.app/....For non-GitHub trackers, also detect the tracker base URL and the project key prefix (e.g. BP, ABC, ENG).
API:, CLI:, Auth:). If none exist, propose labels that match the project's top-level directory or package layout. The human reviewer will correct any that are wrong.Use the detected values everywhere a project key, tracker URL, or GitHub URL is needed. If a constant cannot be determined with confidence, ask the user once before proceeding. Do not guess or invent values.
CHANGELOG.md, if it exists, lives at the repository root. Read it first. If the file does not exist, create it from assets/changelog-template.md (see Step 5).
The merged PR is the atomic unit of a changelog entry - not the commit. A single PR often contains the feature commit, follow-up fixes, review feedback, test additions, and docs updates. These are one logical change and produce one changelog bullet. Never split a PR's commits into separate entries.
#### 2a: Identify the release window
# Last tag, its date (window start), and recent tags for context
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
git log -1 --format="%ai" "$LAST_TAG"
git tag --sort=-version:refname | head -10If no tags exist, treat the entire git history as the unreleased window. The release window is: tag date (exclusive) → today.
#### 2b: List merged PRs in the window
Primary: milestone-based (when the project sets milestones on PRs; replace MILESTONE_PREFIX with the prefix the project uses, e.g. M10):
gh pr list --state merged --limit 100 \
--json number,title,mergedAt,milestone,labels \
--jq '.[] | select(.milestone != null and (.milestone.title | startswith("MILESTONE_PREFIX")))
| "\(.number)\t\(.mergedAt | split("T")[0])\t\(.title)"' \
| sort -t$'\t' -k2Fallback: date-based (when milestones are not set; replace YYYY-MM-DD with the tag date):
gh pr list --state merged --limit 200 \
--json number,title,mergedAt,labels \
--jq '.[] | select(.mergedAt >= "YYYY-MM-DDT00:00:00Z")
| "\(.number)\t\(.mergedAt | split("T")[0])\t\(.title)"' \
| sort -t$'\t' -k2For non-GitHub trackers, also fetch resolved tasks within the same window using the tracker's search API or web UI - see references/trackers.md for the section matching the detected tracker.
#### 2c: Inspect individual PRs and link to tracker tasks
# PR title, body (scope/intent), and constituent commits
gh pr view <NUMBER> --json title,body --jq '"\(.title)\n\(.body)"' | head -40
gh pr view <NUMBER> --json commits --jq '.commits[].messageHeadline'Extract issue/task references from the PR body using the extraction commands in references/trackers.md for the tracker detected in Step 1. Read each linked issue/task for the user-facing problem statement: PR titles are implementation-focused, tracker items are user/operator-focused.
Use the PR body's Scope & Context section (when present) to understand the user-facing or operator-facing impact. Do not rely on git log --oneline - it shows commits, not logical changes.
If the user describes changes verbally, use that as the primary source.
The changelog records notable changes to the distributed software. A change is notable when it alters what a consumer of the project can observe: new capabilities, changed behavior, fixed bugs, security patches, removed features, or deprecation notices.
Apply the following filter to every commit or change before writing an entry.
ALWAYS include:
| Signal | Why it matters to consumers |
|---|---|
| New user-facing feature (CLI flag, integration, config option, API surface, UI capability) | Consumers discover new capabilities |
| Changed behavior of existing feature | Consumers must adjust usage |
| Bug fix for incorrect behavior | Consumers know issues are resolved |
| Security or vulnerability fix | Operators must act on upgrades |
| Deprecation of public interface | Consumers prepare for removal |
| Removal of feature or public interface | Consumers must adapt before upgrading |
| Performance improvement with measurable impact | Consumers benefit from upgrading |
| New or changed persistence schema (migration) | Operators plan upgrade procedures |
| Changed CLI flags, env vars, deployment, or config file format | Operators must update deployment config |
NEVER include - these are noise, not signal:
| Noise | Why it does not belong |
|---|---|
| Internal variable/function/type renames | No observable effect on consumers |
| Code formatting, whitespace, linting fixes | No observable effect on consumers |
| Test-only changes (new tests, test refactors) | Not shipped to consumers |
| CI/CD pipeline changes (workflows, actions) | Not shipped to consumers |
Dotfile changes (.gitignore, .github/*, CODEOWNERS) | Not shipped to consumers |
| Documentation-only changes (README, CLAUDE.md, AGENTS.md, comments) | Not shipped to consumers |
| Merge commits | Infrastructure artifact, not a change |
| Internal refactoring with no behavior change | No observable effect on consumers |
| Dev-only dependency bumps | Not shipped to consumers |
| Project scaffolding and repo housekeeping | Not shipped to consumers |
Edge cases - include only when the threshold is met:
| Change | Include when... | Omit when... |
|---|---|---|
| Dependency bump | Major version, security fix, or changed behavior | Routine patch/minor with no user impact |
| Refactoring | It changes observable performance, error messages, or log output | Purely internal restructuring |
| New internal module/package | It introduces a new adapter or public API surface | It reorganizes existing code |
| ADR or architecture doc update | It records a decision that changes system behavior | It clarifies existing behavior |
When in doubt, ask: "If I were a consumer of this project reading this before upgrading, would I need to know this?" If the answer is no, leave it out.
Place every surviving entry under exactly one category:
| Category | When to use |
|---|---|
| Added | New user-facing capability: CLI command, integration, config option, API surface, UI capability |
| Changed | Existing behavior altered in a way consumers can observe |
| Deprecated | Still works but scheduled for removal in a future version |
| Removed | Previously available feature or interface deleted |
| Fixed | Bug fix - incorrect behavior corrected |
| Security | Vulnerability patch, dependency CVE fix |
Writing rules:
#NNN or bare tracker keys are not clickable in rendered markdown). When a tracker issue/task is linked from the PR, reference the issue/task only - not also the PR. When multiple distinct issues/tasks are linked, list all of them. See references/trackers.md for the URL format matching the detected tracker.coroutine 'main' was never awaited bug after async migration" not "Fixed async bug".API:, CLI:, Auth:, Dashboard:).Use assets/changelog-template.md as the structural template when creating CHANGELOG.md from scratch or adding the first versioned section. The template covers the preamble, [Unreleased] placeholder, a versioned section, and bottom comparison links.
Structural rules:
[Unreleased] section always present at the top.YYYY-MM-DD).### Removed if nothing was removed).When cutting a release, choose the version number:
| Bump | Trigger |
|---|---|
| Major | Breaking API/CLI change for users or operators, removed public functionality |
| Minor | New feature, backward-compatible behavior change |
| Patch | Bug fix, security patch |
To cut a release:
## [Unreleased] with ## [X.Y.Z] - YYYY-MM-DD.## [Unreleased] section above it.#NNN.https://github.com/OWNER/REPO/issues/NNN links are present in the changelog.| Problem | Fix |
|---|---|
| Missing comparison links | Reconstruct from git tag --sort=-version:refname |
| Duplicate entries | Deduplicate, keep the more descriptive version |
| Entry under wrong category | Move it; if ambiguous, prefer Changed over Added |
| No tags in repository | Use commit SHAs in comparison links as a temporary measure |
| Noise entry slipped in | Remove it - a leaner changelog is more trustworthy |
| Anti-pattern | Why it's wrong | Correct approach |
|---|---|---|
| One entry per commit | Commits are implementation steps, not logical changes. A 6-commit PR produces one changelog bullet. | Use gh pr list to enumerate PRs; write one bullet per logical change. |
Using git log --oneline as the primary source | Produces commit-level noise: test commits, review feedback, merge commits, formatting fixes. | Query merged PRs via gh pr list --state merged filtered by milestone or date range since the last git tag. |
Plain #NNN references | Not clickable in rendered markdown - readers must manually construct the URL to navigate to the change. | Use full URLs (see references/trackers.md). |
| Including both the issue/task and the PR in one bullet | Doubles the noise and misleads the reader: the issue/task already describes the user-visible problem, the PR is its implementation. | Reference the issue/task only when one exists; fall back to the PR only when no issue/task is available. |
Bare tracker keys (e.g. BP-123, ENG-42) | Not clickable; readers cannot navigate to the task without knowing the tracker URL. | Use the full tracker URL (see references/trackers.md). |
| GitHub Issue links in changelog when the project's tracker is not GitHub Issues | The detected tracker is the authoritative source for task references. Adding /issues/NNN links is misleading and breaks over time as the GitHub Issues tab is unused. | Use tracker links for all task references; GitHub links remain only for PRs. |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.