Repository navigation
Description
当前接续(2026-11-01)
最新有界批次本机7/7、当前源码hosted69/69通过;原hosted stage6/30秒事件未复现。stage5 WSL观察窗口已有修正与证据,不能替代stage6旧事件的同因证明。
后续调查须针对原事件谱系/明确假设,保留readiness、传输、退出与Job证据,不再反复跑当前绿色版本。本项继续开放,归#38汇总;下方保留原合同和证据。
真实触发与固定证据
PR #79 的 Windows CI,HEAD c820691(main163d8b8加#72限定oracle修正),实际合并checkout 9b62087;默认自研核心/system配置。完整CTest45/46、294.98s,shell唯一错误是 test_local_shell_launch_working_directory_and_cleanup 的第一轮 ui-shells stage6,原30秒耗尽,外层40秒未超时。#72的原两轮保存/普通恢复/钳制恢复全部通过,不能把本失败算作#72重现。
artifact12669796699,4710638B,SHA256 caa86b6a6d376977f28fa6e1301518ac56cfaa835c08968777a5ed0f46ae1574 与GitHub一致;下载一次,只提取26个相关文件、2893470B。本地原件 local/r79-ci-failure,包含sample、progress、layout、shells、固定测试帧及LastTest日志。
已观察与未知
- cmd、Windows PowerShell、pwsh、WSL-Ubuntu均已核对工作目录;源码stage5检查四者真实尺寸标记并向当前WSL发送exit,随后等待collected=1/session_count=3。
- 30秒失败帧上WSL已有TF_SIZE_54x12及TF>,没有可见exit回显;这不能单独证明输入未发送或丢失。底部pwsh也已返回TF>。
- sample return2、Job active0/total34/terminated0、desktopgone;progress中四会话的exit91发生于失败清理,不能当作自然退出成功或自然退出故障原因。
- 当前只有到stage6的观测,缺WM_CHAR/队列/实际WriteFile、WSL接收、native size helper退出与shell返回的时序及自然退出端点。shells.json的normal_exit=true在stage5提前写入,不能覆盖最终失败。
- 与#44的controller graceful、#73的选择首记录缺失没有同因证据;不得合并根因或重跑取绿。
有界交付与验收
- 固定原输入/源码/后端/环境与原失败,建立同症状红例。先区分UI/队列未发送、Windows子进程→WSL转换时输入丢失、WSL已收exit但生命周期未回收三个假设。
- 使用有上限的实际字节与阶段观测或事件握手;需要控制调度时采用明确夹具协议,不加固定sleep、扩大30/40秒或跳过WSL。
- 同一原触发的修前/修后及必要负例;真实目录/子尺寸、四shell顺次正常退出、失败清理与Job/desktop分别留证。
- 原两轮完整四shell方法和声明配置完整回归通过;更新[R2][回归] 收敛 Windows 可靠性与历史未闭合失败 #38/#35和FEATURES/EVIDENCE,不借另一次CI绿覆盖原原因。
父项#38,本项独立阻塞其可靠性出口;ready,无需等待父项或#72结项。限定修正已随 PR79 合入 main;原 hosted 事件因果仍待定位。
当前因果实验
原源码 c820691 的本机 Win11/system 四 shell 原场景有界运行6次,全部通过;按上限停止,不用于解释原 hosted 失败。
受控改变仅使 WSL 启动的 native size helper 在输出原 TF_SIZE 标记后,PeekConsoleInputW 观察到完整 exit\r 才退出,且不消费该输入。一次运行实际复现 stage6/30s 超时,helper 记录字节657869740d;WSL随后显示新TF>但未退出。Job active0/total20/terminated0、desktopgone。证明尺寸输出不是 shell 输入就绪端点;此诊断改变了调度,原hosted样本没有该边界记录,尚不能据此证明原样本一定同因。原件与源码/二进制/补丁身份保存在local/r80-held-child。
已将该边界变成实际ui-shells事件握手回归:WSL native helper在尺寸输出后等待宿主release;在四个真实尺寸标记齐全时,实际退出条件必须仍阻止下一命令,随后释放并验四shell顺次退出。保留旧条件的回归在4.795s明确失败:size output was mistaken for shell input readiness,local/r80-red保留源码补丁、原始样本及二进制。最终新条件只限WSL:必须观察同次尺寸输出之后的独立新提示符;原30/40s不变,normal_exit证据移到四会话实际回收后写入。
限定修正已验证,原事件仍开放
实现2b85fef48149f022b50d9d8878f62539e02c92ba:最终事件握手与原两轮共3场景通过(两方法10.872s),四会话顺次stage6/7/8/9、exit0、Job0/desktopgone。中间全shell提示符方案的cmd重绘stage5失败保留,最终未放宽共享oracle,仅约束已复现的WSL交接。
同源码默认/system完整CTest46/46,283.89s;shell39方法81.664s、3skip,全套12内部skip(候选依赖/真实应用依赖、hosted CF、opt-in参考注入、私有窗口站OpenClipboard拒绝)完整分列。原held红、旧gate红及中间stage5红都有独立源码/二进制/原件哈希;Standards/Spec代码审查无实现发现。文档与公开白名单记录已整合;PR82 合入 PR79 后,PR79 已以 af63a27 合入 main。Build 40374618725 与 Candidate 40374618675 均通过;Windows 默认/system 46/46、268.68s,实际 checkout539557997b6eca198e46065443faff2c8d8147dd。
原hosted stage6是否同因仍未知;本项保持开放,不用限定修正或新CI成功替换旧失败的因果证据。#81另追踪PR76环境准备超时,产品测试未运行。
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsTodo
Activity
Merge pull request #82 from JavaZeroo/investigate/local-shell-exit-r80
Merge pull request #79 from JavaZeroo/fix/workspace-oracle-main-r72
JavaZeroo commentedon Oct 28, 2026
新增独立相关样本(不认定与原stage6同因):纯文档PR142 head
cafd632016d9daa48e7bc13dadde7013e2ff11b4的默认PR工作流40742782507/Windows123008512465,attempt1,CTest53/54、282.45s;同一四shell方法首轮ui-shells明确workspace shells scenario timeout at stage 5,原有源未改。当前只有stage5超时堆栈,尚未检查具体shell/native helper/提示符阶段,不据此称WSL或输入丢失。failure artifact12841470214 SHAf6a61c08024417cb6700365eefffb9382517026b2286388b0e14c3d74b2fd229;LastTest146975B SHAa524cf936c0336034a071334d4c4fdb297b17f3066647ae8faa7a8b1439cd603,本地原件保全。该head天然push默认成功,不能覆盖本次PR失败;未重跑。与原stage6及中间本机stage5调度红分列,准确因果未知。JavaZeroo commentedon Oct 28, 2026
第二个stage5独立样本:PR140 head
b3ae687fc2b9a60532a8c5edaa0db43a80d13d45push/default40744486195/Windows123014523153,attempt1,CTest53/54、283.78s。本次第二轮shells-1失败(shells-0与held-size-helper通过),原30秒stage5/外40秒未超时,exit2、Job0/total34/terminated0、desktopgone。四者cwd-verified都已记录;失败清理的exit91不当自然退出。失败帧可见WSL的TF_SIZE_54x12及新TF>、pwsh TF_SIZE_82x5与TF>,隐藏cmd/PS5.1条件以及是哪一个size/settled/transport gate未满足仍未知;不以可见两会话推断四者通过。与PR142第一轮stage5、原stage6各自分列,不预先归同因。artifact12841541325 SHA
7a2a1fc74b706eb208dadfaf0f8691cb71f51e343470736723195c1eaed389d0;LastTest145516B SHA42a8dbf6b9de77eb8ad9128d4171b05ce57fe7d2e22412b68419a501d059d308;均本地保全。原PR140运行自然成功不覆盖本push失败,无同HEAD重试。JavaZeroo commentedon Oct 29, 2026
新样本(PR #202,只新增一个只读分析脚本,不改产品/测试):
shell95.55s 失败:test_local_shell_launch_working_directory_and_cleanup→workspace shells scenario timeout at stage 5;同一 job 里还出现了一次准备阶段的瞬态失败:
{"schema":"termforge-hosted-shell-preparation-v1","status":"failed","failure_code":"preparation_guard"} {"schema":"termforge-hosted-shell-preparation-v1","status":"passed","failure_code":"none"}即准备步骤失败一次后重试通过(该步骤自带一次重试),与本项 stage5/6 的退出超时同属托管环境低频形状。保留红例、不重跑取绿。
JavaZeroo commentedon Oct 29, 2026
新样本:四个 shell 都已启动并验证 cwd,卡在 stage 5 退出/确认
run 40966552246(5 次重复版)的
shell测试失败:shells-0:workspace shells scenario timeout at stage 5,exit_code 2,Job 回收后 active 0/total 34,desktop_gone=true。shells-progress.jsonl的完整阶段判读
与既有记录的关系
本项此前记录的 stage6 失败(PR79)与本次 stage5 相邻;本次提供了逐 role 的阶段与 tail 字节,可直接对照"退出顺序/确认条件"。
下一步(仍属本项):在同合同下把 stage 5 的"等待条件"(四个 session 关闭计数、Job 成员归零、desktop 释放)分别记录,以判断是哪个条件未满足。
Merge pull request #212 from JavaZeroo/diag/shells-stage5
5 remaining items
Merge pull request #220 from JavaZeroo/diag/transport-probe2
JavaZeroo commentedon Oct 30, 2026
又一次 stage 5 超时(PR #234 的 Windows 回归)
job 123898511789:
workspace shells scenario timeout at stage 5。与既有结论一致:stage 5 等待四个会话的尺寸就绪(
settled()+TF_SIZE_<cols>x<rows>,WSL 还要求 transport 完成),超时分支会写出shells-size-readiness.jsonl与 WSL 的shells-transport-probe.jsonl。本次未下载 artifact 复核那两份诊断文件,因此不追加新判据;仅记录该形状在 IL/DL 变更(与本路径无关)的回归里再次出现。
边界
JavaZeroo commentedon Oct 31, 2026
stage-5 的卡点已由产物直接定位:WSL 尺寸标记没有独立字节记录,不是输入丢失也不是回收挂起
1. 本次核对的原件(我自己下载并逐字节读过)
bccf7a1),artifactfailure-windows-2025(12955492292,6555298 B),下载后复核。test-artifacts/shell/run-x8hs3wwb/shells-0/:sample.json 526 B、shells-progress.jsonl 3036 B、shells-size-readiness.jsonl 751 B、shells-transport-probe.jsonl 169 B、output.bin 2365 B、output-trace.jsonl 215950 B。mode=ui-shells、exit_code=2、stderr="workspace shells scenario timeout at stage 5"、job_after0/34/0、desktop_gone=true。2. 逐会话事实(readiness 原文)
* 非 WSL 的 transport 列是代码短路常量:
workspace_shells_scenario.hpp:23-24「kind != L"wsl" || transport_output_completed(...)」。所以该列只有 wsl 一行有信息量,不能用三行 true 推断「三个会话的 transport 都过了」。同目录的 transport probe(原文):
{"role":"wsl","marker":"TF_SIZE_54x12","output_seen":false,"prompt_seen":false,"malformed":false,"last_line":"TF> "}即:标记在屏幕上(
marker_present=true,由contains_line在渲染后网格上判),但字节级 oracle 从未把任何一条「记录」判等为TF_SIZE_54x12(output_seen=false);prompt_seen因为以output_seen为前置,必然同为 false。3. 为什么
output_seen=false(可复算的字节级重建)termforge-output-trace-v1记录 bytes 之和 等于 output.bin 的 2365 B,因此可按记录顺序把四会话语流逐 chunk 切开:t1 608 / t2 660 / t3 624 / t4 473 B;t4 含/mnt/d/...→ WSL。begin_output_observation()会先清空缓冲(shell.cpp:1360),所以 readiness 的tail_bytes就是该会话观测窗口的长度。WSL(t4)最后 185 B 窗口原文:transport_completion.hpp:19-97逐字节复算这 185 B:得到output_seen=false, prompt_seen=false, last_line="TF> ",与产物 probe 逐字段一致。同一复算对 82x5 两个会话窗口给出output_seen=true(它们的标记独占一条 CRLF 终结记录);54x12 的 powershell 复算同样 false,只是它不受该门控。...shell_size_client.exe"),随后ESC[10;1H是 CUP;transport_completion.hpp:62-66明确「不跨 CUP 拼接回显」,于是该记录被标为非 literal,紧接的TF_SIZE_54x12追加到同一记录也不能置位 → 永远 false。把窗口起点挪到 CUP 之后(或标记前有 LF)即可通过,这正是 82x5 两个会话的形状。4. 对本项三个假设的处置
accepted全 true,拒绝 0exited(exit91、stage=5)属失败清理,不是自然退出原 PR79 的 stage6 事件仍未知;本样本只解释 stage5 等待条件,不能替代原因果。
5. 关闭判据与下一步
原文判据:「原两轮完整四shell方法和声明配置完整回归通过;更新#38/#35和FEATURES/EVIDENCE,不借另一次CI绿覆盖原原因。」
→ 当前不可关闭:stage5 的等待条件机制已定位,但还没有「改窗口起点 / 改 oracle 契约」的单变量修前修后对照,也没有原 stage6 的因果。
单一下一步观测(不改 30/40 秒、不扩样):同一次
ui-shells超时,把 WSL 的 185 B 观测窗口原文(现在只落tail_bytes)以及 marker 所在记录的累积文本(probe 现在只落last_line)写进产物;这样就可以在产物内直接复算transport_output_completed,把「窗口起点落在回显中间」从重建变成记录,并据此二选一:改窗口起点(不动契约),或改 oracle 契约(transport_completion.hpp:6-17明写其语义,放宽需用户确认)。边界
workspace_shells_scenario.hpp、local_shell_diagnostics.hpp、transport_completion.hpp、shell.cpp、queues.hpp的当前 main 版本(origin/main 8c7b1ed)。未改代码/断言/期限,未重跑、未 dispatch。last_line。为免越界,未把重建当作产物读数陈述。check_size()与输入回显的先后),属未知。Merge pull request #277 from JavaZeroo/diag/transport-window-hex
JavaZeroo commentedon Oct 31, 2026
又一次 stage 5 命中,这次带上了每标签页计数器
run 41190299715(job 124505550311):
判读
input_rejected=0input_high_water2/1/19/5output_bytes == consumed(592/592、634/634、537/537、457/457)read_error=0child_signaled=false、exit_code=259即:这不是输入/读取/回收侧的停滞,而是四个会话都没有推进到 stage 5 要求的就绪条件——与上一轮"WSL 的 185B 观察窗口起点落在回显中间,标记与回显同一条记录、oracle 不跨 CUP 拼接"的解释一致:
transport_completed=false是判据匹配问题,不是数据没到。因此本项的状态
边界
shells-size-readiness.jsonl与 probe 行(那是失败分支写出的独立文件,需从 artifact 取);stage=0属选择/工作区场景的已知局限(ShellWindow::stage_不参与这些模式)。JavaZeroo commentedon Oct 31, 2026
首次拿到带
stage与自动判读的失败样本PR #289 的 Windows 回归(job 124536048854)命中本项形态:
新增的两点信息
stage=5(Workspace 自己的阶段)drained=yes与既有结论的关系
此前复现的机制是:WSL 会话的 185B 观察窗口起点落在命令回显中间,
TF_SIZE_54x12与回显同属一条记录、中间只有ESC[10;1H,而transport_completion.hpp:62-66不跨 CUP 拼接 →output_seen永远 false。本样本与之一致:数据都到了、也都消费了(
drained=yes),只是判据没匹配上。修法方向(待你确认)
边界
shells-size-readiness.jsonl与 probe 行,窗口字段实测值仍未拿到。JavaZeroo commentedon Oct 31, 2026
拿到窗口原文了,并且验证了修法方向
从 run 41200805448 的
failure-windows-2025artifact 取到 wsl 探针行:{"role":"wsl","marker":"TF_SIZE_54x12","window_bytes":185, "window_hex":"221b5b3f31303034h 1b5b3f32356c /mnt/d/a/termforge/.../shell_size_client.exe\" 1b5b31303b3148 54465f53495a455f35347831320d0a 54463e20…"}解码后的结构:
readiness 四行也印证:cmd/pwsh/powershell 的
transport_completed=true,只有 wsl 为 false(observed_output_tail_bytes=185)。我试了「B 方案:改 oracle 跨 CUP 拼接」,被既有合同测试否决
在
transport_completion.hpp里把 CUP 当作记录边界后,transport_completion_test立刻失败:这个测试的存在意义正是防止我把回显前缀"洗掉"从而凭空认定标记已输出。 所以 B 方案不可行——不是实现困难,而是它违反既有合同。改动已回退(
transport completion checks passed重新通过)。因此方向确定为 A:改观察窗口起点
正确做法是让观察窗口从命令回显之后开始,而不是让 oracle 去猜。具体位置:
workspace_shells_scenario.hpp:73附近begin_output_observation()的时机边界
observed_output_tail_bytes一致,可交叉核对;JavaZeroo commentedon Oct 31, 2026
A 方案的可行落点(读完调用链后)
观察窗口的起点在这里:
窗口从发命令之前就开了,所以 WSL 的输入回显(
/mnt/.../shell_size_client.exe\")必然落进窗口,后面才是ESC[10;1H+ 标记。三个可选实现
\r\n,使标记自成一条记录begin_output_observation(),即等回显结束再开窗我倾向 A1
因为:
CUP cannot discard an echo prefix…)都不动;需要先确认的一件事
A1 要求 size helper 能控制自己在标记前的输出。我要先读
shell_size_client的实现确认这一点;若它只输出标记本身,那实际可行的最小改动是 A2。边界
experiments/shell),不改变产品行为。JavaZeroo commentedon Oct 31, 2026
排除 A1:helper 已经输出换行,是 conhost 把它变成了 CUP
experiments/shell/size_client.cpp:16:helper 本来就先输出
\r\n。但窗口十六进制里看到的是:即那个
\r\n被 conhost 在 VT 输出模式下翻译成了ESC[10;1H(绝对定位到第 10 行第 1 列),不是字面 CRLF。排除 B:既有合同明确禁止把 CUP 当记录边界
transport_completion_test.cpp里有三条直接相关的用例,且用的都是第 1 列的 CUP:也就是说,"列 1 的 CUP"也不允许被当作换行——设计上就是要防止把回显前缀洗掉后凭空认定输出。
所以只剩场景层:A3
可行判据很具体:回显是我们自己发的命令文本。WSL 场景知道它要执行的 helper 路径,所以可以:
check_size()发出命令;observed_output()里出现该 helper 路径(说明回显已完成),重新begin_output_observation()开一个新窗口;ESC[10;1H+ 标记 + 提示符,oracle 就能正常匹配。风险:重开窗口会丢掉此前内容,若标记恰好在重开前到达就会漏掉。因此需要用"窗口里已含标记但 transport 未完成"作为触发条件,而不是无条件重开。
边界
Merge pull request #290 from JavaZeroo/fix/shells-wsl-window
JavaZeroo commentedon Oct 31, 2026
修前/修后对照:同一提交内容,结果从红转绿
ci/focus-input原始版本,430…)only输入,不含窗口修复workspace-failure mode=ui-shells stage=5only输入改动 + WSL 窗口修复修复内容(#290,已合并)
为什么这是有效的证据
transport_completed=false),不是别的偶发;ui-shells场景通过,说明 WSL 的transport_output_completed现在能匹配上。仍未证明的部分
shells-size-readiness.jsonl里 wsl 的transport_completed是否已变为true(需要该次运行的 artifact,我可以下一轮取);边界
experiments/shell),不改产品行为;JavaZeroo commentedon Oct 31, 2026
修后证据的边界(对照本项自己的验收文字)
本轮去取修后那次运行的 artifact,想确认 wsl 行的
transport_completed是否变为true。结果:actions-repeat-evidenceshells-size-readiness.jsonl原因:
ui-shells场景属于shell套件,跑在regression作业里;actions-repeat只跑 actions/selection 系列。而regression通过时不保留 readiness 文件(该文件只在失败产物里)。因此可以断言什么
sizes_ready()只有在transport_output_completed(observed, marker)为真时才会放行;regression (windows-2025)全绿,说明ui-shells走完了 stage 5 之后的流程;stage=5,这一形态的成因与修法已被单变量对照证实。但本项仍不满足关闭条件
本项正文明确写着:
即:本次修的是 stage 5 的观察窗口(成因已字节级确认),而本项要的是原 hosted stage 6 事件的因果证据。两者不能互相替换。
因此保持开放,并记录本次净收益
Merge pull request #293 from JavaZeroo/docs/evidence-wsl
JavaZeroo commentedon Nov 1, 2026
本批(diagnose/shell-stage6-hosted):hosted 未复现,原事件保持未知
当前形态确认(实测,main HEAD c3e825e)
experiments/shell/workspace_shells_scenario.hpp:46-95的 check_size/sizes_ready 与 stage5 释放门(wsl 记录size-helper-held→sizes-ready);experiments/shell/size_client.cpp:4-22的--wait-event事件与 15s 等待;experiments/shell/transport_completion.hpp:19-97的transport_output_completed(须观察同次尺寸输出之后的独立新提示符)。experiments/shell/local_shell_diagnostics.hpp:34-47(shells-size-readiness.jsonl:settled/marker_present/transport_completed/observed_output_tail_bytes)与:51-125(shells-transport-probe.jsonl:output_seen/prompt_seen/malformed/last_line/window_hex),仅在 30s 超时路径写出,成功路径不产生这两份。本机有界多次(实测,上限 7 次)
local/r80-shells-local-report.json;逐轮shells-progress.jsonl显示 wsl/pwsh/powershell/cmd 顺次 stage6/7/8/9 exit 0,fence 轮含size-helper-held→sizes-ready顺序。首轮 default Windows hosted CI(实测)
diagnose/shell-stage6-hosted(无新提交,等于 origin/main c3e825e)触发 build.yml。Build 41295616231:windows-2025 regression 成功,65/69 Test #65: shell ... Passed 66.61 sec,100% tests passed out of 69,Total 271.01 sec。shells-0/shells-1两轮shells.json均normal_exit=true、main_sessions:2/bottom_sessions:2,四 shell 顺次 stage6/7/8/9 exit 0;shells-held-size-helper轮含size-helper-held→sizes-ready→顺次退出。三个场景均未写出shells-size-readiness.jsonl/shells-transport-probe.jsonl(印证成功路径)。结论
下一步
shells-size-readiness/shells-transport-probe,才能在三假设(UI/队列未发送、Windows 子进程→WSL 输入丢失、WSL 已收 exit 但生命周期未回收)间取舍;本批当前 main 已绿,不重复取绿。JavaZeroo commentedon Nov 1, 2026
修前 hosted 批次(diagnose/shell-stage6-prefix)未复现
结论:原 hosted stage6/30s 事件本轮未复现,保留未知,不循环重跑;三假设无新证,继续开放。
实测
推断
未知
artifact:r1-windows-input,id 13091369066,4305855 B,SHA256 ef93a2b8924bcfda2c6ad1381cb317be576eaab0707603322b77ea4ca9970192。下载一次,shell 两轮证据与全量保留于 tf-r80b local/r80-prefix-batch。