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 @@ -306,6 +306,7 @@ if(BUILD_TESTING)
termforge_add_python_test(windterm_alternate_style_reference -m unittest research.ui.test_export_alternate_style_reference research.ui.test_alternate_style_peer -v)
termforge_add_python_test(windterm_raster_style_reference -m unittest research.ui.test_raster_style_reference -v)
termforge_add_python_test(windterm_raster_selection_proposal -m unittest research.ui.test_raster_selection_reference -v)
termforge_add_python_test(windterm_raster_raw_proposal -m unittest research.ui.test_raster_raw_reference -v)
termforge_add_python_test(differential -m unittest discover -s experiments/differential -p test_*.py -v)
termforge_add_python_test(ime_inventory -m unittest research.ime.test_hosted_inventory research.ime.test_prepare_hosted research.ime.test_product_ime -v)
termforge_add_python_test(text_actions -m unittest experiments.shell.test_actions -v)
Expand Down
1 change: 1 addition & 0 deletions docs/EVIDENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ python -m unittest experiments.shell.test_workflow_sessions -v
| 工作区结构/几何 | [首轮 UI 报告](research/windterm-ui-2026-10-23.md)、[主标签/字体报告](research/windterm-ui-typography-2026-10-23.md)、[探针与准备守卫](../research/ui/README.md) | 发行资源、定向二进制和隔离运行时交叉核对;默认缩放两次及 Qt 1.5 倍一次。旧首启自动导入和错误状态样本已明确排除,不能混作最终纯合成证据 |
| 可公开的 UI 精简结果 | [默认样本 1](research/ui-typography/normal-01.json)、[默认样本 2](research/ui-typography/normal-02.json)、[Qt 1.5 倍样本](research/ui-typography/scale-150.json) | 白名单矩形、字体、DPI 和身份;不是完整像素、逐字形 fallback、真实跨屏或性能证明 |
| 基础文字交互参考合同 | [行为合同](research/windterm-r1-text-contract.md)、[hosted 事实摘要](research/r1-text/hosted-39960732305.json)、[Actions 39960732305](https://github.com/JavaZeroo/termforge/actions/runs/39960732305) | `c386494` 的 text/menu-wrap 各两轮及 repeat 门槛通过:历史/选择/查找、键盘及实际 Select All/Find/Copy/Paste 菜单、精确 CF 软折行/CRLF/尾空白与严格粘贴基线均有证据;四轮 Job 清空。满足 #11 限定参考合同,不代表产品功能等价或性能验收 |
| 五阶段 raw H/space 输出参考(#129) | [固定采集合同](research/windterm-raster-raw-capture-plan.md)、[执行与独立审计](research/windterm-raster-raw-reference-2026-10-29.md)、[脱敏结果](../research/ui/results/2026-10-29-raster-raw-reference/validation.json) | `f6d9a97` 的唯一授权执行取得 5 grab、17 组完整 H/space;phase2 双 H 的 16/16 墨迹并列保留 null,未中断采集。phase1/3 原样 H 唯一匹配同帧 SGR0,phase4 匹配同帧 SGR31;44 的完整有序签名;仅为固定样本输出,不证明内部 pen、完整 grid、presented、local-shell 或性能。旧 #126 0 grab 和旧 #129 3 grab partial 均独立保留,父项未关闭。 |

主对照为官方 Windows x64 2.7.0:ZIP SHA-256 `b05c3c7371340ff1302967247ffcd3a3ba27b237f72010e9157086143c453e50`,EXE SHA-256 `7b10531dccc7cd614ae559f36f1ef518e0c96335637431b4646354823b2804d0`。最初本机安装的 EXE 身份不同;其历史静态报告不得冒充官方包结果。其他目标平台仍需各自固定包身份。

Expand Down
53 changes: 53 additions & 0 deletions docs/research/windterm-raster-raw-capture-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# #129 raw-capture-v1:采集与分析分离

本方案完成复核后,另建授权计划并执行一次新原版,已取得[五阶段完整 raw ROI 与离线签名证据](windterm-raster-raw-reference-2026-10-29.md)。原 `execution_authorized=false` proposal 保持不可运行且未修改。旧 [#126 的 0 grab 停止](windterm-1049-raster-reference-2026-10-28.md)和 [#129 的 3 grab partial](windterm-raster-selection-reference-2026-10-29.md)随 [PR #132](https://github.com/JavaZeroo/termforge/pull/132) 独立保留,均未改写,也没有关闭 parent 颜色调查。

新 case 为 `raw-capture-v1`,独立工作树及分支 `research/windterm-raster-raw-capture`,固定生产源 `f6d9a97e2b2685b6ce39c83dc7107cb52aec7a6a`。[不可运行计划](../../research/ui/results/2026-10-29-raster-raw-proposal/plan.json)列出七个生产源 SHA、分析源 SHA、四个完整模块 SHA、五段输入的 hex/长度/SHA 与单次预算。最终复核及明确运行指令后,必须另建新授权计划和唯一目录,不能把此 false proposal 改为 true 或复用旧批目录。

## 本次改变的合同

[GUI 采集器](../../research/ui/raster_raw_reference.js)在一次 grab 得到的同一 QImage 内,先读完本阶段每个已绑定 H 与其前置 space 的完整 ROI 数组。它不计算主要墨迹、不比较颜色、不以双 H 颜色是否相等作为推进条件。只有结构验证和原生对象回收完成后,`capture_valid=true` 并写 `captured` 确认,允许 peer 发送下一阶段。

| 情况 | 采集推进 | 离线处理 |
|---|---|---|
| 主要墨迹频数并列 | 收完全部 ROI 后继续 | dominant 为 null,保留全部并列候选及频数 |
| space 非单色 | 收完全部 ROI 后继续 | 背景及墨迹分类未知,保留完整 histogram/hash |
| H 与背景无差异 | 收完全部 ROI 后继续 | `no-marker-ink`,不据此匹配样式 |
| 双 H 的输出不一致、正控别名或无匹配 | 继续采集后续阶段 | 保留各自签名,多义或无匹配为 null,不推定 reset |
| 身份、端点、标签、caret、ROI/DPR/空图或原生调用失败 | 保存真实 partial 并停止 | 不移动 ROI、不补抓、不重跑 |

`capture_valid` 只指结构采集有效,不表示颜色、样式、active grid、presented 或产品验收通过。结构失败允许保留已取得的部分 ROI,不能把缺失像素补造为完整阶段。

## 不变的五阶段及边界

五段仍为 `43/38/20/53/54` 字节,各另追加 `CSI 6n`,详见新计划及[生产器](../../research/ui/raster_raw_reference.py)。D0=`SGR0`,S1=`SGR31;44`,S2=`SGR32;45`。

| 阶段 | 内容 | 结束前 SGR |
|---|---|---|
| 0 | 一图内 D0 双 H、M0/S1 双 H | S1 |
| 1 | `1049h` 后原样 A0 H,同一行 S1/D0 正控 | D0 |
| 2 | S2 的 A1 双 H | S2 |
| 3 | 重复 `1049h` 后原样 A2 H,同一行 D0/S1/S2 正控 | S2 |
| 4 | `1049l` 后原样 M1 H,同一行 S1/S2/D0 正控 | D0 |

保留每个前导空格和完整 token 匹配,M1 不匹配 M1S1。运行中逐条完整 NAWS 事件守卫、独立 DSR 回复与阶段确认均保留。GUI 主线程主动读取实际 isAltScreen/isMainScreen 和有限非负 P 端点;caret=anchor 才允许采集,selectionText 只记 type/length。实际 caret(零宽仍按至少 1 逻辑像素)不得与任何 H/space 相交。marker 的 ordinal/完整 label/group/sample 必须按固定身份一一对应,不能以重复条目补齐数量。

仍使用固定官方 WindTerm 2.7.0、隔离 WindowStation/Desktop、OwnedJob、单合成 loopback/profile。最多一次原版运行、每阶段一次 grab、总最多五次;REA capture45、CLI wait60,原版更早启动并另等 2 秒,整程上限未知。禁止用户输入桌面、剪贴板、DPI 变更及计时结论。

Qt5 API/ABI 沿用已核实的完整模块 SHA、实际模块路径与固定导出 RVA:QWidget::grab→QPixmap::toImage→QImage::pixel,QRect 为 inclusive 边界;QPixmap/QImage 各分配 32B、不预构造,正常返回后 image→pixmap 普通析构。仍以 QImage::pixel 逐点读 QRgb,不猜 format/stride。原生 bool 的精确 bool 或整数 0/1 表示显式核对并保留原类型。

## 离线分析与公开出口

[分析器](../../research/ui/raster_raw_analysis.py)先独立检查结构、完整 token 位置、ROI 顺序/唯一身份、DPR、样本数量和 uint32 值,再为每个 H/space 保留完整 RGBA histogram、样本数和有序 QRgb 数组 SHA。数组本身留 local。主墨迹并列只生成 null 和候选,不抛出采集失败,也不改变原批结果。

同帧比较要求目标与正控都在同一文档行及逻辑行,并且都观察到墨迹。匹配条件是 H 和 space 各自的**有序数组 SHA、宽高与样本数完全相同**;只靠主要颜色或 histogram 相同不足以匹配。匹配多个控或未匹配时唯一结论为 null。即使匹配唯一,也只称该同帧原样 H/space 的输出签名与显式正控一致,不声称读到了内部 pen、完整 current_style 或 reset。

[公开 CLI](../../research/ui/export_raster_raw_reference.py)使用显式 require/ValueError,只有身份、合成文本、消息、生命周期及结构审计全部完成后才创建输出目录。公开只有合成源、histogram/频数/尺寸标量和 hash;raw 像素、日志、路径、PID、资源及 profile 均留 local。`raw_capture_complete=true` 与颜色分类未知可以同时成立,不转化为五阶段样式对齐通过。

## 离线复现与验证

[既有 phase2 回放](../../research/ui/results/2026-10-29-raster-raw-proposal/replay.json)绑定原 Evidence ID `ev_432abe8baf4fc86efd4994cd12cc3ab5fe0b5120476d22540c5b26e2e3c693a4` 和原 raster-result SHA `3887faaa8d055f42388eafc4b0a9ee2e2b8111d3fa1384e07ec5f0a50585f34d`。新分析器正确保留两个 16 次候选;旧批第二个 H 没有采样、phase3/4 没有发送,这些缺口均未补造。既有 phase1 的完整 raw 签名也唯一匹配同帧 D0。该回放的新原版运行数为 0,不能把旧 partial 变成新完整采集。

[公共测试](../../research/ui/test_raster_raw_reference.py)与[合成 Qt 边界](../../research/ui/test_raster_raw_native.js)按已确认的采集入口/离线 CLI seam 逐项红→绿:旧逻辑遇 tie 只留 1/4 ROI,新逻辑收全 4;tie 分类从异常变为 null/candidates;重复 marker、重复 ROI 和错误完整 label 从可通过变为拒绝。完整合成五阶段即使 phase2 tie 也能导出全部 ROI;同 histogram 但不同排列不匹配,别名及无墨迹保持未知。另覆盖普通/优化解释器的隐私/身份/结构拒绝不得生成公开输出、32B sret 和异常析构边界,以及 false proposal 不得启动或产生 attempt。

离线普通及 `python -O` 各 11 项通过,相关 CTest `windterm_raster_style_reference`、`windterm_raster_selection_proposal`、`windterm_raster_raw_proposal` 在 Debug 配置下 3/3 通过。`core.autocrlf=true` 的 fresh checkout 也核对新 JS 与 Qt 前缀 SHA 一致。后续唯一授权执行及独立离线审计见[结果报告](windterm-raster-raw-reference-2026-10-29.md);该结果只支持固定样本输出事实,不提升为内部样式、完整栅格、presented 或产品验收。
53 changes: 53 additions & 0 deletions docs/research/windterm-raster-raw-reference-2026-10-29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# #129 raw-capture-v1:五阶段原始 ROI 完整采集与离线签名

按[固定方案](windterm-raster-raw-capture-plan.md)完成一次新原版运行:5 个阶段各一次 grab,17 组 H/前置 space、34 个完整 QRgb 数组全部取得。phase2 两个 H 都有 16/16 主要墨迹并列,离线分类保留 `dominant_ink_rgba=null`,采集仍完成 phase3/4。`raw_capture_complete=true` 只表示这批固定 ROI 完整,不表示五阶段样式、内部 pen 或完整终端行为验收通过。

同帧、同文档行及逻辑行的完整有序 H/space 输出签名比较:phase1 首次 `1049h` 后的原样 A0,以及 phase3 重复 `1049h` 后的原样 A2,均唯一匹配该帧显式 `SGR0` 正控;phase4 `1049l` 后的原样 M1 唯一匹配该帧显式 `SGR31;44` 正控。这里的匹配要求 H 和 space 各自有序 QRgb 数组、尺寸和数量完全相同,不依据主要颜色或 histogram 相同推断内部样式、reset 或完整恢复语义。

## 执行与源身份

- 固定生产源为 `f6d9a97e2b2685b6ce39c83dc7107cb52aec7a6a`,执行前准备 HEAD 为 `46f90d89e5b80b96989861f437b4b10e75ccb199`。七个生产源逐字节匹配固定生产提交、false proposal 与新授权计划;本次证据收尾未改生产源或原件。
- 原 `execution_authorized=false` proposal 保持不变。复核明确授权后另建新计划,私有 SHA 为 `8dbeaae26ed19c6d8f3c22a16308fdf3b85f1d02a14aaa7e20af96c76405d288`;启动前新输出目录及 attempt marker 均不存在,唯一 attempt 随后保留,没有第二次原版运行。
- [授权计划的脱敏投影](../../research/ui/results/2026-10-29-raster-raw-reference/plan.json)列出全部五段 `43/38/20/53/54` 字节及 hex/SHA,每段另追加 `CSI 6n`。本批五段均实际发送。
- 固定官方 WindTerm 2.7.0 EXE SHA 为 `7b10531dccc7cd614ae559f36f1ef518e0c96335637431b4646354823b2804d0`,4,047 文件清单 SHA 为 `e459adf2f12adb6a1b7f55e66a9da1c22794185e66e848057d21e0c60d669203`。离线重审逐个核对实际复制文件,以及 WindTerm/Qt5Core/Qt5Gui/Qt5Widgets 四个原件和副本的完整 SHA;运行时实际模块路径与固定导出 RVA 守卫通过。
- 独立 WindowStation/Desktop、OwnedJob、隔离 HOME/profile、单个合成 loopback Telnet 会话。没有操作用户输入桌面、个人剪贴板或 DPI。Telnet 直达终端观察不代表 WinPTY/ConPTY local-shell 合同。

REA Evidence ID 为 `ev_931e2e152246d132fdf497ec9f4180843ef6244beb4cc9c1ec2fb6e19805326f`。源、模块、输入、白名单标量、histogram/有序签名和原件 SHA 见[脱敏结果](../../research/ui/results/2026-10-29-raster-raw-reference/validation.json)。

## 五阶段实际观察

| 阶段 | DSR 回复 | isAltScreen / isMainScreen | P caret / anchor | selectionText type / length | 完整 H/space 组数 |
|---|---|---|---|---|---|
| 0 D0/M0 双 H | `(4,9)` | false / true | 19 / 19 | string / 10 | 4 |
| 1 A0 与同帧正控 | `(1,19)` | true / false | 38 / 38 | string / 20 | 3 |
| 2 A1 S2 双 H | `(4,11)` | true / false | 51 / 51 | string / 12 | 2 |
| 3 A2 与同帧正控 | `(1,26)` | true / false | 45 / 45 | string / 27 | 4 |
| 4 M1 与同帧正控 | `(4,35)` | false / true | 45 / 45 | string / 36 | 4 |

五条 DSR 回复均为无 `?` 前缀的 `CSI row;column R`,没有额外应用字节。逐条完整 NAWS 事件为 `91×24 → 91×25`,冻结事件数 2,冻结后未观察到变化;终端 API capacity 为 25。五个 ack 文件内容均为 `captured`,只在完整读取该阶段所有 ROI 并完成 image→pixmap 析构后释放下一阶段。所有 `capture_valid=true`,不是颜色分类通过标志。

五次选择端点都是已知、相等、有限非负安全整数;`selectionText` 仅保留 type/length。每个 marker 的完整 token、ordinal/group/sample 和位置独立核对,未将 `M1S1` 等前缀绑定为 `M1`。H/space 与实际 caret 占用均不相交,零宽 caret 按至少一个逻辑像素检查。

五张图均为 `888×451`,QPixmap/QImage DPR 均为 1,inclusive grab QRect 为 `[0,0,887,450]`。每个 H 和 space 均为 `8×18`,各有 144 个 uint32 QRgb;合计 34 个数组、4,896 个采样值。Qt 的 QPixmap/QImage 各分配 32B、不预构造,正常返回后每阶段均按 image→pixmap 普通析构。真实 `QImage::isNull` 原值为整数 `0`,公开保留精确原值/类型并规范为 false。

## 输出签名事实与未知

phase0 的 D0 两组完整 H/space 签名相同,S1 两组也相同,D0 与 S1 可区分。phase2 两个 H 的完整有序签名也相同:其 space 为单一背景 `[138,110,201,255]`,H 中 `[137,110,201,255]` 与 `[138,120,137,255]` 各 16 个样本并列最高;两组均为 `dominant-ink-ambiguous`、`dominant_ink_rgba=null`,保留所有候选、频数和 histogram,没有选定一种颜色。

| 目标 | 同帧显式正控 | 完整 H/space 有序签名结果 |
|---|---|---|
| phase1 A0,首次 `1049h` 后原样写入 | S1、D0 | 唯一匹配 D0 (`SGR0`) |
| phase3 A2,重复 `1049h` 后原样写入 | D0、S1、S2 | 唯一匹配 D0 (`SGR0`) |
| phase4 M1,`1049l` 后原样写入 | S1、S2、D0 | 唯一匹配 S1 (`SGR31;44`) |

匹配只陈述这几个合成 H/space 的局部输出事实。没有读取内部 pen、完整 current_style、非颜色属性或全部 active grid;不据此声称 reset、完整屏幕清空、局部滚动区域、resize、WinPTY/ConPTY local-shell、实际 presented 或性能等价已验证。主要墨迹并列与完整 raw 采集同时成立,不能将 `raw_capture_complete` 改称五阶段样式对齐通过。

## 离线审计与回收

原始 CLI 真正结束、exit=0 后才导出,stderr 为空,REA 无脚本错误、消息截断或清理错误;provider subject/environment 仍为 null。Job 为 `active=0,total=3,terminated=0`,profile 保持唯一合成会话。启动器主动结束原版,Job0 不证明自然 GUI 退出。REA capture 为 45 秒、CLI wait 为 60 秒,原版在单独 2 秒等待前已启动,后续还有清理;整程上限未知,不提供计时结论。

普通和 `python -O` 对同一真实原件的公开出口逐字节相同,SHA 为 `a93b34233806fe3f32bf5fe70a0a5953ad43156d0a574cb79677784e9f3b9cca`,公开 validation 原样保留该出口。独立审计不调用现有分析器:从原消息核对五阶段/最终结果,重建实际注入脚本(含 Windows 写入换行),逐一重算 34 个数组的 histogram、有序 SHA、尺寸和数量,并以完整数组直接比较同帧正控;另核对源/模块/包、plan/attempt、DSR、ack、NAWS、marker/端点/caret/DPR/边界、构造析构和回收,结果一致。

将 main `4f34146ab81f5b156537b080df2156f484793cc4` 合入交付分支后,七个生产源、false proposal、旧批公开原记录与实际执行身份保持不变;独立离线审计再次通过,Debug 配置的 CTest `windterm_raster_style_reference`、`windterm_raster_selection_proposal`、`windterm_raster_raw_proposal` 为 3/3。只运行合成/离线测试,没有重新启动原版;这些测试不增加原版样本数。

原始 ROI 像素、日志、路径、PID、复制资源和 profile 留在唯一私有目录 `local/r129-raw-capture-v1-0`;公开仅有合成输入、审计后的颜色/尺寸/频数标量及哈希。[旧 #126 的 0 grab 停止](windterm-1049-raster-reference-2026-10-28.md)、[旧 #129 的 3 grab partial](windterm-raster-selection-reference-2026-10-29.md)、旧 false proposal 和原件均未改写;旧批第二个 H 与 phase3/4 的缺口没有补造或与本批拼接。本批不关闭 #129、#126、#123、#27 或 R2。
Loading