Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions docs/research/clipboard-stage-observation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Hosted 剪贴板超时的有界阶段观测

[#99](https://github.com/JavaZeroo/termforge/issues/99) 的原 `ui-clipboard-system` 在 occupied 错误反馈后触发 launcher 45 秒期限。原件无法区分后续等待边界。本调查加入临时阶段记录,完成预先固定的一个批次:**两轮均通过,原超时未复现,原因仍未知**。完整 CI 的其他失败分别保留,可靠性缺口没有关闭。

## 方法与身份

观测源码 [`b9789543a792b0a0b96139377ea43f4dfab46626`](https://github.com/JavaZeroo/termforge/commit/b9789543a792b0a0b96139377ea43f4dfab46626),tree `bb8d6ce8464ec8b50ff86000dfb1f0b39b3b9888`,基于 #98 的 `678804ff5201fab4296b133af9457b7120739b68`。只在诊断分支首轮 push/default Windows hosted VM 启用;PR 与 external candidate 检查关闭记录。

原 `ShellTests.test_system_clipboard_product_read_errors_cancel_and_close` 的两轮、四 case、256 B 基线、精确重试字节、45/60 秒期限及完整回归上下文未改。本机仅构建和验证非 hosted 拒绝守卫,没有调用真实系统剪贴板。

记录白名单为 case/stage、callback 计数、单调时长、固定动作前后事件、paste busy、helper 零等待状态及 owner 固定步骤/错误数字。稳定阶段最多每秒一条,总量最多 256 条;不含剪贴板或终端文字、PID/HWND、路径或凭据。owner 多个原子字段不是一致快照;事件只表示调用边界,文件 I/O 可能影响时序。

观测结束后,临时 C++ 记录与 CI 启用步骤全部撤回,三个文件恢复到上述父提交;固定观测提交保留原代码供审查。当前代码不会自动继续这个诊断批次,没有因本调查改变产品行为。

## 实际结果

[push/default run 40459936505,Windows job 122041868650](https://github.com/JavaZeroo/termforge/actions/runs/40459936505/job/122041868650) 使用默认核心与系统 ConPTY。[白名单摘要](../../experiments/shell/results/2026-10-27-clipboard-stages/validation.json)记录来源、构建清单和原件哈希;[trace 0](../../experiments/shell/results/2026-10-27-clipboard-stages/trace-0.jsonl)及[trace 1](../../experiments/shell/results/2026-10-27-clipboard-stages/trace-1.jsonl)经字段检查后保留原字节。

| 检查 | 第一轮 | 第二轮 |
|---|---|---|
| occupied / oversize / cancel / close 接收字节 | 270 / 270 / 268 / 256 | 270 / 270 / 268 / 256 |
| 记录条数 / callback 次数 | 72 / 45 | 72 / 45 |
| complete-before-close 记录 | 1614 ms | 1527 ms |
| launcher 退出 / outer 超时 / stderr | 0 / false / 空 | 0 / false / 空 |
| Job active / total / terminated | 0 / 27 / 0 | 0 / 27 / 0 |
| desktop 回收 / 记录截断 | true / false | true / false |

原 `validate_clipboard_workflow` 与结果 validator 离线重算通过,包含四 case 的独立字节预期、owner 释放/退出、helper 回收及错误反馈。cancel/close 的晚发布按既有合同观察到 1418、requester 已退出,没有改记为成功发布。另核对 trace 字段集合/类型、记录序号、时间和 callback 单调性、各 case 阶段/动作顺序及条数上限。1614/1527 ms 是带诊断的关闭前记录,不是自然退出、性能或呈现端点。

[artifact 12714865514](https://github.com/JavaZeroo/termforge/actions/runs/40459936505/artifacts/12714865514) 为 4269771 B,ZIP SHA-256 `4b597e169d36624c87a6a9859e0fc3b2a37846569bca3eaca4c51322ec7d2791`,与 GitHub digest 一致。完整 ZIP、原文件和离线审计保留在 ignored `local/r99`;首次下载的 1572864 B 不完整文件保留并排除。CI 清单记录该次 clean build 的 shell、launcher、clipboard reader、input client 四个 EXE 哈希及 checkout;EXE 本体未归档,没有声称在本地重新哈希。含进程身份的原 workflow/sample 不直接公开。

## 完整 CI 与独立失败

| 检查 | Windows | Linux | 状态 |
|---|---|---|---|
| push/default,40459936505 | 50/52,280.05 s | 32/33,12.67 s | 整体失败,Windows 启用诊断 |
| PR/default,40459942201 | 51/52,276.72 s | 32/33,12.95 s | 整体失败,诊断关闭 |
| push/external candidate,40459936582 | success | success | 独立候选配置 |
| PR/external candidate,40459942259 | success | success | 独立候选配置 |

PR 实际 checkout 为 `b58c029fc0f861c2e7d251d125b18ec70e80dda9`。四个 default job 均因本次新增清单路径触发既有 workflow 路径计数断言 `2 != 1`。本地单独复现该断言;撤回临时工作流后,原 ActionOracleTest 7/7 通过(0.487 s)。这是诊断配置回归的修正,不是 #99 超时修复;后续 CI 不回填这一批为通过。

push Windows 另有 `test_mouse_selection_to_real_system_clipboard` 的 `ui-copy-system` 第二轮 `OpenClipboard: 5`。第一轮原 validator 离线通过;第二轮已有 12 条基础记录、22 条交互记录,最后为实际 Copy popup 成功读回。之后、构造自有占用 owner 之前有三个夹具剪贴板调用,具体哪个失败及原因未知。此入口补入 [#85](https://github.com/JavaZeroo/termforge/issues/85),与旧入口及 #99 分列,不由同一 API 错误推断同因。

本批已按预定停止条件结束,没有追加重试或改变超时、字节门槛。#99 继续开放;本报告不声称原因修复、完整产品验收或 WindTerm 等价。后续执行状态由 issue 维护。
44 changes: 44 additions & 0 deletions docs/research/conpty-source-margin-controls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 源码 ConPTY:主屏与重复切屏的原生对照

同源 margin 补丁在三个补充场景中符合预先固定的结果:主屏单独滚动保持正确;新建或再次进入备用屏使用默认全屏滚动区域;返回主屏和重复离开备用屏后恢复原来的 `2;3r`。未修补版在后两个场景出现具体预期错误,修补版通过全部原生阶段。实际运输的最终主屏在两版中均正确,不能用末端正确掩盖原生错误。

这是 [#56](https://github.com/JavaZeroo/termforge/issues/56) 的独立补充实验。预期依据是既有 R2 每缓冲区 margin 合同和固定上游状态路径,运行前已记录在 issue;WindTerm 2.7.0 对这些场景的实际行为仍未知。本结果不验收 WindTerm 等价、不选择产品后端,也不关闭 #56/#41。

## 固定输入与观测边界

沿用[原 175B 对照](conpty-source-margin-runtime.md)的同源 baseline/patched:Terminal `dc8ae365847d41f62d1ebca93815bb00959bc12f`、构建 run `40449292015` 和已审核的双文件 SHA、variant/summary/patch receipt。本次未修改上游补丁或重新构建上游。

三个场景各在 `80×24`、`12×7` 下运行 baseline/patched 一次,共 12 次,只开 VT;无自动重试。输入由独立 controls 探针发送,原 175B、四阶段 probe/oracle 和既有期限不变。新场景使用 `CTRL_DONE`,字节数与原负载分列。

| 场景 | 80×24 / 12×7 字节数 | 运行前固定的原生预期 | 未修补版实际结果 | 修补版实际结果 |
|---|---:|---|---|---|
| `main-only` | 99 / 99 | 无备用屏;主屏 `2;3r` 滚动,区域外不变 | before/final 均正确 | before/final 均正确 |
| `default-alt` | 150 / 149 | 主屏区域不传给新备用屏;物理底部换行应全屏滚动;返回后仍为主屏区域 | alt 未全屏滚动:保留 `ALT_TOP`,`ALT_LAST` 被覆盖;其余阶段正确 | before/alt/restored/final 全部正确 |
| `repeat-alt` | 221 / 220 | alt1 的 `4;5r` 不传给再次创建的 alt2;两次离开后主屏仍为 `2;3r` | alt2 同样未全屏滚动;final 出现 `REGION_CIXED`;其余阶段正确 | before/alt1/alt2/restored/final 全部正确 |

每个阶段分别检查 `ReadConsoleOutputCharacterW` 文本、完整 `CHAR_INFO` 字符/属性、光标及 viewport top。预期为字面值,不使用候选 parser 生成;baseline 必须符合上述具体旧状态,异常、生命周期失败或其他文字错误均不计为有效反例。没有设置 SGR,属性检查只证明初始属性保持。

12 次都自然退出 37、读端 EOF 109,creation flags=0,内层子进程清零,外层 Job 为 active0/total4/terminated0,无强制取消。每次仍为 5 秒 child wait、15 秒外期限、共享 5 秒 cleanup;离线候选回放另由既有 trace 入口管理。两版实际运输的最终文字和 alternate=false 均符合预期;没有观测末端逐阶段光标、属性或实际呈现。

## 源码、构建与验证身份

- 本地实际运行源码 `edec26bb3c4d04858a667a96debf69c139476172`,工作树干净;参与文件 SHA、探针、trace、输入、运输、每阶段捕获及监督记录 SHA 见[脱敏清单](../../experiments/conpty/results/2026-10-27-source-margin-controls/validation.json)。
- Windows 11 x64 build 26200;VS17 / MSVC 19.42.34433 / SDK 26100,Release x64。controls 探针 SHA `a71c94795806a40062ace7788ee69cfbac0cd8a274765dce6b28aa6d7f33c7ee`;`.5` trace SHA `5941d4569d0ae146eb005f12ecfb15014bc06c18ee48d1c9460824ab65df93d3`。
- 新旧 margin 判据与 GO/回收回归 17/17,通过耗时 0.375 秒;原 loader/API/清理回归 14/14、零跳过,1.020 秒。后者复用前一批相同源码的原探针 EXE,运行本次修改后的 Python supervisor;不冒充重新编译原探针。两个实际 stdout 日志均保存在本地并记录 SHA,时长仅为测试诊断。
- `TERMFORGE_BUILD_SOURCE_CONPTY_EXPERIMENT` 仍默认 OFF;新增 `conpty_source_margin_controls` 独立目标。仅 supervisor 增加可选参数和期限,既有 API 调用默认仍为 20 秒。纯 controls 判据纳入 Windows/Linux CTest,不依赖 native DLL;原生矩阵需显式运行。

私有原件位于 `local/r56-margin-controls/matrix-1`;公开清单仅含合成场景结果、必要身份和文件哈希,不包含绝对路径、原生二进制、原始运输或用户状态。

## 复验与剩余范围

先按[源码构建说明](../../experiments/conpty/upstream/README.md)取得并审核固定 run 的 baseline/patched。使用全新的输出目录:

```powershell
cmake -S . -B local/source-controls-build -A x64 -DTERMFORGE_BUILD_SOURCE_CONPTY_EXPERIMENT=ON -DTERMFORGE_BUILD_CANDIDATE_ADAPTER=OFF -DTERMFORGE_CONPTY_BACKEND_DIR= -DBUILD_TESTING=OFF
cmake --build local/source-controls-build --config Release --target conpty_source_margin_controls --parallel 2
cargo +1.92.0 build --manifest-path experiments/candidates/alacritty/Cargo.toml --locked --release --bin termforge-alacritty-trace
python -m experiments.conpty.source_margin_controls --baseline local/source-baseline --patched local/source-patched --probe local/source-controls-build/bin/Release/conpty_source_margin_controls.exe --candidate-trace experiments/candidates/alacritty/target/release/termforge-alacritty-trace.exe --output local/source-controls-new
python -m unittest experiments.conpty.test_margin_controls -v
```

本次只补无备用屏、默认备用屏区域、重复 h/l 的真实交叉。显式样式与非零光标的后续[独立对照](conpty-source-margin-styles.md)记录原生通过及末端空白前景色差异,不回写本批结果。历史隔离/压力、resize、查询/API 写入、完整产品工作流、性能及维护升级仍未验证;原 175B 的 VT-off 证据属于前一批,不能合并成同批更大矩阵。原系统/官方失败、#52、#97 和 #99 的独立失败继续保留。正式方案仍由 #34 提交证据及取舍,经用户确认后生效。
Loading