From 70c1bd359855c3b819f769864bd2d11ab07504a2 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Mon, 18 May 2026 08:59:42 +0200 Subject: [PATCH] drop changelog gate's soft warning, keep 60-word hard cap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 40-word warning never blocked a push, so eight bullets had drifted over it. A warning the gate emits and the process ignores just normalises drift, so it's gone — only the 60-word fail remains. Co-Authored-By: Claude --- .claude/skills/git-commit/SKILL.md | 2 +- CHANGELOG.md | 3 +++ ci/changelog_gate.sh | 32 ++++++++++-------------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/.claude/skills/git-commit/SKILL.md b/.claude/skills/git-commit/SKILL.md index 7d3481d6..1329a255 100644 --- a/.claude/skills/git-commit/SKILL.md +++ b/.claude/skills/git-commit/SKILL.md @@ -55,7 +55,7 @@ Entries should be short imperative phrases that describe user-facing impact — ### Be concise — this is the rule, not a suggestion -CHANGELOG entries must be **one or two short sentences**. Strict ceiling: **40 words per bullet**, hard cap at 60. If you can't say it in one line wrapped at ~75 columns, you're writing the wrong document. +CHANGELOG entries must be **one or two short sentences**. Hard cap: **60 words per bullet** (enforced by `ci/changelog_gate.sh`). Aim for 30 or under; if you can't say it in one line wrapped at ~75 columns, you're writing the wrong document. The CHANGELOG is read by humans scanning for what changed between two versions. It is **not** the place for the rationale, the probe results, the implementation detail, the behavior-change deep dive, or the "see also" cross-references. Those belong in: diff --git a/CHANGELOG.md b/CHANGELOG.md index b8a3c6be..cdfac7e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,6 +111,9 @@ heading, and (b) bumping `pubspec.yaml` `version:` in the same commit. ### Changed +- Changelog gate is binary — dropped the soft 40-word warning, kept + the 60-word hard cap. Warnings that never blocked just normalised + drift. - PTY spawning uses `posix_openpt` + `posix_spawn` instead of `forkpty` — closes a ~5% deadlock window in the multithreaded Dart VM (T-96, D-5 amended). Missing exe/cwd now throw `PtyException` at diff --git a/ci/changelog_gate.sh b/ci/changelog_gate.sh index 0a3252fb..4db7b76d 100755 --- a/ci/changelog_gate.sh +++ b/ci/changelog_gate.sh @@ -1,15 +1,14 @@ #!/usr/bin/env bash -# CHANGELOG concision gate — enforces the per-bullet word caps from the -# git-commit skill (40 soft, 60 hard) across the `## [Unreleased]` -# section. Released sections are frozen and skipped (don't penalize -# historical entries pre-dating the rule). +# CHANGELOG concision gate — enforces a single 60-word per-bullet hard +# cap on the `## [Unreleased]` section. Released sections are frozen +# and skipped (don't penalize historical entries pre-dating the rule). # # A "bullet" is a markdown list item beginning with `- `, including any # indented continuation lines until the next bullet, blank line, or # heading. Word count is whitespace-tokenized. # -# Soft cap 40 → warn (non-zero exit only if HARD is also breached). -# Hard cap 60 → fail. +# A soft 40-word warning was tried earlier and dropped — warnings that +# never block a push just normalise drift, so the gate is now binary. # # Bypass: never. If the rule rejects something genuinely user-visible # that needs more context, the context belongs in the commit body or a @@ -18,7 +17,6 @@ set -euo pipefail cd "$(dirname "$0")/.." CHANGELOG=CHANGELOG.md -SOFT_CAP=40 HARD_CAP=60 if [[ ! -f "$CHANGELOG" ]]; then @@ -26,24 +24,18 @@ if [[ ! -f "$CHANGELOG" ]]; then exit 2 fi -awk -v soft="$SOFT_CAP" -v hard="$HARD_CAP" ' - BEGIN { in_unreleased = 0; bullet = ""; bullet_start = 0; fail = 0; warn = 0 } +awk -v hard="$HARD_CAP" ' + BEGIN { in_unreleased = 0; bullet = ""; bullet_start = 0; fail = 0 } function check_bullet() { if (bullet == "") return - n = split(bullet, _words, /[[:space:]]+/) - # split() counts a trailing empty token when the string starts/ends with - # whitespace; trim the leading "- " marker too. + # Trim the leading "- " marker, then tokenize on whitespace. gsub(/^- +/, "", bullet) n = split(bullet, _words, /[[:space:]]+/) if (n > hard) { - printf "FAIL line %d: bullet is %d words (hard cap %d)\n", bullet_start, n, hard + printf "FAIL line %d: bullet is %d words (cap %d)\n", bullet_start, n, hard printf " %s\n\n", substr(bullet, 1, 120) (length(bullet) > 120 ? "..." : "") fail++ - } else if (n > soft) { - printf "WARN line %d: bullet is %d words (soft cap %d)\n", bullet_start, n, soft - printf " %s\n\n", substr(bullet, 1, 120) (length(bullet) > 120 ? "..." : "") - warn++ } bullet = "" bullet_start = 0 @@ -76,10 +68,6 @@ awk -v soft="$SOFT_CAP" -v hard="$HARD_CAP" ' printf " See .claude/skills/git-commit/SKILL.md \"Be concise\".\n" exit 1 } - if (warn > 0) { - printf "==> changelog gate OK with %d warning(s) over %d words.\n", warn, soft - } else { - printf "==> changelog gate OK\n" - } + printf "==> changelog gate OK\n" } ' "$CHANGELOG"