Commit Graph
2 Commits
Author SHA1 Message Date
e74e860725 fix(#1648): final emoji leaks — .obs-clock-naive-chip warning + analytics Channels encrypted group labels (#1665)
## What

Two Phosphor lint-gate breaches found by the v3.8.4 manual-test executor
— app-controlled UI labels still shipping raw emoji glyphs that the M6
final sweep (#1648) missed. One PR, two sprite swaps, same playbook as
#1657.

### Findings

| Test ID | Surface | Glyph | File:line | Fix |
|---|---|---|---|---|
| v384-1.2 | `/observers` `.obs-clock-naive-chip` | `⚠️` (U+26A0) ×14 |
`public/observers.js:30` | `ph-warning` sprite |
| v384-12.18 | `/analytics?tab=channels` encrypted row name cells | `🔒`
(U+1F512) ×158 | `public/analytics.js:978–979` | `ph-lock` sprite |

Finding 2 is a different surface from the M3/#1657 fix (which swapped
the section-header label, not the per-row `displayName`). The
unknown-encrypted row's `displayName` carried a raw `🔒 Encrypted (0xNN)`
text label that then flowed through `esc()` into the rendered name cell
as an escaped emoji glyph — exactly the same `innerText → innerHTML`
class of bug. Refactored to mirror the section-header pattern:
`displayNameHtml` carries the sprite-bearing raw HTML; `displayName`
stays plain text for sort/aria/tests.

## TDD

- **RED** `cde12370` — `test-issue-1648-followup-phosphor-leaks.js`
asserts ph-warning sprite + zero ⚠ in chip output, and ph-lock sprite +
zero 🔒 in analytics row labels. 6 assertions failed on master.
- **GREEN** `f1c64b17` — sprite swaps applied. All 9 assertions pass.
- **Anti-tautology proven both directions**: reverting only
`public/observers.js` → 2 chip-related assertions fail; reverting only
`public/analytics.js` → 4 analytics-related assertions fail.

## Verify

-  `node test-issue-1648-followup-phosphor-leaks.js` — 9/9 pass
-  `node test-issue-1648-m6-final-sweep.js` — 0 violations
-  `node test-observer-naive-clock-1478.js` — 8/8 pass (existing chip
test accepts ph-warning sprite)
-  `node test-analytics-channels-integration.js` — pre-existing
unrelated `Channel Analytics` failure only; encrypted-row assertions all
pass with new plain-text `displayName`
-  pr-preflight all gates green (PII, branch-scope, red-commit,
CSS-var, LIKE-on-JSON, async-migration, XSS sinks)
-  Browser-verified on staging: 11 chips render ph-warning sprite (0
emoji), 156 ph-lock sprites in row name cells (0 lock emoji on page)

Browser verified: http://analyzer-stg.00id.net/#/observers +
/#/analytics?tab=channels (hot-patched)
E2E assertion added: `test-issue-1648-followup-phosphor-leaks.js:67`
(chip), `test-issue-1648-followup-phosphor-leaks.js:147` (row cell)

---------

Co-authored-by: meshcore-bot <bot@meshcore.dev>
2026-06-11 18:29:30 -07:00
89eade6e7b M6: emoji → Phosphor — final sweep, lint gate, carry-forwards (#1648) (#1654)
Red commit: fe7468d473 (CI run: will
appear in this PR's Checks tab — emoji lint test fails on the red
commit, passes on green)

**Fixes #1648.**

Closes the 6-milestone emoji→Phosphor migration started in #1649.

## Sweep results (real UI icons swapped this PR)

| File:line | Before | After |
|---|---|---|
| `public/index.html:140` |  | `ph-star-fill` |
| `public/mobile-page-actions.js:154` |  | `ph-star-fill` |
| `public/geofilter-builder.html:76` | ⬇ | `ph-download-simple` |
| `public/analytics.js:2103` | ⏱️ | `ph-clock` |
| `public/analytics.js:2288` |  | `ph-clock` |
| `public/analytics.js:4080` |  | `ph-clock` |
| `public/nodes.js:1066` |  | `ph-clock` |
| `public/observer-detail.js:284` |  | `ph-clock` |
| `public/channel-qr.js:133` | 📋 | `ph-clipboard-text` |
| `public/channel-qr.js:139` | ✓ | `ph-check` |
| `public/packets.js:1472` | ⏸ | `ph-pause` |

## Carry-forwards addressed

- **M5 CDP — live `.cust-emoji-preview` re-render** —
`public/customize-v2.js:2434` wires `renderConfigGlyph` to the `input`
event so previews update without Save+reload. (commit `9e698a04`)
- **M5 CDP — `.modal-close` 44×44 mobile** — `public/style.css` adds a
≤640px breakpoint bumping both `.modal-close` and `.ch-modal-close` to
WCAG-minimum hit targets. (commit `9e698a04`)
- **M4 CDP — route-hop fallback color** — `public/route-render.js` now
reads `var(--status-info)` (new token added to `:root` and dark-mode
blocks in `style.css`) instead of baked `#3b82f6`. (commit `9e698a04`)
- M2 carry-forward set ( favStar / ▾ More / ⚠️ clock / 🌱 welcome
cards) verified already addressed by re-running M3 emoji scan — all
green.

## Lint gate (M6 headline)

- Test: `test-issue-1648-m6-final-sweep.js` — full repo scan across
`public/**.{js,html,css}` and `cmd/(server|ingestor|decrypt)/*.go`.
- Self-test: `test-issue-1648-m6-lint-self.js` — exercises the lint
engine + anti-tautology probe.
- Allowlist: `tests/emoji-allowlist.txt`. Format: `path` (glob),
`path:line`, `path:line:U+XXXX`, or `/regex/`. Add intentional emojis
here with a `# why` comment.
- Wired into `test-all.sh` alongside M1/M2/M3 scans.

## routes.go smoke check

Server-side defaults in `cmd/server/routes.go:567-574` confirmed
`ph:bluetooth`/`ph:radio`/`ph:broadcast`/`ph:repeat` (M5 landed).
Operator-customized configs on staging/prod still carry their legacy
emoji overrides — per M5 design call those are preserved and NOT touched
by this PR.

## PR closing list

Fixes #1648. M1 #1649 , M2 #1650 , M3 #1651 , M4 #1652 , M5 #1653 ,
this PR .

---------

Co-authored-by: Bot <bot@corescope>
2026-06-11 05:44:37 -07:00