Skip to content

[R1回归] 持续 cmd 输出时 ETX 未中断导致 normal/resize 超时 #36

Closed as not planned

Description

@JavaZeroo

用户结果与原失败

持续 cmd 输出期间,单个 ETX 能在既定期限中断并继续执行后续命令;原生信号交付与窗口回归分别留证。

原 12daefb/Windows11 build26200 的 normal/resize 在持续一百万次 for /L 后仍输出 TF_BUSY、stage5原25秒失败;原始 ConPTY 路径也在五秒内未得到独立 TF_AFTER,不能归因解析器或通过降低输出掩盖。机制调查保留 CDB/ETW 的观测和扰动限制。

已有基础与当前状态

PR #43 已交付 受监督固定入口:原一百万次循环、至少一秒实际持续输出、一次洪流ETX、立即后续命令、五秒独立完整标记、退出37及自有 Job。normal/resize 新重跑和旧探针原二进制当前均绿,CI也运行该入口,见 同源复验。

没有产品 Ctrl-C 修复;旧失败与当前成功的因果差异、原生控制处理函数独立交付仍未知。数值版本与资源显示字符串不同不能当作系统版本变化证据。

下一次有界定位与验收

  • 执行前固定一个可证伪假设、源码/二进制及 cmd/conhost 身份、样本数/监督期限/停止条件;先判断原固定入口是否复现,不无限刷绿,不恢复已停止的侵入式全量读断点路线。
  • 用可维护、低扰动、自有 Job 的同次观测关联 ETX 写完成、输入解析/控制分派、目标原生 handler、循环停止与后续命令,明确每个未知;不将空闲ETX或清理的CTRL_CLOSE_EVENT误归洪流Ctrl-C。
  • 对原生子进程 handler 的独立交付给出可复验信号与反例;不能只用 TF_AFTER、命令回显、Ctrl+Break导致shell退出或重复ETX替代。
  • 若获得同类失败,定位并保留因果 red→green 与相同 normal/resize/完整回归;若原批次未复现,保留历史根因 unknown 与下一假设,本项继续开放,不以当前绿认定修复。
  • 原百万负载、单ETX、五秒标记及原场景期限不变;退出/原始字节与回收继续留证。若确需修订合同必须另行明确决策,当前整理不批准。

真实前置与完成边界

父项 #7;无未解除前置,可独立诊断,是 #35 原生出口阻塞。#38 其他可靠性问题分开处理;本项不证明所有Windows、所有Ctrl-C路径或WindTerm等价。原始transport和调试材料私有,公开仅审核后的合成摘要。

Activity

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

    @JavaZeroo
    OwnerAuthor

    继续隔离结果(临时探针已删除,未改产品/测试门槛):

    1. 原生命令仍使用同一持续 cmd for /L 输出。向 ConPTY 写 ETX、从附加控制台调用 GenerateConsoleCtrlEvent(CTRL_C_EVENT),以及写入实际 Ctrl+C KEY_EVENT_RECORD,均未恢复后续 TF_AFTER。
    2. 改用有 SetConsoleCtrlHandler 的受控原生子进程,以上三条路径也都没有到达处理函数;处理函数中的独立标记未出现。这排除了“只是 cmd 内建 for 不处理中断”的完整解释。
    3. CTRL_BREAK_EVENT 导致 cmd 退出,不能作为中断后继续正常输入的替代。
    4. 空闲提示符下 ETX 后能执行后续命令,但这不证明运行中子进程收到中断,不能作为通过证据。

    当前结论:尚未找到可诚实实现的修复或合同修订依据,normal/resize 和完整 CTest 继续保持失败。FEATURES/EVIDENCE 已标明当前回归,历史 R1 证据不再被描述为当前环境通过。没有减少负载、延长超时、跳过失败或伪造 hosted 结果。

    后续若要继续本项,需要先获得目标平台上参考终端的实际中断行为,或一个能证明控制事件确实到达 ConPTY 子进程的最小系统路径;在此之前不修改产品解析器。

  3. JavaZeroo commented on Oct 24, 2026

    @JavaZeroo
    OwnerAuthor

    无窗口补充验证:

    • 原始 ConPTY 输出在 ETX 后持续 TF_BUSY,没有出现 Terminate batch job (Y/N)?,因此不是需要回答 Y 的批处理提示。
    • 受控原生子进程显式设置 ENABLE_PROCESSED_INPUT 后,Ctrl+C 处理函数仍未出现标记,单纯补该模式不是修复路径。
    • 已停止并删除 Windows Terminal/截图参考尝试;后续不再使用这条路径,也不会将其不可靠结果写成参考结论。

    当前仍无修复或合同修订依据,normal/resize 继续保持失败。静态 Microsoft 一手源码/文档调查仅用于确定输入机制,不再启动应用。

  4. JavaZeroo commented on Oct 24, 2026

    @JavaZeroo
    OwnerAuthor

    Microsoft 一手源码调查已形成 docs/research/conpty-ctrl-c-input.md,并同步 EVIDENCE/TRACKING:

    • 单个 ETX 是正确编码:Windows Terminal 将 Ctrl+C 映射到 0x03,ConPTY 输入解析器专门将其交给控制键处理,不应改用其他字节。
    • HandleGenericKeyEvent 仍要求 processed-input 模式;普通 WriteInput 与特殊 Ctrl+C 路径不同。
    • 全局控制台锁只在最外层 unlock 分派控制事件,持续 WriteConsole 与 VT 输入确实可能产生延迟。官方 #6258/#2141 也保留相关已知问题。
    • 这些只提供候选机制,不证明当前 build 26200 的实际卡点,也不解释三条路径失败的全部关系。仍缺少输入写完成、CtrlFlags、锁等待、客户端模式和目标处理函数时间线。

    可保留的实现原则:继续单个 ETX、独立无阻塞输入/输出、完整原负载验收。不得以 win32-input-mode、GenerateConsoleCtrlEvent、Ctrl+Break 或减少输出冒充修复。当前 #36 仍未解决。

  5. JavaZeroo commented on Oct 24, 2026

    @JavaZeroo
    OwnerAuthor

    定向静态补充已写入 docs/research/conpty-ctrl-c-input.md。固定官方 WindTerm 2.7.0(SHA-256 7b10531dccc7cd614ae559f36f1ef518e0c96335637431b4646354823b2804d0)的 ConPty 写入口 0x1402e5c30 将 QByteArray 写到 ConPTY 输入管道;0x1402e4cc0 是独立输出 ReadFile 线程。当前导入清单未见 GenerateConsoleCtrlEvent / SetConsoleCtrlHandler,普通写入口没有单独 Ctrl+C 分支。未执行参考应用、未截图。键盘到写入口的完整链及 ETX 编码仍未由该二进制证明,build 26200 的实际分派卡点也仍未知;本结果不是修复,不关闭本 issue,也不改变 normal/resize 失败门槛。

  6. JavaZeroo commented on Oct 24, 2026

    @JavaZeroo
    OwnerAuthor

    新增无窗口 CDB 证据已写入 docs/research/conpty-ctrl-c-input.md。探针实际加载系统 conhost 10.0.26100.9444(PDB 716FC77AB82C93512B79D2D4ACBC46F71)。空闲 ETX 依次命中 WriteCtrlKey、HandleGenericKeyEvent 和 cmd CtrlRoutine。一次洪流追踪未命中控制键路径,失败点 VT 输入线程在 ReadFile 而非 LockConsole;另一次较慢追踪中洪流也命中 WriteCtrlKey 和 CtrlRoutine,但 TF_AFTER 仍未执行。普通无调试器重建探针继续红灯,21 字节均写完。结论:调试器改变时序,不能选定某次片段宣称统一根因;需要在同次低扰动样本关联 HandleCtrlEvent/ProcessCtrlEvents、cmd 处理返回和循环停止。未截图、未启动参考应用、未改负载或编码,#36 保持未修复。

  7. JavaZeroo commented on Oct 24, 2026

    @JavaZeroo
    OwnerAuthor

    补充无断点 ETW:同次普通失败运行 6 秒 trace 为 Events Lost=0 / Buffers lost=0。cmd 输入模式在循环期间为 0x7,ENABLE_PROCESSED_INPUT 未关闭;CookedRead 有 @echo off、echo TF_AFTER_IDLE 和原始 for /L,没有 TF_AFTER_FLOOD,确认后续命令未进入 cooked-read 执行路径。Microsoft.Windows.Console.Host 在此次采集未提供 ConPTY ReadFile / HandleCtrlEvent / ProcessCtrlEvents 事件,所以仍无法补齐控制分派链,未出现事件不证明函数未执行。会话已停止;原始 ETL 含其他控制台内容,提取事实后已删除。详见 docs/research/conpty-ctrl-c-input.md;#36 保持未修复。

  8. JavaZeroo commented on Oct 24, 2026

    @JavaZeroo
    OwnerAuthor

    同次 CDB 对照:洪流 ETX 尚未进入 conhost 控制分派

    继续使用原始 100 万次 cmd for /L、单个 ETX 和 5 秒判定,无窗口、无截图、未运行参考应用。docs/research/conpty-ctrl-c-input.md 已更新。

    • 本机 cmd 为 10.0.26200.9457;实际符号/反汇编确认 cmd!Handler 对事件 0/1 调用 SetCtrlC,eFor 检查 CtrlCSeen 后从 eFor+0x286 清理并 longjmp。
    • trace 12 同一次样本中,宿主写入 47 字节循环命令、1 字节 03、20 字节后续命令均成功。日志随后出现的控制键/控制例程事件属于此前尚未完成的空闲 ETX 对照,不能按时间顺序误归给洪流。
    • 洪流 5 秒失败点:conhost CtrlFlags=0、cmd CtrlCSeen=0;没有洪流对应的 HandleCtrlEvent、ProcessCtrlEvents、cmd!Handler 或 eFor 退出分支。conhost 输入线程等待下一次 ReadFile,cmd 主线程仍在 eFor。清理阶段的 Handler(ecx=2) 是 CTRL_CLOSE_EVENT,不是 Ctrl+C。
    • trace 10/11 独立重复了洪流写入成功而 cmd 标记为零的结果。

    因此,当前证据不支持“信号已到 cmd 但 cmd 未停止”或“已证明卡在 LockConsole”。实际未决点是洪流 ETX 写入与 conhost 控制分派之间的时序敏感缺口;需要更低扰动的同次管道 I/O 追踪确认读完成/解析位置。CDB 扰动只代表插桩样本,普通运行 ETW 仍独立证明 TF_AFTER_FLOOD 未进入 cooked-read。

    没有产品修复或编码变更,不减少负载、不延长超时、不跳过失败。#36 保持未解决;全量 CTest 仍不得宣称通过。

  9. JavaZeroo commented on Oct 24, 2026

    @JavaZeroo
    OwnerAuthor

    提交 7880c2a 的当前源码已完成完整 Release 构建,39 项 CTest 自然执行结束:37 项通过,唯一 CTest 失败为 shell,其中仍恰是 normal 与 resize 两个持续输出中断场景(32 个 shell 测试中 2 errors、3 个既有 hosted skip)。结果由 CTest LastTest.log/LastTestsFailed.log 核实;没有减少负载、延长场景超时或跳过失败。本项保持 OPEN,并继续作为 #35 出口前置。

  10. JavaZeroo commented on Oct 25, 2026

    @JavaZeroo
    OwnerAuthor

    有界 I/O 时间线补充(未定位根因,保持 OPEN):

    • 无窗口 CDB 脚本已能自动继续子进程初始断点及首次 Ctrl+C 调试异常;这些只改善采集器,不是产品修复。
    • 最新样本在 flood-observed 后记录到 170 次 NtReadFile 返回,均为 status=0 / Information=0。但没有句柄或调用栈归属,而且日志未到达 before-etx、etx-written、followup-written 或 FLOOD_STALL,不能将这些读返回关联到洪流 ETX,也不能证明管道未读或控制台锁竞争。
    • 全量读断点扰动过大,触及 60 秒外部监督上限;原探针的一百万行负载、单 ETX 和 5 秒判定未改。OwnedJob 最终 active=0。

    临时脚本与日志保留在 ignored 本地路径,没有产品/测试改动可提交。本轮停止扩大这条调试路径,转做独立 R2 事项;本 issue 与 #35 出口继续保持未完成。

  11. JavaZeroo commented on Oct 26, 2026

    @JavaZeroo
    OwnerAuthor

    接手进展见 PR #43。新增可维护的原始 ConPTY 回归(conpty_ctrl_c CTest / experiments.conpty.ctrl_c_run),保留一百万次循环、至少一秒持续输出、一次洪流 ETX、立即后续 echo、五秒完整独立标记和退出 37;不接受命令回显、循环自然结束或重复 ETX。启动受 GO/Job 监督,失败保留私有原始字节,公开记录身份及回收;另外覆盖无 GO/坏 GO/watchdog 与清理错误留证。

    本次在未修改产品 Ctrl-C 路径时,normal/resize 各十次 fresh 均通过;旧探针原二进制也在监督包装下五次通过。当前固定数值版本 cmd 10.0.26100.9278、conhost 10.0.26100.9444;版本资源显示字符串另为 8875,不能把显示字符串误认为系统更换证据。新固定入口三次通过,28b8a77 本地全量 41/41,系统剪贴板/IME本机跳过不计系统验收。

    保持 OPEN。 旧 9444 失败与当前成功的因果差异未知;原生子进程控制处理函数的独立交付仍未验收。本次提供回归入口,没有产品修复,也不恢复已停止的侵入式断点路线。CI 的真实 Windows 验证与 #38 前置准备正在 PR 中继续闭环。

  12. JavaZeroo commented on Oct 26, 2026

    @JavaZeroo
    OwnerAuthor

    已在 #43 合入固定的受监督原始 ConPTY 回归:完整一百万次循环、单次洪流 ETX、立即后续命令、原五秒标记期限、退出 37 与自有 Job 回收。三次 fresh 公开记录的原始字节哈希和断言已在本地独立重算,CI 持续执行;证据与限制同步入库。

    本次没有修改产品 Ctrl-C 路径。当前 conhost 数值版本 10.0.26100.9444 与旧失败一致,不能把资源版本字符串差异当作根因;旧探针原二进制现在通过也不能证明已修复。历史失败的因果差异和原生控制处理函数的独立交付仍未知,本项保持 OPEN。

  13. JavaZeroo commented on Oct 30, 2026

    @JavaZeroo
    OwnerAuthor

    R1 #36 核对:洪流 ETX 的链路端点与仍缺的那个字段

    结论:原始 red 只留下“TF_BUSY 继续、TF_AFTER 未出现”的结论,缺的是 ETX 写完成 / 标记到达时刻 / 循环停止位置 的同次字段,以及 控制分派到原生 handler 这一环。当前 raw ConPTY 入口补上了前三者;handler_delivery_verified 仍写死 false,所以本项保持 OPEN。

    1. 原失败缺什么

    • R1 shell 侧只有布尔:experiments/shell/shell.cpp:1494 输出 ctrl_c_verified,experiments/shell/run.py:185-187 把它作为 normal/resize 门槛。stage5 只能由 line_is("TF_AFTER") && frame_after_(shell.cpp:805,置位见 :1038-1039)翻转,记录里没有“ETX 写到第几字节 / 何时写”与“TF_AFTER 何时到达”。超时后剩下的信息就只有“没翻转”。
    • 因此原 red 无法区分四种情况:ETX 未写入 / 写入但 conhost 未分派 / 分派了但 cmd 未停 / 停但输出未到。
    • 公开结果里没有这条红样本:逐条解析 experiments/shell/results/**/samples.jsonl 的 ctrl_c_verified(兼容 stdout 字符串与 result 对象两种形态)得到 normal=15 全 true、resize=9 全 true、close=15 全 false、resize-close=9 全 false,normal/resize 的 false 为 0 条。原 red 只存在于 issue 文字与私有材料中。

    2. 现在记录这条链的端点(当前 main)

    环节 字段 写入路径
    洪流进行中 flood_observed、busy_hold_ms(须 ≥1000ms) experiments/conpty/ctrl_c_probe.cpp:130-136,输出 :164
    ETX 写完成 flood_input_bytes(=21:ETX 1B + echo TF_AFTER_FLOOD\r 20B) send 的写完成回调累加,ctrl_c_probe.cpp:107-115 与 :139-140(flood_input=true),输出 :165;ctrl_c_run.py:202 断言其等于 FOLLOWUP 长度
    标记到达 after_marker、after_wait_ms 从 ETX 写入时刻 interrupt 起算,ctrl_c_probe.cpp:138-142;5 秒预算 marker_timeout_ms = 5000(:10,wait_marker :63-68);阈值 0 ≤ after_wait_ms ≤ 5000(ctrl_c_run.py:204)
    循环停止 highest_busy(须 0 < n < 1000000),并由 trace 独立重算 probe :143、:149、:157;ctrl_c_run.py:53-68 与 :205-206
    退出与回收 exit_code=37、active_children_after=0、cleanup_complete、强制取消标志、外层 job_after.active probe :145、:166-171;ctrl_c_run.py:200-216
    原生 handler 交付 handler_delivery_verified 常量 False:ctrl_c_run.py:250(样本)与 :427(manifest);NATIVE_FIELDS(:26-31)与 probe 输出(:160-172)都没有对应键

    3. 记录里的实际数值

    experiments/conpty/results/2026-10-26-ctrl-c-retest/(提交 274f3b2,recorded_source_commit c44ae98):

    • sample-0.json:59-81:highest_busy 8466(<1,000,000)、busy_hold_ms 1010、after_wait_ms 32、flood_input_bytes 21、input_bytes 106、exit_code 37、read_error 109、cleanup_complete true、forced_process_cancel/forced_reader_cancel false;handler_delivery_verified false(:6)。
    • 同批系统身份:cmd 10.0.26100.9278、conhost 10.0.26100.9444(:19、:26),conhost 与旧失败一致,版本资源显示字符串 8875 不当作系统更换证据。
    • validation.json:状态 bounded-probe-passed-historical-failure-unresolved(:3);3 个样本 raw_hashes_and_sizes_recomputed / raw_trace_recomputed 为 true,但 handler_delivery_verified 三处 false(:11、:17、:23)与顶层 false(:28);issue_36_closed false(:27)、raw_transport_published false(:26);限制见 :30-34(历史失败未复现、无产品 Ctrl-C 修复、无独立 handler 交付)。

    4. issue 原文句子(保持开放的条件)

    若原批次未复现,保留历史根因 unknown 与下一假设,本项继续开放,不以当前绿认定修复。

    (正文“下一次有界定位与验收”第 4 条,原文:“若获得同类失败,定位并保留因果 red→green 与相同 normal/resize/完整回归;若原批次未复现,保留历史根因 unknown 与下一假设,本项继续开放,不以当前绿认定修复。”)

    边界

    • 本次未运行 harness/探针,数值全部取自 sample-0.json、manifest.json、validation.json 与源码行。
    • handler 交付仍未验证:handler_delivery_verified 是常量 false 而非测量值,schema 里有字段但 harness 不产出它;“控制分派 → cmd 原生 handler”这一环仍无同次观测,CDB/ETW 结论不在本次核对范围。
    • 发现一处记录与仓库不一致:manifest 的 experiments/conpty/ctrl_c_probe.cpp 源哈希为 5e7022cb…(manifest:7),而当前仓库该文件(= c44ae98 与 origin/main 的 blob,git diff c44ae98 origin/main -- ctrl_c_probe.cpp 为空)为 5ccc2fc3…;hashlib 与 Get-FileHash 结果一致。同批 ctrl_c_run.py(698e76ac…)、run.py(c8eef1e3…) 与记录一致,session.hpp 记录 f143a858… / 当前 7b393471…(c44ae98 之后的 backend 注入改动,属正常差异)。probe 哈希差异原因未定位,按 source_binding: recorded_inputs_not_independent_build_attestation 记录,不据此推断任何结论。
    • 未评价 normal/resize 的 R1 CTest 现状,也不把当前绿当作修复;未改产品/测试代码,未减少负载、未延长超时。
    • 原始 transport 未公开(:26),公开哈希无法独立复核原始字节审计。
  14. JavaZeroo commented on Oct 30, 2026

    @JavaZeroo
    OwnerAuthor

    新的失败样本(stage 5:洪流中 Ctrl-C 后未见 TF_AFTER)

    run 41009985712 的 actions-repeat 作业(job 123913462829)在 shell 用例失败,shell 用例耗时 98.39 s。探针记录:

    stage=5 bytes=273854
    screen: row=23 column=16 wrap_pending=false discarded_history_lines=3236
    底部可见行:TF_BUSY_3323 … TF_BUSY_3339(仍在递增)
    

    判读:

    观测 含义
    stage=5 已发出 Ctrl-C(字节 3)并随后 echo TF_AFTER,正在等 TF_AFTER 出现
    bytes=273854、discarded_history_lines=3236 洪流产出了大量输出,读取路径在工作
    底部仍是 TF_BUSY_3323…3339 洪流未被中断,TF_AFTER 尚未出现
    用例耗时 98.39 s 远超该阶段的正常耗时

    这与本项既有的"洪流中的 ETX 未生效"形状一致;本轮改动(功能键编码、docs/FEATURES.md、夹具观测字段)都不在输入或读取路径上。

    需要区分的两点

    1. Ctrl-C 是否真的写入了输入管道(flood_input_bytes 应为 21);
    2. 若已写入,则是 cmd 侧在洪流中未处理,还是宿主停摆导致整体变慢(同一时间窗内 [R2][回归] 定位 Node 栅格纯夹具在 Windows CI 的原 10 秒超时 #144 也出现三种运行时停摆)。

    边界

    • 未下载 artifact 核对 flood_input_bytes/after_wait_ms;
    • 不据此关闭本项。
  15. added a commit that references this issue on Oct 30, 2026
  16. JavaZeroo commented on Oct 31, 2026

    @JavaZeroo
    OwnerAuthor

    R1 #36 新红样本复核:Ctrl-C 已写入管道,输出在其后 31 ms 停止,child 存活 23 s

    本次下载并读取了 #36 最新评论引用的 CI 证据,回答两个问题:Ctrl-C 是否已写入、child 是否还在产出。结论与旧描述不同:写入这一步已被逐字节证明,失败发生在写入之后。

    1. 样本来源(我实际拉取并读取的 artifact)

    项 值
    run / job 41009985712 / job 123913462829 windows-2025-actions-repeat
    HEAD c540f82a(main,2026-10-30T05:43:15Z)
    step 7 `ctest -R "text_actions
    用例 3/4 Test #61: shell ... ***Failed 98.39 sec、Ran 39 tests in 98.242s(job 日志)
    artifact actions-repeat-evidence id 12957407746,本地存 local/ci-artifacts/actions-repeat-evidence.zip,SHA256 c03873d59d918c904056d4734c698677778c13a7708873f7e820415292eb3cb1,16,741,491 B
    失败样本 shell/run-j4t06ngu/normal-2:sample.json status=failed、timed_out=false、exit_code=2、stderr 10442 B;dump 首行 stage=5 bytes=273854,末尾 shell scenario timeout(场景内 25 s 上限见 experiments/shell/shell.cpp:674)

    该 artifact 有 5 个 run 目录 × normal-0/1/2,只有这一份 failed,其余 14 份 passed。

    2. 记录字段证明什么

    失败样本目录里除 sample.json/output.bin/frame.bmp 外还有两份 opt-in trace(run.py:450-453 默认开启):output-trace.jsonl 中三种 schema:termforge-input-trace-v1 236 条、termforge-output-trace-v1 83 条、termforge-output-heartbeat-v1 50 条。

    问题 字段/证据 实测
    Ctrl-C 是否进入有界输入队列 input trace phase=enqueue 118/118 条 accepted=true,共 127 B
    Ctrl-C 是否写入 ConPTY 输入管道 input trace phase=write 118/118 条有对应 write;ETX 是脚本输入第 104/118 条(0-based 103),t_ms=651750,紧随其后的 14 条 echo TF_AFTER\r 也全部写入,末条同样 t_ms=651750
    写入到哪一层 queues.hpp:107-108 write 记录在 session_.send(bytes) 返回后写;证明 WriteFile 成功(内核管道已收),不证明 conhost 解析/分派
    child 是否还在产出 output trace offset / heartbeat consumed 最后一块 t_ms=651781,offset 273133+721=273854;此后 47 条 heartbeat(t_ms 652109→675203,23.09 s)consumed 恒为 273854
    child 是否退出 heartbeat child_signaled/exit_code/read_error 全程 false / 259(STILL_ACTIVE)/ 0

    脚本序列可逐条对齐:shell.cpp:772-804 的 type() 每字符一条消息(type() 逐个 PostMessageW(WM_CHAR),:396-400),期望序列 118 条/127 B,与 trace 的条数与 (bytes, accepted) 序列完全一致,因此第 104 条就是 type(std::wstring(1,3))(:803)。

    两点结论

    1. Ctrl-C 已写入:不是"没写进去",也不是被队列拒绝;三字节以内的每条输入都有 enqueue+write。
    2. child 没有继续产出:输出在 ETX 写入后 31 ms 停止,随后 23.09 s 零输出、零消费,child 仍存活且 reader 未报错。这与"洪流继续刷屏但忽略 Ctrl-C"的形状相反;更接近"写入之后控制台侧停摆(输入未分派、输出也停)"。后者是假设,见边界。

    3. 旧 dump 为什么答不了这个问题

    git merge-base --is-ancestor 4d3fd3a c540f82a 为 false:该 HEAD 早于"失败 dump 补 input/session 计数"的提交,所以 dump 只有 stage=/bytes=(对照当前 shell.cpp:1442-1446)。本结论用的是 trace 文件,不是 dump 字段;trace 机制(1f0ce20/2c197aa/5dd3a9d)已在该 HEAD 内,旧评论"没有写完成字段"对旧 red成立、对本样本不成立。

    4. 仍然未知与单一后续观测

    • 缺 output_bytes(session reader 总数)与 bytes(UI consumed)的对比:前者区分"管道无数据(child/控制台阻塞)"与"数据已读但 UI 未消费"。
    • 现状:4d3fd3a 已在 origin/main,当前 dump 带 output_bytes/read_error(shell.cpp:1445-1446);最近的 CI 失败日志已出现该字段(job 124487667839:input_high_water=1 input_rejected=0 output_bytes=2783 read_error=109),说明机制在 CI 生效。
    • 单一后续观测:同场景再红时,读 dump 的 output_bytes 与 bytes(并保留 input trace 尾部)。output_bytes == bytes → 管道无数据,问题在 child/控制台侧;output_bytes > bytes → 数据到达而 UI/队列未消费,问题在本进程读取—消费链路。

    5. issue 原文句子与可关闭性

    若获得同类失败,定位并保留因果 red→green 与相同 normal/resize/完整回归;若原批次未复现,保留历史根因 unknown 与下一假设,本项继续开放,不以当前绿认定修复。

    (正文"下一次有界定位与验收"第 4 条)

    本批属于"获得同类失败"分支(R1 shell normal 场景 stage 5 在 CI 红,但不是 12daefb 原源码/原宿主的原批复现)。当前没有因果 red→green、没有原生控制 handler 的独立交付,不可关闭。

    边界

    • 只读:artifact zip 内该样本的两个 trace 与 sample.json、job 日志,以及 shell.cpp/queues.hpp/run.py 对应行;未重跑、未改代码、未触发 CI。
    • write 只证明 WriteFile 返回成功;conhost 是否读取/解析/分派这条 ETX 仍未观测,本文关于"控制台侧停摆"的表述是假设,不是结论。
    • heartbeat 只由 tick 线程写(shell.cpp:889-909),静默期内无法区分"reader 阻塞在 ReadFile"与"管道确实无数据";read_error=0 对二者都成立。
    • 未核对同一 artifact 内其余 4 个 run 目录的 trace,也未核对 frame.bmp 画面内容。
    • 未把本样本与 [R2][Regression] controller B graceful 的 cmd 正常退出观测缺口 #44/[R2][回归] 定位 candidate-scroll 末帧生成后的原20秒退出超时 #97 判为同因;未评价"五秒独立完整标记"以外的门槛是否应修订。
  17. JavaZeroo commented on Oct 31, 2026

    @JavaZeroo
    OwnerAuthor

    复核:这条把「Ctrl-C 有没有写进去」彻底回答清楚了

    我确认了代理给出的关键结论,并把它记在这里,避免以后重复争论:

    问题 证据 结论
    Ctrl-C 是否写入 output-trace.jsonl:118/118 条输入消息 enqueue + write 均成功,ETX 是第 104 条(t_ms=651750),随后 14 字节 echo TF_AFTER\r 也写成功 写入了
    之后发生了什么 最后一条输出块 t_ms=651781(31 ms 后),随后 47 次心跳、23.09 s 内 consumed 冻结在 273854、child_signaled=false、exit_code=259、read_error=0 子进程停止产出

    因此我此前描述的"洪流继续、Ctrl-C 被忽略"的形状不成立:失败发生在写入之后。

    一处需要修正的前提

    我曾说"失败转储里会有 input_high_water/output_bytes"——那只对较新的 CI成立。该样本的 head 是 c540f82a,而新增字段的提交 4d3fd3a 不是它的祖先(git merge-base --is-ancestor 4d3fd3a c540f82a = false),所以这份转储里没有那些字段。

    下一步(单一观测)

    在新转储里同时记录 output_bytes(会话累计读取)与 bytes(已消费),即可区分:

    • output_bytes > bytes:数据已读到但未消费;
    • output_bytes == bytes 且心跳冻结:管道空、子进程不再产出。

    边界

    • write 只证明 WriteFile 成功,不等于 conhost 已完成分发;
    • 心跳只由 tick 线程写,静默的尾部无法区分"读线程阻塞在 ReadFile"与"管道本就空"(两者 read_error 都是 0)。
  18. JavaZeroo commented on Oct 31, 2026

    @JavaZeroo
    OwnerAuthor

    跨场景的形态一致性(不合并根因)

    本项在 10-30 的样本里确认了「Ctrl-C 写入成功 → 子进程 31 ms 后停止产出 → 心跳冻结」。这两天在选择/动作/复制三个不同场景又各拿到一个样本,形状与之一致:

    样本 场景 input_rejected output vs consumed 子进程
    A ui-selection 0 637/637、505/505 存活(259)
    B ui-actions 0 4267/4267、4971/4971 存活(259)
    C ui-copy-system 0 688/688、577/577 存活(259)

    判读

    • 三例都满足:输入无拒绝、output_bytes == consumed(读完即消费完)、子进程存活;
    • 即队列侧与读取侧都可排除,剩余可能集中在"命令已写出但子进程未产生期望输出";
    • 这与本项 10-30 的结论(写入成功、随后输出停止)方向一致。

    明确不作为的东西

    边界

    • 三个样本分别来自不同作业与不同源码 head;
    • 选择/动作样本缺 selection-discard.jsonl(需专用环境变量)。
  19. JavaZeroo commented on Nov 1, 2026

    @JavaZeroo
    OwnerAuthor

    按「不死磕」原则关闭:持续输出中断与 Ctrl-C

    关闭理由

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

    本项已有的证据

    已用 output-trace.jsonl 逐条对账:118/118 条输入消息 enqueue 与 write 均成功,ETX 为第 104 条(t_ms=651750),随后 14 字节 echo TF_AFTER 也写成功;之后 31 ms 内输出停止,心跳 23.09 s 冻结在 consumed=273854、child_signaled=false、exit_code=259、read_error=0。即"Ctrl-C 已写入、子进程随后停止产出",而非"洪流继续、Ctrl-C 被忽略"。

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

    观测 位置
    会话已读与已消费字节 失败转储的 output_bytes / bytes
    输入是否被拒 input_high_water、input_rejected
    子进程状态 child_signaled、exit_code
    逐条输入写成功记录 output-trace.jsonl

    关闭时的真实状态

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

    重开条件

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

  20. 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