Repository navigation
Description
Problem
After the #1581 fix (PR #2945), the TS world presenter (pkgs/id/web/src/world-surface.ts) and the Rust validator (pkgs/id/src/world_presentation.rs, unicode-width 0.2.2) still disagree on the alone width of 2529 single code points — classes #1581 never scoped. Same failure mode as #1581: a Rust-valid screen can fall back to raw text in the browser (TS refuses a width the Rust side admitted), or TS accepts a width Rust refused.
Evidence (gathered 2026-10-31, queue task 1842)
Exhaustive differential: the real graphemeWidth from world-surface.ts (driven under bun) vs UnicodeWidthStr::width on the pinned unicode-width 0.2.2 (standalone Rust probe), every code point U+0020..U+2FFFF, alone and +U+FE0E. The PR #2945 work zeroed all #1581/FE0E divergences (57 alone + 93 FE0E fixed, zero new); the residual alone-width mismatches, by class:
| Rust | TS | count | examples |
|---|---|---|---|
| 2 | 1 | 2295 | U+17A4 (Khmer vowel), U+2630..U+2637 (trigrams) |
| 1 | 2 | 76 | U+2E9A, U+2EF4..U+2EFA (CJK radicals inside TS's broad 0x2E80..0x303E / 0x3040..0x33FF wide ranges) |
| 0 | 1 | 143 | U+00AD, U+0605, U+061C, U+070F, U+0890..U+0891, U+08E2 (format/invisible chars) |
| 0 | 2 | 13 | U+302A..U+302F (ideographic tone marks), U+3099, U+309A |
| 1 | 0 | 1 | U+2D7F |
| 3 | 1 | 1 | U+17D8 |
Reproduction is mechanical: rebuild the two probes (a ~30-line Rust binary pinned to unicode-width = "=0.2.2" dumping cp / alone / +FE0E, and a bun script importing graphemeWidth) and diff — counts above must reproduce exactly against PR #2945's head or later main.
Reachability note (why this needs triage, not a blind table sync)
The Rust validator admits only graphemes of width 1..=2 per cell, so classes with Rust width 2 / TS 1 are reachable in principle (e.g. a screen cell U+2630 at columns: 2 is Rust-valid and TS-refused). Other classes may be unreachable: U+17D8 is Rust width 3 alone (never admittable as a lone cell), and some rust=0 classes may be excluded upstream by the presenter's control-char refusal. Each class needs a disposition before table surgery on 2529 code points is justified.
Acceptance criteria
- Each residual class above is dispositioned reachable-as-a-cell or unreachable, with the reasoning recorded (single-grapheme admission, control-char refusal, segmenter behavior in clusters — clusters may differ from the alone table)
- Reachable classes are fixed in
world-surface.tswith parity tests inworld-surface.test.ts, re-verified by the exhaustive differential (target: zero alone and +FE0E mismatches outside proven-unreachable classes) - id(web): world presenter still mis-measures ⬛/⭕, narrow-base skin tones, composed Hangul jamo and long graphemes — #1431's folded-in classes survived its fix, and the 16-unit symbol cap has no Rust twin #1581 / PR id(web): grapheme-width parity remainders for the world presenter (#1581) #2945 are not reopened — this issue covers only the residual classes
Filed by the queue worker (Lane B, task 1842) from evidence gathered fixing the Codex P2 on PR #2945; a queue triage task keyed to this issue carries the same evidence.
Activity
dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 1, 2026
🤖 Agent note · triaged — every residual class dispositioned (2,372 reachable / 157 unreachable-alone)
graphemeWidth(world-surface.ts) vsUnicodeWidthStr::widthon pinned unicode-width 0.2.2 (194,528 scalars scanned) — plus a Bun probe of the realrenderWorldSurfacefor representative points. Admission frame: the Rust presenter admits a single-grapheme cell only at widths 1..=2 (world_presentation.rs), so a class is reachable-as-a-cell exactly when Rust's alone-width is 1 or 2 and TS disagrees.repo-health:v1:fix:developing-today/code:issue:2962) scoped to the 2,372 reachable points, with the differential re-run as its oracle (reachable mismatches → 0; residual exactly the 157 unreachable points). id(web): world presenter still mis-measures ⬛/⭕, narrow-base skin tones, composed Hangul jamo and long graphemes — #1431's folded-in classes survived its fix, and the 16-unit symbol cap has no Rust twin #1581 and PR id(web): grapheme-width parity remainders for the world presenter (#1581) #2945 are not reopened.75 remaining items
dezren39 commentedon Nov 2, 2026
Picked up: OpenChamber scheduled lane claimed repo-health-code-pilot task 5514.
queue/5514-2962-width-parity; guard check is QUEUED, started 2026-11-02T17:34:58Z. No hard-stop labels.dezren39 commentedon Nov 2, 2026
Parked: Task 5514 parked for 20 minutes because PR #4491's basic OpenCode metered-provider guard remains QUEUED beyond the five-minute poll window.
queue/5514-2962-width-parity; no held, user/owned, do-not-merge, or do-not-auto-edit labels. Existing CI/test evidence remains from the prior checkpoint; no new tests run.fix(id/web): presenter width parity for the 2372 reachable code points (
dezren39 commentedon Nov 2, 2026
{"schema":"agent-note:v1","type":"status","stage":"done","task_id":5514,"lane":"code-d","worker":"repo-worker-code","note":"Merged on resume: PR #4491 (squash c9f0309) syncs WIDE_RANGES in world-surface.ts with unicode-width 0.2.2 for the three reachable classes (2295 points to width 2, 76 CJK-radical points to width 1, U+2D7F to width 1). Exhaustive differential re-run documented on the PR: 0 reachable mismatches alone and +U+FE0E; residual is exactly the unreachable-alone points. Codex review of head acad12b completed with no findings; checks SUCCESS/NEUTRAL."}