-
-
Notifications
You must be signed in to change notification settings - Fork 0
fix: replace a literal NUL with the jq backslash-u0000 escape #682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f6accdf
c5912a1
0966e4e
a4d9ea1
42a3a8a
f87c2ca
ca84e05
de36809
b6459fb
7b8b6fb
de339dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,81 @@ | ||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||
| # Language-policy drift gate. | ||||||||||||||
| # | ||||||||||||||
| # WHY THIS EXISTS. The estate's language policy is duplicated into ~372 per-repo | ||||||||||||||
| # `.claude/CLAUDE.md` files across 131 repos. On 2026-08-26 a census found 868 of them | ||||||||||||||
| # still listed **Bun as BANNED** with Deno as its replacement - the exact inverse of the | ||||||||||||||
| # standing ruling - and nothing had ever detected it. Correcting `standards` fixes one copy; | ||||||||||||||
| # agents read the local one. | ||||||||||||||
| # | ||||||||||||||
| # WHY ASSERTIONS, NOT A DIFF. The copies are legitimately not identical: repos carry their | ||||||||||||||
| # own exemption tables, architecture notes and carve-outs. A byte-for-byte generator would | ||||||||||||||
| # be permanently red. So this gate asserts the INVARIANTS the policy must satisfy, whatever | ||||||||||||||
| # the surrounding wording. | ||||||||||||||
| # | ||||||||||||||
| # Exit 0 = compliant. Exit 1 = drift. Every failure prints file:line. | ||||||||||||||
| set -uo pipefail | ||||||||||||||
| status=0 | ||||||||||||||
| files=$(git ls-files '*CLAUDE.md' 2>/dev/null | grep -v node_modules) | ||||||||||||||
| [ -z "$files" ] && { echo "no CLAUDE.md tracked - nothing to check"; exit 0; } | ||||||||||||||
|
Check failure on line 19 in tools/policy/check-language-policy.sh
|
||||||||||||||
|
|
||||||||||||||
| fail(){ printf ' \033[31mFAIL\033[0m %s\n %s\n' "$1" "$2"; status=1; } | ||||||||||||||
|
Check warning on line 21 in tools/policy/check-language-policy.sh
|
||||||||||||||
|
|
||||||||||||||
| for f in $files; do | ||||||||||||||
| echo "checking $f" | ||||||||||||||
|
|
||||||||||||||
| # --- must NOT appear ------------------------------------------------------- | ||||||||||||||
| # 1. Bun banned. This is the inversion that went undetected across 868 files. | ||||||||||||||
| if grep -nF -- '| Bun | Deno |' "$f" >/dev/null; then | ||||||||||||||
| fail "$f:$(grep -nF -- '| Bun | Deno |' "$f" | head -1 | cut -d: -f1)" \ | ||||||||||||||
| 'Bun is listed as BANNED with Deno as replacement - inverted. Bun is tier 1.' | ||||||||||||||
| fi | ||||||||||||||
| # 2. The rule that told repos not to declare dependencies at all. hyperpolymath/ubicity | ||||||||||||||
| # a phrase inside a blockquote or quotation marks is HISTORY, not policy | ||||||||||||||
| live(){ grep -vE '^[[:space:]]*>' "$1" | grep -vE '"[^"]*'"$2"'[^"]*"|“[^”]*'"$2"'[^”]*”'; } | ||||||||||||||
|
Check warning on line 34 in tools/policy/check-language-policy.sh
|
||||||||||||||
| # imported zod and glob, shipped no manifest, and could not build under ANY toolchain. | ||||||||||||||
| if live "$f" 'No package.json for runtime deps' | grep -qF 'No package.json for runtime deps'; then | ||||||||||||||
| fail "$f:$(grep -nF 'No package.json for runtime deps' "$f" | head -1 | cut -d: -f1)" \ | ||||||||||||||
| 'Forbids declaring dependencies. Bun is npm-compatible; a manifest is REQUIRED.' | ||||||||||||||
| fi | ||||||||||||||
| if live "$f" 'deno.json imports' | grep -qF 'deno.json imports'; then | ||||||||||||||
| fail "$f:$(grep -nF 'deno.json imports' "$f" | head -1 | cut -d: -f1)" \ | ||||||||||||||
| 'Directs dependency declaration into deno.json. Use package.json + bun.lock.' | ||||||||||||||
| fi | ||||||||||||||
| # 3. No tool description may advertise TypeScript. Owner ruling 2026-08-27: | ||||||||||||||
| # "no typescript ... that should not exist at all." | ||||||||||||||
| if grep -nE 'Executes .\.ts. directly|JS/TS runtime' "$f" >/dev/null; then | ||||||||||||||
| fail "$f:$(grep -nE 'Executes .\.ts. directly|JS/TS runtime' "$f" | head -1 | cut -d: -f1)" \ | ||||||||||||||
| 'Advertises TypeScript execution. TypeScript is banned; do not describe tools as TS runtimes.' | ||||||||||||||
|
Comment on lines
+46
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Enforce the complete TypeScript prohibition. This matcher detects only 🤖 Prompt for AI Agents |
||||||||||||||
| fi | ||||||||||||||
| # 4. Blanking scars. A bulk purge substituted a token with an EMPTY STRING, which also | ||||||||||||||
| # produced `rm -rf /lib` in wordpress-tools (the lethal shape is <token>/path -> /path). | ||||||||||||||
| if awk -F'|' 'NF>=4 && $2 ~ /^[[:space:]]*$/{exit 0} END{exit 1}' "$f"; then | ||||||||||||||
| fail "$f" 'Policy table row with an EMPTY first cell - blanking scar from a bulk substitution.' | ||||||||||||||
| fi | ||||||||||||||
|
Comment on lines
+52
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Fix the
Proposed fix- if awk -F'|' 'NF>=4 && $2 ~ /^[[:space:]]*$/{exit 0} END{exit 1}' "$f"; then
+ if awk -F'|' 'NF>=4 && $2 ~ /^[[:space:]]*$/{found=1} END{exit !found}' "$f"; then📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| if grep -nF '| **** |' "$f" >/dev/null; then | ||||||||||||||
| fail "$f:$(grep -nF '| **** |' "$f" | head -1 | cut -d: -f1)" \ | ||||||||||||||
| 'Empty bold cell (****) - the language name was blanked out.' | ||||||||||||||
| fi | ||||||||||||||
| if grep -nE '\*\*No new +files\*\*|Only where +cannot' "$f" >/dev/null; then | ||||||||||||||
| fail "$f" 'Enforcement rule with a blanked language name.' | ||||||||||||||
| fi | ||||||||||||||
| # 5. A rule may not ban the language it mandates. | ||||||||||||||
| if grep -nE '^\| AffineScript \| AffineScript \|' "$f" >/dev/null; then | ||||||||||||||
| fail "$f" 'BANNED table maps AffineScript to itself - it bans the mandated language.' | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # --- must appear, if the file carries a language-policy table --------------- | ||||||||||||||
| if grep -qE '^### (ALLOWED|BANNED)' "$f"; then | ||||||||||||||
| { grep -qE '^\|[[:space:]]*\*\*Bun\*\*[[:space:]]*\|' "$f" || grep -qiE '^[-*][[:space:]]+\*{0,2}Bun\*{0,2}\b' "$f"; } || \ | ||||||||||||||
| fail "$f" 'No Bun row in ALLOWED. Bun is the tier-1 JS runtime and package manager.' | ||||||||||||||
| { grep -qE '^\|[[:space:]]*\*{0,2}Deno\*{0,2}[[:space:]]*\|[[:space:]]*\*{0,2}Bun\*{0,2}[[:space:]]*\|' "$f" || grep -qiE '^[-*][[:space:]]+Deno[[:space:]]*\(use Bun\)' "$f"; } || \ | ||||||||||||||
| fail "$f" 'Deno is not listed in BANNED with Bun as its replacement (ruling 2026-08-26).' | ||||||||||||||
| fi | ||||||||||||||
| done | ||||||||||||||
|
|
||||||||||||||
| if [ $status -eq 0 ]; then echo "language policy OK"; else | ||||||||||||||
|
Check failure on line 76 in tools/policy/check-language-policy.sh
|
||||||||||||||
| echo | ||||||||||||||
| echo "Language-policy drift detected. Canonical source: hyperpolymath/standards .claude/CLAUDE.md" | ||||||||||||||
| echo "Fix the local copy; do not weaken this gate." | ||||||||||||||
| fi | ||||||||||||||
| exit $status | ||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,61 @@ | ||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||
| # Fail if any GitHub Actions workflow does not parse. | ||||||||||||||||||
| # | ||||||||||||||||||
| # WHY THIS EXISTS. Measured across the estate on 2026-08-27: **481 workflow files in | ||||||||||||||||||
| # 134 repos do not parse at all**. A workflow that cannot be loaded produces NO check | ||||||||||||||||||
| # run, so it is invisible to `?status=failure` sweeps and to `gh pr checks` — the gate | ||||||||||||||||||
| # simply never runs, and its absence looks exactly like success. | ||||||||||||||||||
| # | ||||||||||||||||||
| # One was root-caused to a literal BACKSPACE byte (0x08) committed inside a regex. | ||||||||||||||||||
| # The other 480 are structural YAML: 245 "mapping values are not allowed in this | ||||||||||||||||||
| # context", 137 "could not find expected ':'", 73 block-mapping errors, 6 unterminated | ||||||||||||||||||
| # quotes. | ||||||||||||||||||
| # | ||||||||||||||||||
| # Exit 0 = every workflow parses. Exit 1 = at least one does not. | ||||||||||||||||||
| set -uo pipefail | ||||||||||||||||||
|
|
||||||||||||||||||
| parser="" | ||||||||||||||||||
| if command -v yq >/dev/null 2>&1; then parser=yq | ||||||||||||||||||
| elif command -v python3 >/dev/null 2>&1 && python3 -c 'import yaml' 2>/dev/null; then parser=python | ||||||||||||||||||
| elif command -v ruby >/dev/null 2>&1; then parser=ruby | ||||||||||||||||||
| else | ||||||||||||||||||
| echo "::warning::no YAML parser available (yq, python3+pyyaml, or ruby) — cannot verify workflows" | ||||||||||||||||||
| exit 0 | ||||||||||||||||||
| fi | ||||||||||||||||||
|
Comment on lines
+21
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Fail closed when no YAML parser is available. The script currently prints a warning and exits 0. CI can therefore report success without checking any workflow, which violates the gate’s exit contract. Return 1, or make one parser an explicit CI prerequisite. Proposed fix else
echo "::warning::no YAML parser available (yq, python3+pyyaml, or ruby) — cannot verify workflows"
- exit 0
+ exit 1
fi📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| parse_ok() { | ||||||||||||||||||
|
Check warning on line 26 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| case "$parser" in | ||||||||||||||||||
|
Check failure on line 27 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| yq) yq '.' "$1" >/dev/null 2>&1 ;; | ||||||||||||||||||
|
Check warning on line 28 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| python) python3 -c 'import sys,yaml; yaml.safe_load(open(sys.argv[1]))' "$1" >/dev/null 2>&1 ;; | ||||||||||||||||||
|
Check warning on line 29 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| ruby) ruby -ryaml -e 'YAML.safe_load(File.read(ARGV[0]), aliases: true)' "$1" >/dev/null 2>&1 ;; | ||||||||||||||||||
|
Check warning on line 30 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| esac | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| status=0; checked=0 | ||||||||||||||||||
| while IFS= read -r f; do | ||||||||||||||||||
| [ -f "$f" ] || continue | ||||||||||||||||||
|
Check failure on line 36 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| checked=$((checked + 1)) | ||||||||||||||||||
| if ! parse_ok "$f"; then | ||||||||||||||||||
| status=1 | ||||||||||||||||||
| printf '::error file=%s::workflow does not parse — it produces NO check run, so this gate never executes\n' "$f" | ||||||||||||||||||
| case "$parser" in | ||||||||||||||||||
|
Check failure on line 41 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| yq) yq '.' "$f" 2>&1 | head -2 | sed 's/^/ /' ;; | ||||||||||||||||||
| python) python3 -c 'import sys,yaml; yaml.safe_load(open(sys.argv[1]))' "$f" 2>&1 | tail -2 | sed 's/^/ /' ;; | ||||||||||||||||||
| ruby) ruby -ryaml -e 'YAML.safe_load(File.read(ARGV[0]), aliases: true)' "$f" 2>&1 | head -2 | sed 's/^/ /' ;; | ||||||||||||||||||
| esac | ||||||||||||||||||
| # control characters are a common, easily-missed cause | ||||||||||||||||||
| if grep -qP '[\x00-\x08\x0B\x0C\x0E-\x1F]' "$f" 2>/dev/null; then | ||||||||||||||||||
| echo " ⚠ contains CONTROL CHARACTERS — YAML forbids them; see empty-linter" | ||||||||||||||||||
| grep -nP '[\x00-\x08\x0B\x0C\x0E-\x1F]' "$f" | head -3 | cat -v | sed 's/^/ /' | ||||||||||||||||||
| fi | ||||||||||||||||||
| fi | ||||||||||||||||||
| done < <(git ls-files '.github/workflows/*.yml' '.github/workflows/*.yaml' '**/.github/workflows/*.yml' '**/.github/workflows/*.yaml' 2>/dev/null | sort -u) | ||||||||||||||||||
|
|
||||||||||||||||||
| if [ "$checked" -eq 0 ]; then echo "no workflows tracked — nothing to check"; exit 0; fi | ||||||||||||||||||
|
Check failure on line 54 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| if [ "$status" -eq 0 ]; then echo "✅ all $checked workflow(s) parse"; else | ||||||||||||||||||
|
Check failure on line 55 in tools/policy/check-workflows-parse.sh
|
||||||||||||||||||
| echo | ||||||||||||||||||
| echo "A workflow that does not parse produces no check run. Its gate has never run," | ||||||||||||||||||
| echo "and its silence is indistinguishable from success. Fix the YAML; do not delete" | ||||||||||||||||||
| echo "the check." | ||||||||||||||||||
| fi | ||||||||||||||||||
| exit $status | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Do not combine
grep -qwithpipefailhere.When the outer
grep -qFfinds the first match, it can close the pipe whileliveis still writing. Withpipefail, the upstreamgrepcan return 141, making the condition false and allowing a prohibited policy phrase through. Consume the complete stream, for example withgrep -F ... >/dev/null.Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 GitHub Check: SonarCloud Code Analysis
[warning] 34-34: Assign this positional parameter to a local variable.
See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBFoc5xe1Z-jWfPM1PE&open=AaBFoc5xe1Z-jWfPM1PE&pullRequest=682
[warning] 34-34: Add an explicit return statement at the end of the function.
See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBFoc5xe1Z-jWfPM1PC&open=AaBFoc5xe1Z-jWfPM1PC&pullRequest=682
[warning] 34-34: Assign this positional parameter to a local variable.
See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBFoc5xe1Z-jWfPM1PF&open=AaBFoc5xe1Z-jWfPM1PF&pullRequest=682
[warning] 34-34: Assign this positional parameter to a local variable.
See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBFoc5xe1Z-jWfPM1PD&open=AaBFoc5xe1Z-jWfPM1PD&pullRequest=682
🤖 Prompt for AI Agents