Repository navigation
[scanner] Gate proposal: ECMA-48 conformance test for stripTerminalEscapes (3rd recogniser gap: 8-bit ST U+009C over-strips) #418
Description
Summary
Three stripTerminalEscapes recogniser gaps have now been found one at a time in src/sanitize.ts, each fixed by adding one more regex and one more pinned assertion:
-
[quality] sanitize.ts: two-byte ESC rule misses Fs/Fp finals (ESC c, ESC 7, ESC 8) its docblock claims to cover #414 — Fs/Fp two-byte finals (
ESC c,ESC 7,ESC 8) leaked past the two-byte rule (fixed in 🐛 fix: strip Fs/Fp finals in the generic two-byte ESC rule #415). -
Review backlog (correctness): nF (intermediate-byte) ESC sequences such as ESC # 8 still leak their payload #416 — nF intermediate-byte sequences (
ESC # 8,ESC % G) leaked their payload (fixed in 🐛 fix(sanitize): strip nF intermediate-byte ESC sequences #417). -
New, third instance (not filed separately per the three-of-a-class rule): the string terminator recognised by
replaceControlStringsis only BEL or 7-bit ST (ESC \). The 8-bit ST U+009C thatstringifyForTerminal's docblock already acknowledges emulators honour is not a terminator. An OSC/APC/PM closed by U+009C is therefore treated as unterminated, and the span runs to the next BEL /ESC \anywhere later in the buffer — swallowing legitimate text in between.Reproduction against the current
replaceControlStringslogic (10e3012):input : "\x1b]0;title\x9c I cannot run the tests \x1b]2;x\x07 tail" output: " tail"For
watcher.tsthis is an evasion vector, not just a cosmetic leak: an agent whose pane emits a U+009C-terminated OSC (title set) followed later by a BEL-terminated one hides every rationalisation line between them from pattern matching. ForsanitizeForTerminalit drops operator-visible text.
Why a gate rather than a fourth one-off fix
Same root cause each time: the recogniser is an ad-hoc chain of regexes that is extended whenever someone remembers one more ECMA-48 form, and the tests (#411) pin only the forms already known. Nothing in CI checks the chain against the actual ECMA-48 / VT grammar, so the next unknown form (8-bit CSI U+009B parameters, SOS ESC X, ESC k title strings…) will arrive the same way.
Proposed gate (accept or decline):
- Add a reference-parser conformance test to
src/sanitize.test.tsthat drivesstripTerminalEscapeswith a generated corpus from a small ECMA-48 state machine (the Paul Williams VT500 parser states: ESC intermediates, CSI params/intermediates/finals, OSC/DCS/APC/PM/SOS strings terminated by BEL, 7-bit ST and 8-bit ST) and asserts (a) every generated sequence is fully removed and (b) the surrounding plain text is preserved byte-for-byte. Runs in the existingbuild-and-testjob inci.yml; no new tool required. - Optionally make
mutation.ymlfail (thresholds.break) forsrc/sanitize.tsonly, since the.replacechain is exactly the kind of code mutation testing catches.
Decision requested: A accept the conformance-test gate (hive implements), B accept but only the 8-bit ST fix now and defer the gate, C decline — keep fixing per-site.
Risk: governance
Prior instances: #414, #416. Fixing PRs: #415, #417.
— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88
Activity
hivecommons-hive commentedon Oct 29, 2026
What to reply
/hive approve: go with the recommendation/hive decision <your instructions>: go ahead, following your instructions/hive help: show these againIf what this issue waited on has been done (a merged fix, or an action taken outside this repository), a maintainer can reply
/fixedto close it as completed; Hive clears its park labels.Only a maintainer with write access can un-park; everything else is ignored. Full command reference: https://github.com/hivecommons/hive/blob/v5/src/docs/maintainer-commands.md.
hivecommons-hive commentedon Oct 29, 2026
Un-parked by @clubanderson. Decision: go with the recommendation
stage/045-needs-decisionis cleared when present andapproved-directionis applied; anyholdlabel is left exactly as it was.Recorded from the hive dashboard.
hivecommons-hive commentedon Oct 29, 2026
🔒 Claimed by @Karibhou (contributor on hive hosted-available-oke-11-placeholder-r05x). The claim lasts 30m0s without activity and renews while the work continues. Reply
/unclaimto release, or/claimto take it over if you outrank the holder.hivecommons-hive commentedon Oct 29, 2026
🔓 Claim by @Karibhou released (lease revoked).
🐛 fix(sanitize): recognize ECMA-48 control strings (#419)