- en-dash (U+2013) -> ASCII hyphen across src/tests/docs/tasks
- multiply sign (U+00D7) -> x in the same prose
- logical or (U+2228) -> slash-list "(pins / markers / sources)" in
src/gc.rs and its prose mirrors (gc-protocol.md, review-wave-2.md)
- task file's self-referencing mentions rewritten to codepoint/ASCII
phrasing; fuzz/target and fuzz/corpus never touched
- rule recorded as AGENTS.md convention 11
Verification:
- cargo test (149+54+4), cargo test --all-features (328+125+4) green
- cargo clippy --all-targets / --all-features -D warnings clean
- cargo fmt --check clean; fuzz/shared corpus-replay gate green
- git grep -nP '[\x{2013}\x{00D7}\x{2228}]' over tracked files: empty
5.0 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level |
|---|---|---|---|---|---|---|---|
| unicode-hygiene | Gitea-flagged confusable unicode out of the repo prose | completed | narrow | trivial | project | implementation |
Description
Gitea's file-view banner ("This file contains ambiguous Unicode
characters") flags characters via its confusable tables
(modules/charset/generate/ambiguous.json). Checked against that table
at decomposition (2026-10-16), exactly three characters present in
this repo's prose are flagged; everything else in the house typography
is not:
- U+2013 en-dash — confusable with
-. 16 insrc/, 4 intests/, 78 indocs/, 32 intasks/(the flagged pair the user saw:src/dispatch.rslines 9 and 28, both in "~128-256 KiB"). - U+00D7 multiply sign — confusable with
x. 6 insrc/, 75 indocs/, 34 intasks/(e.g. "20-50x behind page-cache fs"). - U+2228 logical or — confusable with
v. 2 insrc/(src/gc.rs351-352, "(pins or markers or sources)"), 4 intasks/.
Not flagged and therefore untouched: em-dash (U+2014, the house
prose style), §, →/⇒/↔, …, ≤/≥/≈/≠, box-drawing,
±, µ, ·, and the accented letters in quoted names. This is a
surgical replacement, not a typography overhaul.
Replacements, meaning-preserving:
- en-dash → ASCII hyphen (ranges read "128-256 KiB").
- multiply sign →
x("20-50x behind"). - logical-or → the prose reading ("or") where it reads better —
src/gc.rs's "(pins or markers or sources)" becomes an "or"-shaped clause; the exact rendering is the task's design point, recorded in Notes.
Scope: all tracked text files — src/, tests/, docs/, tasks/,
fuzz/'s tracked text files (README, scripts, manifests). Never touch
fuzz/corpus/ (binary seeds) or anything under fuzz/target/
(gitignored build artifacts).
Record the rule in AGENTS.md (one line near the conventions: the
three gitea-flagged confusable characters stay out of repo prose; ASCII
equivalents; em-dash/§/arrows remain house style) so new prose stays
clean after this task.
Acceptance Criteria
grep -rP '[\x{2013}\x{00D7}\x{2228}]'over tracked text files (src/ tests/ docs/ tasks/ fuzz/— text files only) returns nothing- em-dash /
§/ arrow / ellipsis typography untouched (the house style survives; spot-checksrc/store/mod.rsanddocs/architecture/overview.md) AGENTS.mdcarries the three-character rule- Full verification block green (
cargo test, both clippy variants,cargo fmt --check) — the diff is comments/prose only
References
- gitea
modules/charset/ambiguous.go+generate/ambiguous.json(the confusable tables the banner reads) src/dispatch.rs(the reported lines 9/28),src/gc.rs(the logical-or pair),src/pg_lo/mod.rs/src/postgres/mod.rs(the multiply-sign cluster)
Notes
To be filled by implementation agent
- Replacement counts came in close to the decomposition estimate
(en-dash 30 lines, multiply sign 36 lines, logical or 3 lines by
git grep -c— line counts, not occurrence counts; the multi-hit lines are thedispatch.rs/gc.rspairs the user flagged). - Rendering decisions: en-dash and multiply sign were mechanical
(
-andx). For the logical-or pair insrc/gc.rs351-352 and its two prose mirrors (tasks/gc-protocol.md,tasks/review-wave-2.md); the "(pins or markers or sources)" clause was rendered as "(pins / markers / sources)" — the slash-list is an existing house idiom (local/membackticks) and reads better than a doubled "or" in a parenthetical. Intasks/review-wave-2.mdthe sibling "(pins / delete markers ∞ sources ...)" keeps its interposed "infinity" glyph untouched — only the three flagged characters were in scope. fuzz/'s tracked text files (README,run-detached.sh,gen_fuzz_seeds.py, manifests) had zero occurrences; the corpus and gitignored build areas were never opened for edit.tasks/unicode-hygiene.mditself carried occurrences (its own description quotes the flagged characters); those mentions were rewritten to codepoint/ASCII phrasing so the acceptance grep stays clean including this file. TheAGENTS.mdcount line ("pg-heavy tests x up to 2 pools each x poolmax_size8") keeps the arithmetic reading.
Summary
To be filled on completion
Completed 2026-10-16. All three gitea-flagged confusable characters
(U+2013 en-dash, U+00D7 multiply sign, U+2228 logical or) removed from
the repo's tracked text files: mechanical ASCII replacements
(-, x) everywhere, plus the slash-list rendering for the
src/gc.rs logical-or clause and its prose mirrors. Diff is comments
and prose only — no code changes. The three-character rule recorded in
AGENTS.md convention 11. Acceptance grep (git grep -nP '\x{2013}|\x{00D7}|\x{2228}') returns nothing across src/, tests/,
docs/, tasks/, fuzz/; em-dash/§/arrow/ellipsis typography
spot-checked intact in src/store/mod.rs and
docs/architecture/overview.md. Full verification block green.