Skip to content

[R2][回归] 定位旧 candidate normal-1 的未知 invalid text 事件 #57

Closed as not planned

Description

@JavaZeroo

问题与目标

旧候选完整回归的 normal-1 出现 invalid text,当时已看到 TF_AFTER,但未记录事件种类、字节数、UTF-8 转换调用点或载荷。#45 已通过真实合法空标题最小复现修复一个独立缺陷;该修复不能回填旧 normal-1 的因果链。

补足有界、隐私安全的诊断,并逐项定位真实事件与转换边界,关闭 #38 尚未独立承接的旧失败缺口。

范围与非目标

保留旧事件 unknown;沿原 normal/持续输出/退出合同与期限,记录允许公开的固定标量诊断,不直接 dump 标题、路径、会话文本或任意 payload。

不重新打开 #45 的已验收最小修复,不将任何新空标题成功当成旧失败根因;合法空输入保持支持,非法非空 UTF-8 继续严格拒绝。

依赖

父项 #38;本项阻塞 #38。无未解除的开工前置,可独立使用原失败身份和当前候选回归入口。#45 已关闭,但不作为本项根因证明。

验收条件

  • 固定原失败可获得的源码、二进制、输入/场景、已观察 TF_AFTER 与未观测字段;不能恢复的原载荷或调用点明确 unknown,不伪造历史时间线。
  • 在 terminal event 路由、事件 kind/长度、UTF-8→UTF-16 转换及异常边界增加有界诊断;使用固定 reason 白名单、整数/布尔阶段等安全字段,异常/失败后仍保留观测,原异常和回收不被诊断覆盖。
  • 诊断采集有明确运行数/时间/容量与停止条件,原产品负载、单ETX、退出期限及监督合同保持;不恢复已停止的侵入式无限断点路线、不操作输入桌面、不因未复现而无限刷绿。
  • 以真实原场景或已证明同类失败建立 event→转换→异常的可检查因果链;修复有相同触发的 red→green 及必要反例。新最小缺陷与旧失败无法关联时分别记录,本项旧根因继续 unknown,不据此关闭。
  • 合法空标题/空转换仍通过,非法非空 UTF-8、分块/错误字节及非标题事件的必要拒绝负例保持;不要以吞异常、跳过事件或无条件接受非法文本取得通过。
  • 固定最终源码重跑原 normal/resize 与相关 candidate event/GUI 及资源回收;旧失败、新观察与修复结果分列,[R2][回归] 收敛 Windows 可靠性与历史未闭合失败 #38/FEATURES/EVIDENCE 同步。仅重跑成功且原因未知时保留本项开放。

验证方法与证据

沿用现有 candidate GUI、原 normal 场景、真实自有 console/ConPTY、独立 Job/非输入 desktop 与期限。公开合成反例和经审核的诊断摘要;必要私有 payload 只在有界本地证据中保留,不能直接上传。日志不把用户会话标题、完整路径或任意终端文本写入公开 CI artifact。

来源、限制与已知差异

旧 normal-1 的事件种类、长度与具体载荷尚未知。新诊断不能回填旧观测;本项不替代 #36、#40、#44 或完整 R2 出口。

Activity

  1. added
    bugSomething isn't working
    ready-for-agent范围明确且真实阻塞已解除,可开始实施
    compatibility平台、协议或行为兼容问题
    on Oct 26, 2026
  2. JavaZeroo commented on Oct 30, 2026

    @JavaZeroo
    OwnerAuthor

    当前可达性(只读核对)

    核对对象:worktree D:\Code\termforge-uia-note,HEAD d3f24d6(merge-base 3841281 + 1 个 diag 提交;落后 origin/main 7ff5cde 2 个提交,差异只有 experiments/shell/clipboard_scenario_state.hpp 与 research/ime/test_hosted_inventory.py,未触及下文所引行)。

    结论:失败路径仍可达(a),但旧失败仍不可回填。

    环节 当前状态 证据(文件:行)
    抛出点 仍在,且是生产代码唯一 invalid text experiments/presentation/render.hpp:23-29,L26 require(n != 0, "invalid text"),MB_ERR_INVALID_CHARS 保留
    事件→转换 仍在(仅候选构建) experiments/shell/shell.cpp:815-829,L821 case 2: terminal_title_ = utf16(event.bytes);格文本转换 render.hpp:215、:247
    原场景入口 仍在 experiments/shell/test_shell.py:390-400(mode normal ×3)、shell.cpp:1458(接受 normal)、run.py:185-187(校验)
    #45 修复边界 只修了空串 render.hpp:24 空串短路;非法非空仍拒绝:experiments/shell/results/2026-10-26-empty-title/validation.json:57-68(ff/c080/eda080/e4b8 拒绝、mb_err_invalid_chars_retained: true)
    旧失败身份 仍未知 .../2026-10-26-empty-title/original-normal-invalid-text.json:20-44:conversion_callsite、candidate_event_kind、载荷长度、conversion_native_error 全 null
    有界诊断 尚未实现 experiments/core/candidate_terminal.cpp 无 UTF-8 校验(全文件仅 L39 尺寸消息);shell.cpp 事件路由无 kind/长度白名单

    路由补充(不等于(c)):ADR-0008 已把 Alacritty 候选与 Win32 实验 shell 降为参考;产品 Qt 入口用 QString::fromUtf8(src/qt/terminal_widget.hpp:210、src/qt/main.cpp:23)不抛异常,且目前没有 OSC 标题→窗口标题通路(只有固定 setWindowTitle,src/qt/main.cpp:17)。同一条严格转换门槛因此不在产品路线里;但 ADR-0008 写明"本次路线确认不关闭 #34、R2 或任何真实功能缺口",这不能作为关闭依据。

    一个下一步观测

    在三个转换点(render.hpp:215、:247、shell.cpp:821)与事件路由加有界标量:调用点 id、输入字节长度、首个非法字节偏移、GetLastError,以及 event.kind/字节长度;再跑一次 mode normal(单轮、40 s 外层期限、候选构建,沿用 test_shell.py:390-400 原入口),只记录是否复现与触发调用点。若未复现,按 docs/milestones/R2-local-terminal.md:59 记为"本批未复现 + 下一可证伪假设",不改判旧因。

    能否关闭

    不能,本项原文即禁止:

    • 验收第 4 条:"新最小缺陷与旧失败无法关联时分别记录,本项旧根因继续 unknown,不据此关闭。"
    • 验收第 6 条:"仅重跑成功且原因未知时保留本项开放。"

    docs/TRACKING.md:48 同样登记为"原事件 kind/载荷未知,不能回填根因"。

    边界

    • 只做只读核对:未构建候选适配器(build-diag/CMakeCache.txt:TERMFORGE_BUILD_CANDIDATE_ADAPTER:BOOL=OFF),未运行任何 GUI/normal 场景,未新增诊断或改测试。
    • 未恢复旧 normal-1 的 event kind、字节长度、调用点或载荷;"仍可达"仅指源码入口与抛出点仍在,不等于复现。
    • 未验证产品 Qt 路径的标题行为(该路径当前无标题事件实现),也未把参考路径状态写成产品能力。
    • 未重跑 [R2][Bug] 合法空标题事件导致候选 GUI 抛出 invalid text #45 的记录,未核对旧分支源码 4211763 能否原样重建。
  3. added a commit that references this issue on Oct 31, 2026
  4. JavaZeroo commented on Nov 1, 2026

    @JavaZeroo
    OwnerAuthor

    按「不死磕」原则关闭:旧 candidate normal-1 的未知 invalid text 事件

    关闭理由

    用户明确「可以接受不完美、不需要一直死磕一个问题」。本项属于批次内不可复现、诊断已就位的一类,因此按此原则关闭。

    本项已有的证据

    已在候选事件路径为标题事件加入有界诊断:异常时报告 kind、字节数与十六进制前缀(上限 32 字节),使下次复现可直接看出是空串、代理对截断还是非 UTF-8 数据。

    已就位的诊断(再次命中时可立即判读)

    观测 位置
    事件种类与载荷长度 失败信息 invalid text in title event: kind=2 bytes=…
    载荷前缀 同行的 hex=…

    关闭时的真实状态

    本项不是根因修复。原始失败记录仍保留,未被新批次覆盖。

    重开条件

    若同类失败再次出现,凭上述诊断字段可直接判读,恢复本项即可,无需重做本轮探索。

  5. removed
    ready-for-agent范围明确且真实阻塞已解除,可开始实施
    on Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcompatibility平台、协议或行为兼容问题

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions