Skip to content

Hold commits to the rules in one awk pass - #480

Merged
jserv merged 3 commits into
mainfrom
refine-scripts
Oct 25, 2026
Merged

jserv merged 3 commits into
mainfrom
refine-scripts

Conversation

@jserv

@jserv jserv commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

The commit-msg hook now holds a message to Chris Beams' seven rules in one POSIX awk pass instead of a pipeline of sed, grep and tr: a hook run drops from 119 ms to 50 ms in the editor and 12 ms for a stored message, and replaying 150 commits through check-commit-log.sh from 21.2 s to 5.5 s on this machine. It also refuses what maintainers have been asking for by hand in review: an AI attribution, a subject that only names a file such as "Update web/app.js" (the message says why), and a Refs line standing as the last line, with Close #N preferred and Closes #N accepted. A link or file name longer than a line, and a trailer, may run past 72 columns. CONTRIBUTING.md states the seven rules, shows an example and describes all of this, and the skill docs agree.

The exit status adds up what is wrong (1 a style rule, 2 a credit to a tool, 4 unreadable input), so hygiene.sh and check-commit-log.sh ask the same hook and agent-marker.jq is deleted. A new --stored flag judges a message a commit already holds, so a scissors-looking line cannot hide a trailer and the CRLF from GitHub's web editor is tolerated. The three copies of the server-readiness loop become scripts/wait-for-server.sh, and the gate parses scripts with dash where it is installed, since macOS sh accepts an array, a here-string and the function keyword that dash refuses (neither parser objects to [[ or local; shellcheck, which CI installs, does).

The series is three commits, each revertible on its own and passing its own checks: the shared server wait, the dash lane, and the hook. Checked with scripts/test-git-hooks.sh (250 checks, under sh, dash and gawk), the Python and Rust tests for the helpers, shellcheck and the formatter. Replaying 400 commits through the old and new hook, 399 agree; the one that differs ends on a Refs line, as intended. The file-only rule refuses none of the 767 non-merge commits here and does refuse the "Update web/interview.js" commit in #469. ./scripts/test.sh passes every lane except browser-tests, which also fails on an untouched checkout of the base (45 tests there, 43 here, different sets); nothing under web/ changes.

Left out: the Actions steps that set shell: bash, which rely on its pipefail and cannot be run here, and mawk, which was not available to test (the awk avoids regex intervals and gawk-only features for it).

jserv added 3 commits October 25, 2026 18:34
browser-check.sh, server-check.sh and visual-parity-check.sh each
carried a copy of the loop that waits for the server they start, with
three limits and three ideas of what to print when it ran out. They now
source scripts/wait-for-server.sh. It holds to its limit in wall time,
cuts each probe off after five seconds so a server that accepts a
connection and never replies cannot hold it past the limit, and gives
up at once when the server process has already exited, printing the log
that says why.
macOS sh is bash in POSIX mode, so sh -n there accepts an array
assignment, a here-string and the function keyword that dash refuses,
and the syntax lane passed scripts that the sh on Debian and Ubuntu
cannot run. The gate now asks dash first where it exists. Neither
parser objects to [[ or local, which only shellcheck sees.
The commit-msg rules were a pipeline of sed, grep and tr that cost 37
commands per message and left three gaps that maintainers filled by
hand. They now run as one POSIX awk pass behind a status that adds up
what is wrong: a broken rule, a credit to an AI tool, or both. The hook
refuses an AI attribution, a subject that only names a file such as
"Update web/app.js" and says why, and a Refs line standing where the
closing line goes. A link, a file name or a trailer may run past 72
columns. Close #N is the preferred closing line and Closes #N is
accepted. A tool is recognized by its address or by a name no person
shares: a co-author called Devin or Jules with an ordinary address is
left alone. check-commit-log.sh and the PR sweep ask the same hook, with
--stored for a message a commit already holds, so agent-marker.jq goes.
CONTRIBUTING.md states the seven rules and the skills that described
the old behavior now agree with it.
@jserv
jserv merged commit 9be0a78 into main Oct 25, 2026
11 checks passed
@jserv
jserv deleted the refine-scripts branch October 25, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant