chore(cleanup): ASCII-only sweep + .keep audit (closes #149 + #150 + #151) #161

Merged
quartermaster merged 1 commit from i/cleanup-pre-v1-unicode-keep into main 2026-06-27 02:29:39 +02:00

Summary

Pre-1.0 cleanup-bundle Sprint 1: mechanical Unicode → ASCII sweep across code paths + tests/.keep removal + AGENTS.md sections 11/12 codifying the disciplines.

Closes #149 (workflow YAML Unicode), #150 (compose-scripts + bats Unicode), #151 (.keep audit).

Substitutions (ASCII discipline)

Unicode ASCII Occurrences
em-dash - 171
right-arrow -> 198
α Greek alpha alpha 19
γ Greek gamma gamma 12
§ section sign section 7
× multiply x 1
ellipsis ... 1
element-of in 1
not-equal != 1
Total ~411

The path-alpha / path-gamma jargon (ADR-0007) becomes spelled in code paths; the ADR documents themselves retain the Greek letters.

Scope vs tracker inventory

Honest expansion: the trackers' inventories listed ~319 occurrences across ~23 files; the actual in-spirit sweep covers ~411 occurrences across 30 files, because the inventory missed:

  • scripts/check-self-bootstrap.sh (added per #124, recently merged)
  • scripts/setup-bump-labels.sh
  • tests/check-self-bootstrap.bats
  • The three secondary workflow YAMLs (_manifest-check.yml, manifest-check.yml, check-self-bootstrap.yml)

Choosing the wider scope keeps the "ASCII-only in code paths" discipline consistent rather than leaving a Unicode patch on the secondary workflows.

Files touched

  • 5 workflow YAMLs in .forgejo/workflows/
  • 14 scripts in scripts/ (incl. scripts/lib/)
  • 12 bats tests in tests/
  • tests/.keep deleted (no longer load-bearing — 13 bats files now)
  • AGENTS.md — new sections 11 (ASCII discipline) + 12 (load-bearing .keep)

Preserved: changelog.d/.keep (LOAD-BEARING per release-prep.sh:364 delete_fragments changelog.d after each cut), examples/go-project/.keep + examples/node-project/.keep (deferred to #152).

Verification

  • Bats: 361/361 pass locally (no behavioral change — substitutions are in comments, log strings, and bats assertion patterns. Scripts + bats updated in lockstep so assertions tracking script output stay aligned.)
  • Unicode-free verification: post-sweep grep across all 30 scoped files confirms none of the 9 characters remain.
  • ADR docs + docs/ + AGENTS.md (existing content) + README.md + CHANGELOG.md + decisions/ UNTOUCHED — verified via git diff --stat.

Decision-tree

  • Why ASCII-only in code paths but not ADRs/docs? Forgejo's workflow YAML lint flags ambiguous Unicode (look-alike security concern). Bats assertions track script log output → both must change in lockstep, easier as ASCII. Look-alike-character security applies to code interpretation. Docs/ADRs render in browser fonts where em-dash vs hyphen distinction is intentional typography; no parser interprets the chars.
  • Why bundle scripts + bats + workflows + .keep? All four are mechanical cleanups gated by AGENTS.md section 2 (compose-script touches → re-pin needed). One PR → one re-pin → one cut. Splitting into 4 PRs would trigger 4 re-pin cycles.
  • - (single hyphen), not -- (double)? The trackers list - as primary with -- only "where the em-dash separates clauses." In practice, em-dash usage was almost entirely intra-sentence punctuation where single hyphen reads cleanly with surrounding spaces (a — ba - b).
  • §section (full word), not sec.? Reads more naturally inline: AGENTS.md section 2 flows better than AGENTS.md sec. 2. Cost: 4 extra characters per occurrence (7 total instances). Worth the readability.

Composition with AGENTS.md section 2

This PR touches compose-scripts in the AGENTS.md section 2 mechanism-of-touch list. In-cycle re-pin required before the next cut. The #124 backstop will fire red on push:main until a re-pin PR lands (expected behavior, not a defect — see AGENTS.md section 2.3).

Re-pin sequencing for v0.11.1 cut:

  1. Merge this PR
  2. Tag v0.11.1-rc.1 at post-merge HEAD
  3. Re-pin .forgejo/workflows/release.yml @v0.11.1-rc.1
  4. Push:main fires release.yml at new ref → rolling PR for v0.11.1

What this PR does NOT do

  • Does NOT touch ADRs, docs/, AGENTS.md (existing prose), README.md, CHANGELOG.md, or fragment files — Unicode latitude preserved there
  • Does NOT add an automated lint regression guard — out of scope; AGENTS.md section 11 codifies the discipline at PR-author surface
  • Does NOT touch the examples/*/.keep files — those follow from #152's resolution (populate vs retire)
  • Does NOT change runtime behavior — substitutions are in comments + log output text + bats assertion patterns

Refs

  • Operator engagement 2026-06-27 (the Forgejo YAML lint warning that surfaced the sweep)
  • AGENTS.md section 2 (mechanism-of-touch — applies post-merge)
  • #124 backstop (will surface red on push:main until re-pin)
  • Sister sprints: Sprint 4 (#148 + #155 bake + naming), Sprint 5 (#156 + #158 audits)
  • New AGENTS.md sections: 11 (ASCII discipline), 12 (load-bearing .keep)
## Summary Pre-1.0 cleanup-bundle Sprint 1: mechanical Unicode → ASCII sweep across code paths + tests/.keep removal + AGENTS.md sections 11/12 codifying the disciplines. Closes #149 (workflow YAML Unicode), #150 (compose-scripts + bats Unicode), #151 (.keep audit). ## Substitutions (ASCII discipline) | Unicode | ASCII | Occurrences | |---|---|---| | `—` em-dash | `-` | 171 | | `→` right-arrow | `->` | 198 | | `α` Greek alpha | `alpha` | 19 | | `γ` Greek gamma | `gamma` | 12 | | `§` section sign | `section` | 7 | | `×` multiply | `x` | 1 | | `…` ellipsis | `...` | 1 | | `∈` element-of | `in` | 1 | | `≠` not-equal | `!=` | 1 | | **Total** | | **~411** | The `path-alpha` / `path-gamma` jargon (ADR-0007) becomes spelled in code paths; the ADR documents themselves retain the Greek letters. ## Scope vs tracker inventory Honest expansion: the trackers' inventories listed ~319 occurrences across ~23 files; the actual in-spirit sweep covers ~411 occurrences across **30 files**, because the inventory missed: - `scripts/check-self-bootstrap.sh` (added per #124, recently merged) - `scripts/setup-bump-labels.sh` - `tests/check-self-bootstrap.bats` - The three secondary workflow YAMLs (`_manifest-check.yml`, `manifest-check.yml`, `check-self-bootstrap.yml`) Choosing the wider scope keeps the "ASCII-only in code paths" discipline consistent rather than leaving a Unicode patch on the secondary workflows. ## Files touched - 5 workflow YAMLs in `.forgejo/workflows/` - 14 scripts in `scripts/` (incl. `scripts/lib/`) - 12 bats tests in `tests/` - `tests/.keep` deleted (no longer load-bearing — 13 bats files now) - `AGENTS.md` — new sections 11 (ASCII discipline) + 12 (load-bearing `.keep`) **Preserved**: `changelog.d/.keep` (LOAD-BEARING per `release-prep.sh:364` `delete_fragments changelog.d` after each cut), `examples/go-project/.keep` + `examples/node-project/.keep` (deferred to #152). ## Verification - Bats: **361/361 pass** locally (no behavioral change — substitutions are in comments, log strings, and bats assertion patterns. Scripts + bats updated in lockstep so assertions tracking script output stay aligned.) - Unicode-free verification: post-sweep grep across all 30 scoped files confirms none of the 9 characters remain. - ADR docs + `docs/` + `AGENTS.md` (existing content) + `README.md` + `CHANGELOG.md` + `decisions/` UNTOUCHED — verified via `git diff --stat`. ## Decision-tree - **Why ASCII-only in code paths but not ADRs/docs?** Forgejo's workflow YAML lint flags ambiguous Unicode (look-alike security concern). Bats assertions track script log output → both must change in lockstep, easier as ASCII. Look-alike-character security applies to code interpretation. Docs/ADRs render in browser fonts where em-dash vs hyphen distinction is intentional typography; no parser interprets the chars. - **Why bundle scripts + bats + workflows + .keep?** All four are mechanical cleanups gated by AGENTS.md section 2 (compose-script touches → re-pin needed). One PR → one re-pin → one cut. Splitting into 4 PRs would trigger 4 re-pin cycles. - **`—` → `-` (single hyphen), not `--` (double)?** The trackers list `-` as primary with `--` only "where the em-dash separates clauses." In practice, em-dash usage was almost entirely intra-sentence punctuation where single hyphen reads cleanly with surrounding spaces (`a — b` → `a - b`). - **`§` → `section` (full word), not `sec.`?** Reads more naturally inline: `AGENTS.md section 2` flows better than `AGENTS.md sec. 2`. Cost: 4 extra characters per occurrence (7 total instances). Worth the readability. ## Composition with AGENTS.md section 2 This PR touches compose-scripts in the AGENTS.md section 2 mechanism-of-touch list. **In-cycle re-pin required** before the next cut. The #124 backstop will fire red on `push:main` until a re-pin PR lands (expected behavior, not a defect — see AGENTS.md section 2.3). Re-pin sequencing for v0.11.1 cut: 1. Merge this PR 2. Tag `v0.11.1-rc.1` at post-merge HEAD 3. Re-pin `.forgejo/workflows/release.yml` `@v0.11.1-rc.1` 4. Push:main fires `release.yml` at new ref → rolling PR for v0.11.1 ## What this PR does NOT do - Does NOT touch ADRs, `docs/`, `AGENTS.md` (existing prose), `README.md`, `CHANGELOG.md`, or fragment files — Unicode latitude preserved there - Does NOT add an automated lint regression guard — out of scope; AGENTS.md section 11 codifies the discipline at PR-author surface - Does NOT touch the `examples/*/.keep` files — those follow from #152's resolution (populate vs retire) - Does NOT change runtime behavior — substitutions are in comments + log output text + bats assertion patterns ## Refs - Operator engagement 2026-06-27 (the Forgejo YAML lint warning that surfaced the sweep) - AGENTS.md section 2 (mechanism-of-touch — applies post-merge) - #124 backstop (will surface red on push:main until re-pin) - Sister sprints: Sprint 4 (#148 + #155 bake + naming), Sprint 5 (#156 + #158 audits) - New AGENTS.md sections: 11 (ASCII discipline), 12 (load-bearing `.keep`)
chore(cleanup): ASCII-only sweep + .keep audit (#149 + #150 + #151)
Some checks failed
check-self-bootstrap / check (pull_request) Failing after 4s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
manifest-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (push) Failing after 3s
release / decide + act (push) Successful in 4s
release / release (push) Successful in 0s
1e7bbf129c
Closes #149 (workflow YAML Unicode).
Closes #150 (compose-scripts + bats Unicode).
Closes #151 (.keep audit).

Mechanical Unicode -> ASCII substitution across 30 files
(5 workflow YAMLs + 14 scripts + 12 bats tests):
- em-dash -> hyphen, right-arrow -> "->", alpha/gamma -> spelled,
  section sign -> "section", multiply -> "x", ellipsis -> "...",
  element-of -> "in", not-equal -> "!="

The path-alpha / path-gamma jargon (ADR-0007) becomes spelled in code
paths; the ADR documents themselves retain the Greek letters.

Drop tests/.keep (directory has 13 bats files; .keep no longer
load-bearing). Preserve changelog.d/.keep (LOAD-BEARING per
release-prep.sh delete_fragments after each cut) and
examples/*/.keep (deferred to #152 examples-populate sprint).

AGENTS.md section 11 codifies the ASCII discipline; section 12
documents changelog.d/.keep's load-bearing nature.

Bats: 361/361 pass (no behavioral change; substitutions only in
comments + log strings + bats assertion patterns, updated in
lockstep).

Composition with AGENTS.md section 2 (mechanism-of-touch): this PR
touches compose-scripts on the section 2 list. In-cycle re-pin
required before the next cut; #124 backstop will fire red on
push:main until the re-pin PR lands.

Scope note vs tracker inventory: the actual sweep covers ~410
occurrences across 30 files (vs the trackers' ~319 across ~23
files), because the inventory missed scripts/check-self-bootstrap.sh,
scripts/setup-bump-labels.sh, tests/check-self-bootstrap.bats, and
the three secondary workflow YAMLs (_manifest-check.yml,
manifest-check.yml, check-self-bootstrap.yml). Honest scope-expansion
in the spirit of the cleanup.
surveyor approved these changes 2026-06-27 02:28:49 +02:00
surveyor left a comment

APPROVED — ASCII sweep + .keep audit (head 1e7bbf1, official/gating)

Mechanical sweep, but I verified the two load-bearing claims at source and both hold. Honestly scoped, well-codified. FF-feasible, 361/361. Clean opener for the pre-1.0 wave.

ASCII scope — honestly bounded, in-scope complete

§11 declares the boundary precisely: code-paths (scripts/*.sh, tests/*.bats, .forgejo/workflows/*.yml) ASCII-only; markdown (AGENTS.md, docs/, README, CHANGELOG) + fragments keep Unicode latitude. Verified at source: a grep -P '[^\x00-\x7F]' across scripts/ tests/ .forgejo/ returns only .forgejo/pull_request_template.md — which is markdown, not a workflow YAML, so it's correctly out of scope (same class as AGENTS.md's 60 Unicode lines). So the in-scope trees are fully ASCII-clean, and the residuals aren't misses — they're the declared boundary. The rationale lands too: the lint-security + bats-lockstep + look-alike concerns apply to parsed code-paths, not rendered docs, so "code ASCII / docs Unicode" is the right cut, not an arbitrary one. The honest-expansion (411 swept vs trackers' 319 — incl. check-self-bootstrap.sh/.bats + setup-bump-labels.sh + the 3 secondary YAMLs) is exactly the thoroughness I'd want: swept what's actually in-scope, not just what the trackers enumerated.

changelog.d/.keep load-bearing — verified against the contract

The §12 claim isn't hand-waved; it's true against the actual code. delete_fragments() (fragments.sh:477) does rm -f -- "$path" only over list_fragments "$dir" — i.e. files matching the fragment glob. .keep doesn't match, so it survives the post-cut sweep. Without it, changelog.d/ goes empty after the first cut → vanishes from git (no empty-dir tracking) → the documented first-cut bootstrap (touch changelog.d/.keep, integration.md Step 2) loses its anchor. So .keep is genuinely load-bearing, and §12 documents why (the glob-non-match) rather than just that. Correct.

.keep audit — right calls

  • tests/.keep dropped: safe — tests/ has real .bats files holding the dir; §12 documents the removal-once-populated rule. ✓
  • examples/*/.keep deferred to #152: correct (the dir-populate is the natural place to retire them). ✓
  • The PR-author-time discipline in §12 ("add a dir that transits empty states → add .keep AND document load-bearing-ness here") is the right embodied-not-re-caught placement.

bats lockstep

361/361 — the sweep converted Unicode in log() strings AND the matching [[ "$output" == *"..."* ]] bats assertions in lockstep, so nothing silently broke. That lockstep risk is exactly what §11 names as a rationale, and the green confirms it was handled.

Nit (non-blocking): §12's delete_fragments ... (line 364 as of 2026-06-27) line-ref will drift, but it's hedged with the date AND anchored on the function name — resilient enough. Leave it.

Closes #149/#150/#151. Clean to self-merge → v0.11.1 cut via the §2 re-pin path. Good Sprint-1 of the wave — mechanical in substance, but the scope-honesty and the load-bearing-marker discipline are the parts that'll pay forward. 🎯

## APPROVED — ASCII sweep + .keep audit (head 1e7bbf1, official/gating) Mechanical sweep, but I verified the two load-bearing claims at source and both hold. Honestly scoped, well-codified. FF-feasible, 361/361. Clean opener for the pre-1.0 wave. ### ASCII scope — honestly bounded, in-scope complete ✅ §11 declares the boundary precisely: code-paths (`scripts/*.sh`, `tests/*.bats`, `.forgejo/workflows/*.yml`) ASCII-only; markdown (`AGENTS.md`, `docs/`, `README`, `CHANGELOG`) + fragments keep Unicode latitude. Verified at source: a `grep -P '[^\x00-\x7F]'` across `scripts/ tests/ .forgejo/` returns **only** `.forgejo/pull_request_template.md` — which is markdown, not a workflow YAML, so it's correctly *out* of scope (same class as AGENTS.md's 60 Unicode lines). So the in-scope trees are fully ASCII-clean, and the residuals aren't misses — they're the declared boundary. The rationale lands too: the lint-security + bats-lockstep + look-alike concerns apply to *parsed* code-paths, not *rendered* docs, so "code ASCII / docs Unicode" is the right cut, not an arbitrary one. The honest-expansion (411 swept vs trackers' 319 — incl. check-self-bootstrap.sh/.bats + setup-bump-labels.sh + the 3 secondary YAMLs) is exactly the thoroughness I'd want: swept what's actually in-scope, not just what the trackers enumerated. ### `changelog.d/.keep` load-bearing — verified against the contract ✅ The §12 claim isn't hand-waved; it's true against the actual code. `delete_fragments()` (fragments.sh:477) does `rm -f -- "$path"` only over `list_fragments "$dir"` — i.e. files matching the fragment glob. `.keep` doesn't match, so it survives the post-cut sweep. Without it, `changelog.d/` goes empty after the first cut → vanishes from git (no empty-dir tracking) → the documented first-cut bootstrap (`touch changelog.d/.keep`, integration.md Step 2) loses its anchor. So `.keep` is genuinely load-bearing, and §12 documents *why* (the glob-non-match) rather than just *that*. Correct. ### .keep audit — right calls - `tests/.keep` dropped: safe — `tests/` has real `.bats` files holding the dir; §12 documents the removal-once-populated rule. ✓ - `examples/*/.keep` deferred to #152: correct (the dir-populate is the natural place to retire them). ✓ - The PR-author-time discipline in §12 ("add a dir that transits empty states → add `.keep` AND document load-bearing-ness here") is the right embodied-not-re-caught placement. ### bats lockstep ✅ 361/361 — the sweep converted Unicode in `log()` strings AND the matching `[[ "$output" == *"..."* ]]` bats assertions in lockstep, so nothing silently broke. That lockstep risk is exactly what §11 names as a rationale, and the green confirms it was handled. Nit (non-blocking): §12's `delete_fragments ... (line 364 as of 2026-06-27)` line-ref will drift, but it's hedged with the date AND anchored on the function name — resilient enough. Leave it. Closes #149/#150/#151. Clean to self-merge → v0.11.1 cut via the §2 re-pin path. Good Sprint-1 of the wave — mechanical in substance, but the scope-honesty and the load-bearing-marker discipline are the parts that'll pay forward. 🎯
Sign in to join this conversation.
No description provided.