Skip to content

Commit 9c223cd

Browse files
author
endolinbot
committed
pre-push-gates: no-non-ascii-in-source probe (kriskowal #417 directive)
Per the maintainer's review on endojs/endo-but-for-bots#417 (inline comment r3353301111, 2026-06-04T04:21Z): Avoid non-ASCII. This is in the guide. Dispatch a gardener to revise the driver to have deterministic automation to keep source generally in the ASCII range. The fixer (bb2325) that addressed the four section-sign instances on the PR forwarded the gardener-level ask via journal entry 2026-06-04T04:40Z message-fixer-bb2325. This commit lands the deterministic gate. skills/pre-push-gates/probes/no-non-ascii-in-source.sh (new): scans newly-added lines of packages/<pkg>/src/ and packages/<pkg>/lib/ .js/.ts/.mjs/.cjs files for non-ASCII characters. Reports each finding as file:line: non-ASCII U+XXXX ('char') and exits 1 if any found. Path exclusions: anything not under src/ or lib/ (so test/ and fixtures/ are naturally exempt); per-file opt-out via a /* ascii-exempt */ marker on a line within the first 5 (for the rare case of a UTF-8-round-trip test living under src/). Added-lines precision: the probe uses git diff -U0 + perl to track post-image line numbers and check only the + lines. Pre-existing non-ASCII in unchanged code does not surface; only new introductions fail. skills/pre-push-gates/SKILL.md: probe-table row added with description and provenance. Notes-from-the-field row for 2026-06-04 cites the precipitating PR comment and the fixer message. Composition: the probe runs alongside the existing seven (ascii-banners, pull-citations, inline-import-jsdoc, test-package-no-main, security-md-hash-uniform, filename-no-stutter, sentence-per-line-md) as stage 3 of the pre-push gate. Builder and fixer dispatches that run `pre-push-gates.sh` before pushing now catch this class at push time rather than at maintainer review.
1 parent 5558874 commit 9c223cd

2 files changed

Lines changed: 66 additions & 1 deletion

File tree

skills/pre-push-gates/SKILL.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
created: 2026-05-20
3-
updated: 2026-05-20
3+
updated: 2026-06-04
44
author: gardener
55
---
66

@@ -75,6 +75,7 @@ Probes shipped with the garden today:
7575
| `security-md-hash-uniform` | Every `packages/*/SECURITY.md` has the same SHA-256 hash. | PR #75 `r3223750050` ("dispatch a builder to create a CI rule"). |
7676
| `filename-no-stutter` | No file at `packages/<P>/.../<P>-foo.<ext>` (filename basename does not start with or contain `_<P>_`). | PR #75 `r3223811705`. |
7777
| `sentence-per-line-md` | Markdown files in changed paths use sentence-per-line shape (no multi-sentence physical lines outside of code blocks). | PR #75 `r3270500584` + CONTRIBUTING.md style guide. |
78+
| `no-non-ascii-in-source` | No non-ASCII characters in newly-added lines of `packages/<pkg>/src/` and `packages/<pkg>/lib/` `.js` / `.ts` / `.mjs` / `.cjs` files. Test paths and fixtures excluded by path. Per-file opt-out via a `/* ascii-exempt */` marker on a line within the first 5. | PR #417 inline `r3353301111` (kriskowal 2026-06-04: "Avoid non-ASCII. This is in the guide. Dispatch a gardener to revise the driver to have deterministic automation to keep source generally in the ASCII range."). |
7879

7980
Each probe is small (typically 5 to 30 lines of shell or awk). A new probe is one new script in `probes/`; the driver picks it up by glob.
8081

@@ -145,3 +146,5 @@ The driver does not need to know about the new probe; it walks `probes/*.sh` at
145146
(Append; terse and dated.)
146147

147148
- _2026-05-20_: initial bootstrap. The seven probes ship with the skill; provenance traces to PR #75 (six items) and PR #238 (the mermaid rule). The next several PRs through the gamut will exercise the gate; expect new probes to land for patterns the maintainer surfaces that the seven do not catch.
149+
150+
- _2026-06-04_: added `no-non-ascii-in-source` probe per the maintainer's inline review on `endojs/endo-but-for-bots#417` (comment `r3353301111`): *"Avoid non-ASCII. This is in the guide. Dispatch a gardener to revise the driver to have deterministic automation to keep source generally in the ASCII range."* The fixer that addressed the four `§` (U+00A7) instances in `packages/ses/src/permits.js` forwarded the gardener-level ask via `journal/entries/2026/06/04/044044Z-message-fixer-bb2325.md`. The probe is the deterministic gate: future builder, fixer, and weaver pushes that introduce a non-ASCII character in `packages/<pkg>/src/` or `lib/` source fail at the gate. The per-file `/* ascii-exempt */` marker opts out a file that legitimately carries non-ASCII (rare under src/lib; the path glob already excludes the typical UTF-8-round-trip test paths).
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/bin/bash
2+
# no-non-ascii-in-source — reject non-ASCII characters introduced in newly-added
3+
# lines of source code under packages/<pkg>/src/ and packages/<pkg>/lib/. Test
4+
# paths and fixture paths are excluded by glob; individual files that
5+
# legitimately carry non-ASCII (UTF-8 round-trip tests living under src/, etc.)
6+
# opt out via a `/* ascii-exempt */` marker on a line within the first 5.
7+
#
8+
# Provenance: PR endojs/endo-but-for-bots#417 inline r3353301111
9+
# (kriskowal 2026-06-04T04:21Z): "Avoid non-ASCII. This is in the guide.
10+
# Dispatch a gardener to revise the driver to have deterministic automation
11+
# to keep source generally in the ASCII range."
12+
13+
set -uo pipefail
14+
15+
base=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null | sed 's|^origin/||' || echo master)
16+
17+
paths=$(git diff --cached --name-only --diff-filter=AM 2>/dev/null \
18+
| grep -E '^packages/[^/]+/(src|lib)/.*\.(js|ts|mjs|cjs)$' || true)
19+
if [ -z "$paths" ]; then
20+
paths=$(git diff "origin/$base...HEAD" --name-only --diff-filter=AM 2>/dev/null \
21+
| grep -E '^packages/[^/]+/(src|lib)/.*\.(js|ts|mjs|cjs)$' || true)
22+
fi
23+
24+
findings=""
25+
for p in $paths; do
26+
[ -f "$p" ] || continue
27+
# Opt-out marker for files that legitimately carry non-ASCII (rare under
28+
# src/lib; the path glob above already excludes test/ and fixtures/).
29+
if head -5 "$p" 2>/dev/null | grep -qE '/\*[[:space:]]*ascii-exempt[[:space:]]*\*/'; then
30+
continue
31+
fi
32+
diff=$(git diff --cached -U0 -- "$p" 2>/dev/null)
33+
if [ -z "$diff" ]; then
34+
diff=$(git diff "origin/$base...HEAD" -U0 -- "$p" 2>/dev/null)
35+
fi
36+
hits=$(printf '%s\n' "$diff" | perl -CSAD -ne '
37+
BEGIN { our $line = 0; }
38+
if (/^\+\+\+/) { next; }
39+
if (/^@@.*?\+(\d+)/) { $line = $1 - 1; next; }
40+
if (/^\+/) {
41+
$line++;
42+
my $content = substr($_, 1);
43+
if ($content =~ /([^\x00-\x7F])/) {
44+
printf "%d: non-ASCII U+%04X (\x27%s\x27)\n", $line, ord($1), $1;
45+
}
46+
}
47+
')
48+
if [ -n "$hits" ]; then
49+
while IFS= read -r hit; do
50+
findings="$findings$p:$hit
51+
"
52+
done <<< "$hits"
53+
fi
54+
done
55+
56+
if [ -n "$findings" ]; then
57+
printf 'fail: non-ASCII characters in added source lines\n'
58+
printf ' %s' "$findings"
59+
exit 1
60+
fi
61+
echo pass
62+
exit 0

0 commit comments

Comments
 (0)