## 已观察的失败 [PR141默认工作流40742159646](https://github.com/JavaZeroo/termforge/actions/runs/40742159646),attempt1,head `43883022883d382e3dd57bd627e9c735bafe58ca`、实际checkout merge `9ecdba0`,Windows job123006322929的CTest **52/53**、285.94s。唯一失败为 `test_watchdog_kills_only_owned_job` **正式watchdog前的startup(normal)**,`resized dimensions mismatch`,不是watchdog工作负载超时或越界杀进程。 旧固定源probe先已收到TFREADY、80×24和精确UTF8 ECHO;`session.resize(120,40)`未抛错后仅发送一次SIZE。实际新增回复仍为 `TFSIZE:80x24:END`,原5秒等待未收到120×40。VT前缀另有CSI8;40;120t/旧画面重绘,不能据此证明child实际尺寸。样本ready1/echo1/resized0/descendant0;close后child code3221225786(0xC000013A),自然退出未知,read_error109、output596B、active_children_after0、forced reader/process均0,elapsed6052.71ms。具体调用先后、系统后台resize/child查询/流排序原因未知,尚不认定异步竞态。 本PR未改probe/Session/测试源。专用Qt/fixedConPTY验证和另一push运行不覆盖本system/legacy样本,未提交同HEAD重试。 原件artifact12839763555 ZIP SHA256 `1d077810c6dc5f33eb5ba300c1888328ad2e8631117727fb57e391370e772756`;LastTest.log145190B SHA256 `7329a3b656223fb011cb8e7c28aa90b5c41599f395358be356a50e3b23dbe05f`,本地保全。父项#38,相关#29/#143;不同source/backend结果分列。 ## 有界接续 - [ ] 固定旧输入、源码/二进制、实际system ConPTY/Windows身份、一个可证伪时序假设、样本数与停止条件;原5秒SIZE与watchdog8秒不变。 - [ ] 记录resize调用前后、子程序独立CSBI采样、输入接收/nonce与原始VT的各阶段,不用请求值/返回S_OK/旧回显或resize VT作为childack。 - [ ] 获得同类反例后单变量因果验证;任何采样/重查询协议变更明确为新源码与诊断,不丢弃旧尺寸或把新成功回填旧根因。未复现只记录该批实际结果。 - [ ] 原自然退出/清理边界与所有原件保留;修复复验实际完整行为。当前#143正式fixedConPTY动态尺寸工作独立推进,不自动修复本system探针。 不运行WindTerm、不修改个人桌面,不延长期限/删预期/重跑取绿。本项和#38/#35/R2保持开放。
Activity
JavaZeroo commentedon Oct 29, 2026
PR168 的首次 push 回归新增同类观察:run40814207316、Windows job123251361984,60/61、299.34s;唯一 conpty 失败在 close 第三轮的 resize reply gate,尚未进入 TREE/SPAM。ready/echo=1、resized=0;目标请求120×40,但596B完整VT仅含三次80×24回复和resize VT。CLI1、非外层timeout、Job0/12/0,不能称已建忙碌树的关闭回收失败。
该596B与本issue旧PR141 startup失败捕获逐字节一致,SHA256
c63fc584c75f7be84b1f4a6a995841ade67af9931c43eaae44f0375e0f56a085;相关六个ConPTY源文件未变,只支持同类观察,根因仍未知。失败artifact12871348874为4797707B/SHA4cb48a8827605f7facf4ec294b99bd014f81cff0d3514ecf4e6135a369a0c4f8,原件及成员验和留私有;该artifact不含EXE,逐运行EXE和系统DLL身份未知。同head的PR运行 Windows61/61、277.85s;其checkout29c58f4与push fe72d897的tree相同,但结果独立保留,不覆盖红例,未rerun/retest。本次#73相关断言及#160 watchdog均通过。R2与本issue继续开放。
diagnose(conpty): reproduce the recorded fresh-session resize sample …
docs(conpty): publish bounded resize-reply samples for #145
JavaZeroo commentedon Oct 29, 2026
有界接续切片:把“resize 返回后立即排入 SIZE 查询”这一时序放大采样,判断它是否足以解释本 issue 的旧尺寸回复。
方法(不改原探针/oracle/5s 等待):新增
conpty_resize_reply_probe+resize_reply_run.py,客户端报告自己的 buffer(dwSize) 与 window(srWindow),回复带独立 tag;raw模式同一会话交替 120×40/80×24 各 200 轮,startup模式每次全新会话复刻ready→SIZE→ECHO→resize(120×40)→SIZE。运行于 workflow_dispatch 的windows-2025-resize-replyjob(build.yml 同一 hosted 镜像),只断言结构完整性,陈旧计数作为证据记录。结果(结果与身份、validation.json):
resize VT100% 先于回复;回复中位 8.7–16.1 ms、最大 64.7 ms,远低于原 5 秒等待,说明失败样本不是“等得不够久”。结论与边界:否定“resize 后立即查询存在必然时序竞态”这一假设;本 issue 的两条 CI 失败(PR141 40742159646、PR168 push 40814207316,596B 逐字节一致)仍是真实失败,根因未知,
#145/#38状态不变。未覆盖:原探针在完整 ctest 上下文中的运行、hosted 运行器镜像/宿主差异、以及“每次运行首条会话”这类稀有例外。下一步(有界):在同一 hosted 运行器上跑原探针本身的重复批次,确认 clone 与原 oracle 的失败率是否一致;若两者皆为零,优先固定首个会话/首条 resize 的宿主状态,而不是继续放大同一时序样本量。
Merge pull request #171 from JavaZeroo/diagnose/system-conpty-resize-…
JavaZeroo commentedon Oct 29, 2026
诊断切片已合入 main(PR #171,
dc666ef):conpty_resize_reply_probe+ dispatch-only 的windows-2025-resize-reply作业 + 固定结果。结论仍是 2800 样本无陈旧回复(hosted windows-2025:1000 交替 resize + 500 全新会话),否定“resize 后立即查询必然竞态”。本 issue 保持开放:原两条 CI 失败(PR141 40742159646、PR168 push 40814207316)仍是真实失败、根因未知;下一步按 bounded 计划在同宿主跑原探针的重复批次,并优先固定“首个会话/首条 resize”的宿主状态。diagnose(conpty): sample the probe after the regression suite refs #145
diagnose(conpty): sample after the console-heavy ConPTY tests refs #145
diagnose(conpty): repeat the original probe and sample after console …
JavaZeroo commentedon Oct 29, 2026
第二片有界接续:重复原探针本身,以及“先跑控制台密集测试再采样”,用来判断旧尺寸回复是否与作业上下文有关。
方法:新增
experiments/conpty/repeat_run.py,每迭代复用既有run.execute()(自有 Job、GO 门、原 5 秒等待、原断言),逐次保留独立结果;两个 dispatch-only 作业 —— 隔离重复 40×4、先在conpty_ctrl_c(5.31s)/conpty_margin(0.31s) 通过之后采样 20×4。结果:
唯一红色不是本 issue 的症状:iteration 10 的 normal repeat 1,
resized=1、最终 VT 为TFSIZE:120x40:END、child exit 37、608B 完整;失败判据是steady_resources=false——会话结束后线程 4→6、resource_settle_ms=1011.02超过 1 秒结算窗口。这属于 #38 族的稳态夹具边界(首次初始化只对 startup 豁免),不并入 #145 根因,也不说明 resize 机制有问题。结论:原样本在“隔离”和“轻度前置”两种上下文下都未复现旧尺寸回复;根因仍未知。本片只缩小假设空间,不关闭 #145。
保留的反例:分支上“先跑完整 ctest 再采样”的作业(run 40848143873)因该 dispatch 作业缺少 build.yml 的夹具准备,在
benchmark_tools/differential/workflow_*/shell失败,未进入采样阶段——这是“作业环境不等价”,不能当作采样结果。下一步(有界):要真正复刻 build.yml 的上下文,需要复制其准备步骤(hosted shell/benchmark 夹具),或改为在 build.yml 的 job 内直接插入一次重复采样;两条都会改动常规 CI,需先评估成本。否则建议把 #145 当作“低频不可复现”,由 #38 的回归策略按已记录失败处理,不再无界重复。
Merge pull request #173 from JavaZeroo/diagnose/conpty-probe-repeat-r145
JavaZeroo commentedon Oct 30, 2026
现状记录:连续 13 轮全绿,旧尺寸回复仍 0 复现
text_actions|selection_context|shell,5 次重复)已连续 13 轮全绿,累计约 260 次执行,仍没有出现"resize 后回复旧尺寸";pid/child_signaled/exit_code、几何切换记录、失败路径 readiness)都能在下一次同类命中时提供更细的边界。保持开放的理由
本项验收要求"获得同类反例后单变量因果验证";目前只有大样本未复现,没有同类反例,因此不改写为"已修复",也不关闭。
下一假设
若再次出现,优先检查:resize 请求与
SIZE回复之间的时序是否被 ConPTY 的尾部队列重排(与 #194 的重绘错位同一类窗口),用现有termforge-resize-trace-v1与回复时刻对照即可判定。JavaZeroo commentedon Oct 30, 2026
对 2800 样本记录的核对:数字可复算,身份可复算,结论口径需收紧
位置更正:该切片实际在
experiments/conpty/results/2026-10-29-resize-reply-r145/(research/ui/results/下没有该目录)。同族还有experiments/conpty/results/2026-10-29-probe-repeat-r145/。1. 记录项逐条复算
validation.json:15-62)replies_with_resize_vt_before_reply="2800/2800"一致,各环境表逐行相加合规resize_to_reply_us_median_range=[8686.5,16072]µs = 8.69–16.07 msresize_to_reply_us_max=64735µsoriginal_probe_wait_ms=5000source_sha256validation.json:4记录的 commitd66f9f3上按 CRLF 检出形式重算:probe.cpp03efd353…、run.pye3ff4b07…、session.hppc85872fd…、backend.hppc64309b7…4/4 逐字节相同core.autocrlf=true,cmp/hpp 的 LF blob 哈希不同属检出形式差异,不是内容漂移)2. 引用时必须保留的两条口径
resize_reply_run.py:29-45仅summarize()统计stale_buffer/stale_window/disagreement并写入证据,不设 gateresize_reply_probe.cpp:112-116读GetConsoleScreenBufferInfo,同时给dwSize与srWindow;回复带独立 tag(:134/:149)结论:记录本身没有发现算术或身份矛盾;它排除的假设范围应严格写作"resize 成功后立即排入 SIZE 查询"这一孤立时序,而不是"任何时序竞态"。
3. issue 要求的下一次观测只有一个
在失败真正发生的上下文里(build.yml 的完整 ctest 顺序与并发、同一 runner 镜像),对该 job 的第一个会话 / 第一条 resize记录 resize 调用前后各阶段时序,并对 child 做独立 CSBI 采样。
理由(避免重复已做完的样本放大):
2026-10-29-probe-repeat-r145,run 40847785625)三种条件都为 0,唯一尚未建模的变量就是宿主/镜像/并发顺序——即本切片 README 的"下一步 2"。(README 的"下一步 1:在同 hosted 跑原探针本身"已由
2026-10-29-probe-repeat-r145完成,不应再作为下一步重复。)边界
experiments/conpty/results/下两份切片与experiments/conpty/resize_reply_{probe.cpp,run.py},未重跑任何探针、未 dispatch 作业、未改探针或产品代码。performance_claim=false,不构成任何预算。JavaZeroo commentedon Oct 31, 2026
又一批量化结果:1500 轮 resize,三项异常计数全为 0
数据来源:run 41198898623 的
conpty-resize-reply-r145artifact(10 个resize-reply.json:6 个 session + 4 个 startup 配置)。status=passed)stale_bufferstale_windowbuffer_window_disagreementresize_vt_before_reply延时(探针自带、仅作分布参考、非性能声明):
resize_to_reply_us中位数(10 个文件的中位数再平均)对本项的意义
本项要的是同类反例:一次实际观测到 resize 之后仍回复旧尺寸(
TFSIZE:80x24:END)的样本。本批 1500 轮里:即:这批仍未复现,与之前的结论一致。
边界
resize_to_reply_us是探针自身计时,不构成性能声明(performance_claim: false);本项按自身验收文字保持开放。
JavaZeroo commentedon Nov 1, 2026
按「不死磕」原则关闭:系统 ConPTY resize 后仍回复旧尺寸
关闭理由
用户明确「可以接受不完美、不需要一直死磕一个问题」。本项属于批次内不可复现、诊断已就位的一类,因此按此原则关闭。
本项已有的证据
run 41198898623 的
conpty-resize-reply-r145artifact:10 个配置、1500 轮,stale_buffer=0、stale_window=0、buffer_window_disagreement=0;resize_to_reply_us中位约 13.8 ms、最大 23.6 ms(探针自身计时,非性能声明)。已就位的诊断(再次命中时可立即判读)
resize-reply.json的stale_buffer/stale_window/buffer_window_disagreementresize_to_send_us/resize_to_reply_us关闭时的真实状态
本项不是根因修复。原始失败记录仍保留,未被新批次覆盖。
重开条件
若同类失败再次出现,凭上述诊断字段可直接判读,恢复本项即可,无需重做本轮探索。