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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ if(BUILD_TESTING)
termforge_add_python_test(copy_error_frame -m unittest experiments.shell.test_copy_error_frame -v)
if(WIN32)
termforge_add_python_test(research_guards -m unittest discover -s research/tests -v)
termforge_add_python_test(windterm_cmd_contract -m unittest benchmarks.tools.test_windterm_cmd -v)
termforge_add_python_test(receive -m unittest experiments.receive.test_receive -v)
termforge_add_python_test(conpty -m unittest experiments.conpty.test_conpty -v)
termforge_add_python_test(conpty_ctrl_c -m unittest experiments.conpty.test_ctrl_c -v)
Expand Down
1 change: 1 addition & 0 deletions benchmarks/tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,6 @@ JSONL 有 metadata、sample、schedule_gap、end 类型。采样包含 root、de
- 已实现:确定性数据、逻辑文本 oracle、字节播放器、Windows 进程树资源 JSONL、合成负载校准。
- 已实现视觉诊断:[自建窗口捕获、序列标记匹配、F13 注入、时钟往返校准](VISUAL.md),另有实验性的固定像素模板录制/等待工具。
- 已实现资源汇总与语义校验:观察到的分组 CPU、同时采样内存峰值、缺失与调度质量、来源哈希。
- 已实现限定的[原版本地 cmd 自动正确性诊断](WINDTERM-CMD.md):独立非输入桌面/Job、合成 profile、14 行全文 oracle 和生产事件绑定;[固定脱敏结果](results/2026-10-28-windterm-cmd/README.md)不包含真实呈现或性能结论。
- 待完成:WindTerm 实际文本标记/输入驱动验证、T01 捕获/采样开销校准、完整运行记录 JSON Schema、节流/交互驱动。
- 剩余任务统一见[路线图](../../docs/PLAN.md);任何工具校准均不代表 WindTerm 基线或性能达标。
30 changes: 30 additions & 0 deletions benchmarks/tools/WINDTERM-CMD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 原版本地 cmd 自动正确性诊断

本工具对应 #119,是 #3 的一个有界切片。它启动固定官方 2.7.0 的独立副本、全新合成 profile 和本地 cmd;cmd 运行一个 14 行 ASCII producer。它不操作用户输入桌面、剪贴板或显示设置,不连接远程服务。

```powershell
# 使用已有 REA 6.7.0 公共 CLI,不安装/更新 provider。
D:/Code/termforge/.venv/Scripts/python.exe -B -X utf8 benchmarks/tools/windterm_cmd.py run `
--source D:/Code/termforge/local/windterm-official/WindTerm_2.7.0 `
--rea D:/Code/termforge/research/ui/r1-tools/node_modules/.bin/rea.cmd `
--out local/windterm-cmd/new-run --seconds 30
```

输出目录必须不存在且位于当前仓库 `local/` 下。复用 `research/ui/launch.py` 的发行物内容清单、禁首启导入的合成配置、home 环境隔离和 Owned Job;挂起创建后先加入 Job,再执行。独立非输入桌面不会切换到前台。所有外部 CLI 及目标子进程同样有界回收。隔离配置与桌面不是文件系统或网络沙箱。

producer 通过 `cmd /c` 启动,C argv 的 `list2cmdline` 不能视为 cmd 引用器。因此在读取/复制发行物或创建输出前,显式拒绝 out、Python 解释器和 runner 路径(传入及解析后的拼写)中的 `& | < > ^ ( ) % ! "` 与控制字符。具有这些字符的正常文件路径也不支持。`--seconds 30` 是 Frida 观察时长,公共 CLI 另有45秒等待上限;准备、两秒启动等待及有界清理另外计入整个生命周期。

producer 在计时事件外清屏,从本地 cmd 控制台写入合成数据,记录 run_id、payload SHA、原始生产事件及控制台窗口/缓冲尺寸,然后保持存活供文本读取。结束/退出不代表消费或呈现完成。

producer 记录通过 run_id 和负载身份关联;probe 与 cleanup 通过原版 target PID 关联。不据此声称已经核验 producer 的父子进程链。

独立探针通过已调查的固定 Qt5 API 打开唯一合成会话,并在其 GUI 线程读取 `activeText.visibleLineCount` 和每一条 `lineText(i)`;最多 128 行。仅末尾 marker 用于决定何时获取完整文本,Python 校验器对照独立生成的所有 14 条逻辑行逐行比较,剩余行只能为空。不会 trim 空格、忽略前缀、只比 marker 或从配置文件值推定当前实际设置。未知 API、缺失行、超时、错误、截断或身份不符均不能通过。

`diagnostic.json` 是供审查的白名单摘要,原始 `run.json`、producer、REA evidence、复制发行物和 profile 全部留在忽略目录,不提交。`actual_settings` 只记录实际可读的控制台尺寸、文档容量、控件几何和 QWidget 字体;该字体不代表全部 QPainter/glyph fallback,其他 C0 配置仍未知。用同一执行源码可离线重算:

```powershell
python benchmarks/tools/windterm_cmd.py summarize --out local/windterm-cmd/new-run
python -m unittest benchmarks.tools.test_windterm_cmd -v
```

**这是 instrumented correctness diagnostic。** 它没有原生输入或画面捕获,`consumer_done`、`presented_done` 固定为 null,`performance_gate=not_evaluated`。生产计数器仅原始本地事件,不发布吞吐/时延。它没有执行正式 T01、观测开销校准、历史/Unicode或完整 WindTerm 基线,也不续跑旧手工 5/12 批次。
34 changes: 34 additions & 0 deletions benchmarks/tools/results/2026-10-28-windterm-cmd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 原版 WindTerm 本地 cmd:有界自动正确性诊断

#119 的首个自动切片,基于 main `2903290`。工具及其运行边界见 [WINDTERM-CMD.md](../../WINDTERM-CMD.md)。本页只记录固定结果;#3/#4 的实际呈现、低扰动校准和正式基线仍未完成。

首次提交的最终执行源码 `windterm_cmd.py` SHA-256 为 `bd4a67f5df26c32a13c5d9f0296bf2347719a3b9024d0607afe81f4655e00f61`;后续路径守卫修订及其独立运行见下文。在 Windows 11 上使用既有 REA 6.7.0 公共 CLI,启动固定官方 2.7.0 EXE 和经完整内容清单校验的发行物副本。没有改动发行物、用户配置、输入桌面、剪贴板或显示设置。

| 检查点 | 最终实际结果 |
|---|---|
| 合成数据 | 新 run_id 的 14 行 ASCII,536 B,字节 SHA 与独立 manifest 一致 |
| 本地链路 | 原版合成 Shell 会话 → 本地 cmd → Python producer;本地控制台 VT 启用成功 |
| 文本正确性 | `visibleLineCount=15`,逐条 `lineText(i)` 恰为全部 14 条独立预期及 1 条空白尾行;不是只检查 marker |
| 配置可读项 | producer 控制台窗口80×24、缓冲80×3000;JS `screenLineCapacity=23`;控件矩形 `[0,0,905,428]`、QWidget 字体 Roboto Mono 9pt / pixel_size -1 |
| 身份与回收 | producer 按 run_id/负载身份关联;probe 与 cleanup 按原版 target PID 关联;自有 Job active=0;profile 仍只有一个合成会话。未核验 producer 的父子进程身份 |
| 未观测端点 | consumer_done=null;presented_done=null;performance_gate=not_evaluated |

控制台尺寸、JS 文档容量与 QWidget 几何属于各自读取点,原样分列;没有将它们解释为同一网格、完整 C0 验证或真实像素呈现。控件字体也不证明 QPainter、实际 glyph fallback 或字体文件身份。

首次工具源码曾完成同样的小负载诊断,其原件与执行源码保存在 `local/windterm-cmd/initial-20261028`,没有覆盖。随后离线审查修正异步 TerminateProcess 的等待,以及 cleanup 身份和摘要白名单/原始记录哈希绑定;只在新源码、新 run_id 和新目录 `local/windterm-cmd/final-20261028` 执行了一次已预声明的最终验证。两次均为独立正确性诊断,没有合并成性能样本或重跑旧手工批次。

新工具10项边界测试及既有隔离准备3项通过,独立 JS 语法检查通过。测试覆盖 marker-only、缺失中间/首行、多余内容、空格改变、错误运行/源码/PID、截断、probe错误、重复快照、缺失 producer、配置白名单、异常终止仍回收以及非零 Job/profile 变化拒绝。独立离线脚本重新生成 oracle、核对 payload/生产事件/完整15行/身份/六份原始记录哈希和清理等式,全部通过;没有再次启动目标。

[validation.json](validation.json) 仅公开人工审查过的白名单摘要、设置和来源哈希,不含 PID、宿主路径、原始生产计数器、画面、复制发行物或 profile。原始 REA evidence 和本地数据均保留在忽略目录。

## cmd 路径守卫修订

Standards 审查指出 `list2cmdline` 只处理 C argv 引用,原守卫遗漏的无空格 `&` 路径会进入 `cmd /c` 语法。修复前先增加不启动原版的反例:`& | < > ^ ( )` 各在 out、runner 和 Python 解释器路径上的21个子例到达了发行物准备,公共 CLI 的 `out&echo.TF_CMD_REVIEW_MARKER` 也未被提前拒绝,两项测试失败。测试只使用 mock 或 Python 公共 CLI 的缺失发行物入口,没有启动 cmd/原版试注入。

修订在任何发行物读取/复制或输出目录创建前,检查三个路径的传入及解析后拼写,拒绝上述字符以及原来的 `% ! "` 和控制字符。修复后12项工具边界测试与3项既有隔离准备测试全部通过;独立 JS 语法检查通过。README 中的身份描述也已精确区分:producer 用 run_id/负载,probe/cleanup 用原版 target PID,不声称已有 producer 父子进程核验。

预声明的 `local/windterm-cmd/final-path-guard-20261028` 仅执行一次正常14行验证,run_id 与前两轮不同。运行源码 SHA-256 为 `e517f8cab36d55e5d4bdda3fc14d4641e5ce6256991af04762dbf43c25961297`;30秒为 Frida 观察时长,CLI等待上限45秒,准备、启动和清理另外计入生命周期。536 B 全文逐行匹配并有1空白尾行,producer complete;可读配置与上表一致,自有 Job active=0、合成 profile 一项,未知端点及所有性能限制不变。

[path-guard-validation.json](path-guard-validation.json) 保留此新源码的独立白名单和六份原件哈希。离线独立审计重新核对全部文本、身份与清理;前 `final-20261028` 六份原件哈希仍与原公开摘要完全一致,其执行源码副本另行保留。新 summarizer 仍拒绝旧 runner source,未放宽绑定;没有改写前两次数据或把三次独立诊断合并为性能样本。

这是有插桩的小 ASCII 文本读取链路,尚不覆盖滚动历史、Unicode、ANSI样式、输入响应、真实呈现、观测扰动或正式 T01。没有计算吞吐/时延、提出数值容差或声明原版性能等价。
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"schema": "termforge.windterm-cmd-diagnostic.v1",
"run_id": "2cb6f43c4e384983a1c1ef8104e6ca64",
"kind": "correctness-diagnostic",
"target_sha256": "7b10531dccc7cd614ae559f36f1ef518e0c96335637431b4646354823b2804d0",
"distribution_sha256": "e459adf2f12adb6a1b7f55e66a9da1c22794185e66e848057d21e0c60d669203",
"runner_sha256": "e517f8cab36d55e5d4bdda3fc14d4641e5ce6256991af04762dbf43c25961297",
"probe_sha256": "648b00e683f9544fc305aef1186084ad5fb57934e78b1dce46b5a819deccab3f",
"payload_sha256": "61c6afe24b3642e6491e2382f30c5a5993819d7b23d702dbc59e2b25daa71bf9",
"payload_bytes": 536,
"producer_status": "complete",
"correctness": {
"status": "passed",
"method": "all-bounded-logical-lines-exact",
"payload_lines": 14,
"observed_lines": 15,
"terminal_text_sha256": "5ff220f3626d945002a7b2cd2d4468e91c3132e1509e700ccdb2f9e2d0cfeb80"
},
"actual_settings": {
"producer_console": {
"vt_enable_succeeded": true,
"original_mode": 3,
"columns": 80,
"rows": 24,
"buffer_columns": 80,
"buffer_rows": 3000
},
"terminal": {
"screen_line_capacity": 23,
"widget_geometry": [
0,
0,
905,
428
],
"widget_font": {
"family": "Roboto Mono",
"point_size": 9,
"pixel_size": -1
}
}
},
"consumer_done": null,
"presented_done": null,
"performance_gate": "not_evaluated",
"cleanup": {
"owned_active": 0,
"only_synthetic_session": true
},
"limitations": [
"Instrumented local cmd diagnostic on a non-input desktop; no native input or presentation timing.",
"Small ASCII payload only; no T01 baseline, retained-history, Unicode or performance acceptance.",
"Widget font and console dimensions are readable settings, not complete C0 verification."
],
"raw_records_sha256": {
"run.json": "b4c74552b0bf150ab4dcca6e22f5a08060fb8ee51a108547849d32154d3db353",
"workload.json": "eb488ec88b339aac6f3ff75ebcbb40220d8cf88888fd0275fa8aa9a23f6308ad",
"producer.json": "0ad5292ce921653c9730dcdfbd625098d32626e0964485d19b169c3ae0143645",
"evidence.json": "03bb9a6910ba856dd93a6418c5b42941594f2b195468bfe9aa0afda607cad5c2",
"cleanup.json": "cc83e085935e3cc581b8e39c693b536718d30840e2fe56b6121d7e57a76d2bf4",
"profile-check.json": "5e522a64e98197722ccd084639b1ce50258b238e03be2f016e81c8af023b5ee1"
},
"source_base": "0582a02bbfd332d03761b1831445754eebd77549",
"issue": 119,
"validation": {
"public_boundary_tests": 12,
"existing_isolation_preparation_tests": 3,
"js_syntax_check": "passed",
"independent_offline_audit": "passed",
"raw_record_hashes_checked": 6,
"target_launches_for_final_source": 1,
"prior_six_record_hashes_unchanged": true,
"prior_source_rejected_by_current_summarizer": true
},
"path_guard_red_green": {
"guarded_paths": [
"out",
"runner",
"sys.executable"
],
"explicit_metacharacters": "&|<>^()%!\"",
"also_rejects_control_characters": true,
"before_fix_boundary_failures": 21,
"before_fix_public_cli_failures": 1,
"injection_target_launches": 0
}
}
73 changes: 73 additions & 0 deletions benchmarks/tools/results/2026-10-28-windterm-cmd/validation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"schema": "termforge.windterm-cmd-diagnostic.v1",
"run_id": "dc5fe5779e3e4e2985505af394365865",
"kind": "correctness-diagnostic",
"target_sha256": "7b10531dccc7cd614ae559f36f1ef518e0c96335637431b4646354823b2804d0",
"distribution_sha256": "e459adf2f12adb6a1b7f55e66a9da1c22794185e66e848057d21e0c60d669203",
"runner_sha256": "bd4a67f5df26c32a13c5d9f0296bf2347719a3b9024d0607afe81f4655e00f61",
"probe_sha256": "421cf8e238fa7362f3f557ac772127f79796753918a9b025afb6e0c09da4c296",
"payload_sha256": "c3c5ee519e60e2bff5c1498e1aaef599d5cff7dfe54c40a66ba01b4d23b2bb23",
"payload_bytes": 536,
"producer_status": "complete",
"correctness": {
"status": "passed",
"method": "all-bounded-logical-lines-exact",
"payload_lines": 14,
"observed_lines": 15,
"terminal_text_sha256": "44b8badd8084200fb0895b4d65aa7fce8c3430a690d86f5289c02e40700e203a"
},
"actual_settings": {
"producer_console": {
"vt_enable_succeeded": true,
"original_mode": 3,
"columns": 80,
"rows": 24,
"buffer_columns": 80,
"buffer_rows": 3000
},
"terminal": {
"screen_line_capacity": 23,
"widget_geometry": [
0,
0,
905,
428
],
"widget_font": {
"family": "Roboto Mono",
"point_size": 9,
"pixel_size": -1
}
}
},
"consumer_done": null,
"presented_done": null,
"performance_gate": "not_evaluated",
"cleanup": {
"owned_active": 0,
"only_synthetic_session": true
},
"limitations": [
"Instrumented local cmd diagnostic on a non-input desktop; no native input or presentation timing.",
"Small ASCII payload only; no T01 baseline, retained-history, Unicode or performance acceptance.",
"Widget font and console dimensions are readable settings, not complete C0 verification."
],
"raw_records_sha256": {
"run.json": "850d7077f6066e93d8ca9b352b892fc7354460d84c6082e96b7abd16fc1eaabb",
"workload.json": "7df03dc2324d20b5a2dd3948aab01cd464cd0e0b9b6e59187434eb808473b506",
"producer.json": "7fc89ad3561407c066eb7a4c15d1ae269a55844024fb7a0d82d11eb397dac262",
"evidence.json": "ab3bfd1bdeb87ca904a172b222e63fd3944283322240f622f8d15469d0fa9a73",
"cleanup.json": "c5c5c0699ff0e15119b92a6c0ff931a07a419443daca740da4035ed0961725a6",
"profile-check.json": "5e522a64e98197722ccd084639b1ce50258b238e03be2f016e81c8af023b5ee1"
},
"source_base": "2903290",
"issue": 119,
"validation": {
"public_boundary_tests": 10,
"existing_isolation_preparation_tests": 3,
"js_syntax_check": "passed",
"independent_offline_audit": "passed",
"raw_record_hashes_checked": 6,
"target_launches_for_final_source": 1
}
}
Loading