From 178faba6c245298a1410d6954b6a7e1df1e9bbd7 Mon Sep 17 00:00:00 2001 From: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com> Date: Thu, 29 Oct 2026 06:43:07 +0800 Subject: [PATCH 1/4] diagnostics: prepare fixed resize repaint witness for #156 --- CMakeLists.txt | 5 + docs/research/resize-repaint-witness-plan.md | 55 +++++ .../core/prepare_resize_repaint_witness.py | 162 +++++++++++++ experiments/core/resize_repaint_witness.cpp | 229 ++++++++++++++++++ 4 files changed, 451 insertions(+) create mode 100644 docs/research/resize-repaint-witness-plan.md create mode 100644 experiments/core/prepare_resize_repaint_witness.py create mode 100644 experiments/core/resize_repaint_witness.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 886fc35d..54241eb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,11 @@ add_executable(selection_test experiments/core/selection_test.cpp) target_link_libraries(selection_test PRIVATE termforge_core) termforge_warnings(selection_test) +# Explicit, data-only diagnosis; observed bad states are never CTest passes. +add_executable(resize_repaint_witness EXCLUDE_FROM_ALL experiments/core/resize_repaint_witness.cpp) +target_link_libraries(resize_repaint_witness PRIVATE termforge_core) +termforge_warnings(resize_repaint_witness) + add_executable(search_test experiments/core/search_test.cpp) target_link_libraries(search_test PRIVATE termforge_core) termforge_warnings(search_test) diff --git a/docs/research/resize-repaint-witness-plan.md b/docs/research/resize-repaint-witness-plan.md new file mode 100644 index 00000000..21ed257a --- /dev/null +++ b/docs/research/resize-repaint-witness-plan.md @@ -0,0 +1,55 @@ +# #156 缩小与重绘交错的固定机制诊断 + +这是独立 C++ 诊断的执行前合同,不是产品修复、性能测试或 CI 根因裁决。实现以实际失败的 `58fee2805cde34c67683a79473ca56f9df3cbf69` 为基点,不修改 Win32、Qt、Parser、Screen、TextDocument 或 TextSelection。原始失败 artifact 保持原件;本诊断不上传图片、私有路径、进程或个人会话。 + +## 已知事实与缺口 + +[#156](https://github.com/JavaZeroo/termforge/issues/156) 的旧默认 Win32/system-ConPTY 运行中,阶段 82 为 111×7/document 82,阶段 83 为 149×10/document 85,两者选区复制均为 2499B。阶段 84 恢复 111×7 后,document 仍为 85、top 从 75 变 78,选区失效;原选中行的部分身份对应的文字确实改变。TextSelection 已允许文字、span、边界不变的纯 version 更新,不能仅以 version 变更解释失效。 + +`ResizeWorker::settled()` 只说明原生 resize API 返回,不证明 Parser 已消费前一重绘、child 已确认尺寸或画面已呈现。原记录缺少每阶段已消费 transport offset 和 parser cursor。本诊断只验证给定交错能否形成相关坏状态,无法证明 CI 使用了这个切点、真实调度或唯一根因。 + +## 输入与初始状态 + +使用实际 `Parser(ParseMode::recovery)`、`TextDocument` 与 `TextSelection` 的公开边界。初始化 111 columns × 7 rows、history capacity 100;由失败源 `text_client.cpp` 的原 fixture 生成函数构造 `TF_FIND_000` 至 `TF_FIND_079`、`TF_FIND_READY 080`,再按 `ShellWindow::select_all_text` 的实际范围规则 Select All。禁止直接写入 Screen 行、补造行身份或更改选择内容以匹配目标。 + +初始硬门槛是 history 75、document 82、cursor row 6/column 0、实际复制字节与完整原 fixture literal 相等且恰为 2499B。任一门槛失败就保留部分记录并以 exit 2 停止;先调查缺失的源复现条件,不调整输入、ID 或断言来取绿。新 Parser 使用自身自然分配的相对 ID,不声称复制了 CI 启动前的绝对 ID 偏移。 + +transport 只由原创合成标记与 VT 构造。准备脚本在内存中与固定原 archive 的相关 member 逐字节比较,不提取、覆盖或直接 dump archive 文件: + +- 原 failure ZIP SHA-256:`ea38ca1099f6f52420d77bee16796d04e986eab02c8912a692e013bf4d12282a`。 +- 完整 transport:1071B,SHA-256 `c1d7cb18d5da399a838c997e0abe9375fd4db037e9f8f609ac02e1a58878cb84`。 +- 五段长度:210 / 210 / 210 / 231 / 210;全局边界 0 / 210 / 420 / 630 / 861 / 1071。 +- 普通段 SHA-256:`2f9e22d1b637e223fee1aa4fa0f9bcf3dab37dbccc29702cbfa8c3b591cd8de6`;第四段:`0ace2466754cef766944ccf2b80dce8bf85947eb7debaa057a8f7d61044d1610`。 + +每段包含 hide cursor、Home、`TF_FIND_075..079` 与 READY 行的原序重绘。第四段有四空行并以 CUP 7;1 收束,其余段只有一空行。所有字节和顺序都保留,不根据重复文字去重;切分只决定 resize 插入点。 + +## 四个 case,各一次 + +每个 case 使用全新 Parser/selection 和相同初始门槛。前三次依次 resize 至 112×7、112×7、111×7,各喂入对应完整 210B 段;第四次先到 149×10,再按下表喂第四段前缀、缩小到 111×7、喂原尾部(如有),最后喂完整第五段。尺寸统一写作 columns×rows。 + +| Case | 第四段已消费 | 全局 offset | 缩小边界 | 静态预测,非验收断言 | +| --- | ---: | ---: | --- | --- | +| A | 231B | 861 | 完整第四段后 | 选区保留 | +| B | 204B | 834 | 第七物理行的 EL 后,原尾部 27B 待消费 | 可能出现与 CI 相近的相对行身份/文字覆盖和选区失效 | +| C | 225B | 855 | CUP 7;1 完成后,仅 show cursor 待消费 | 选区保留 | +| D | 219B | 849 | CUP 7;1 之前 | 可能因缩小时 cursor 位于更低行而出现另一种移动/覆盖路径 | + +只执行这四个 case,各一次,不扫描额外切点,不重试、筛选或丢弃不支持假设的结果。A/B/C/D 均完整消费 1071B;诊断不得修改产品 policy。 + +## 观测、判定与边界 + +每次 seed/feed/resize 后按照当前 policy reconcile,再通过公开接口复制。Select All 建立后也记录一个 checkpoint。输出 JSONL 包含固定 case/sequence、累计 transport offset、cursor/wrap、grid/history/document、epoch/discarded、选区 reconcile 前后范围、复制状态/长度/摘要、首个失效 sequence,以及全部保留行的 index/ID/version、文字与 span 摘要、ending/joins-next。行摘要使用十进制 FNV-1a64,供比较变化;它不替代输入/源/原件的 SHA-256 身份,也不推断 glyph 或呈现。 + +固定 51 个 checkpoint(A 12、B/C/D 各 13),每个最多 40000B、document 最多 110 行、copy 最多 8192B;协议总 stdout 上限 2MiB、stderr 64KiB。无时钟、sleep、网络、窗口、ConPTY、worker 或外部进程进入 C++ witness。未来进程外执行上限为 10s;这只是诊断资源守卫,不是性能要求。准备阶段不启动任何核心、编译器或诊断程序。 + +单 case 最终复制不是原 2499B 就报告 `observed_bad_state`,始终 `semantic_acceptance=false`、`ci_cause_established=false`。预测只记录 `prediction_matches`,不控制退出码或筛选结果。CLI 0 只表示四个预定诊断齐全且记录成功,允许包含已观察坏状态;不是产品正确性通过。协议、初始门槛或写出错误返回 2,保留 stdout/stderr/exit 和所有已完成 case,不悄悄重跑。不向 CTest 注册这个诊断,避免把已知坏状态当成自动产品通过。 + +## 源、构建与执行授权 + +`resize_repaint_witness` 是 CMake 的 `EXCLUDE_FROM_ALL` 显式 target,只链接现有 header-only `termforge_core`,无新依赖/后端。准备脚本不编译、不运行 witness,只读 Git 和固定 ZIP、生成独立合成 transport 与本地冻结 plan。脚本要求源码已提交且工作树干净、输出目录不存在、固定原件与 transport hash 正确,逐项确认原八个相关文件在失败源、本次源及显式比较源 `6a10e5322a1bddeb038670e50f32ff6deac145cf` 的 Git blob 一致。 + +本地 plan 记录准备提交、15 个实际源/参考文件的 SHA-256 与 Git blob、原 ZIP 身份、输入字节/段身份、四个 case 与预算。计划的构建配置是 Visual Studio 17 2022 x64 Release、C++17、`/W4 /utf-8`、parallel 1,关闭 BUILD_TESTING、Qt shell、candidate adapter;只构建显式 witness target,不运行 CTest。CMake 默认生成的优化、运行库和其他实际 flags 不能仅凭该意图视为已核。 + +**当前仅允许准备;编译与执行授权为 false。** 实际 compiler 路径/hash/version、展开后的 flags、EXE 大小/hash 和构建日志均为 null,不能借用旧 EXE 身份。等 root 发放短诊断租约后,先核所有冻结输入与原 archive,再独立配置/构建并记录真实 compiler/flags/EXE;若源码或协议需要修订,先重新冻结新身份、保留旧 plan,不用旧执行预算暗中重试。 + +未来只能使用记录的绝对 EXE 和输入路径启动一次、保留完整 stdout/stderr/exit;执行后核输入、15 源和原 archive 均未改。原 CI artifact、其他旧证据和生产源码保持原样。实际结果、机制支持程度、未知与后续是否需要产品修复归 #156,不把这份执行前计划写成验收或批次日志。 diff --git a/experiments/core/prepare_resize_repaint_witness.py b/experiments/core/prepare_resize_repaint_witness.py new file mode 100644 index 00000000..5b565529 --- /dev/null +++ b/experiments/core/prepare_resize_repaint_witness.py @@ -0,0 +1,162 @@ +"""Freeze #156's synthetic input and local plan; never build or run the witness.""" +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path +import subprocess +import zipfile + +BASE = "58fee2805cde34c67683a79473ca56f9df3cbf69" +COMPARISON = "6a10e5322a1bddeb038670e50f32ff6deac145cf" +ARCHIVE_SHA = "ea38ca1099f6f52420d77bee16796d04e986eab02c8912a692e013bf4d12282a" +TRANSPORT_SHA = "c1d7cb18d5da399a838c997e0abe9375fd4db037e9f8f609ac02e1a58878cb84" +MEMBER = "test-artifacts/text-actions/run-rhfh7zlm/system-0/actions-geometry-bottom.transport.bin" +ROOT = Path(__file__).resolve().parents[2] +ORIGINAL_EIGHT = ( + "experiments/core/terminal.hpp", "experiments/core/screen.hpp", + "experiments/core/text_document.hpp", "experiments/core/text_selection.hpp", + "experiments/shell/shell.cpp", "experiments/shell/resize.hpp", + "experiments/shell/workspace_actions_scenario.hpp", "experiments/shell/text_client.cpp", +) +SOURCES = ORIGINAL_EIGHT + ( + "experiments/core/text_projection.hpp", "experiments/core/unicode_width.hpp", + "experiments/shell/text_interactions.hpp", "CMakeLists.txt", + "experiments/core/resize_repaint_witness.cpp", + "experiments/core/prepare_resize_repaint_witness.py", + "docs/research/resize-repaint-witness-plan.md", +) +CASES = [ + {"case": "A", "fourth_prefix_bytes": 231, "cut_global_offset": 861, "predicted_bad_state": False}, + {"case": "B", "fourth_prefix_bytes": 204, "cut_global_offset": 834, "predicted_bad_state": True}, + {"case": "C", "fourth_prefix_bytes": 225, "cut_global_offset": 855, "predicted_bad_state": False}, + {"case": "D", "fourth_prefix_bytes": 219, "cut_global_offset": 849, "predicted_bad_state": True}, +] + + +def require(condition: bool, message: str) -> None: + if not condition: + raise ValueError(message) + + +def sha(data: bytes) -> str: + return hashlib.sha256(data).hexdigest() + + +def file_identity(path: Path) -> dict: + digest = hashlib.sha256() + size = 0 + with path.open("rb") as stream: + for chunk in iter(lambda: stream.read(65536), b""): + digest.update(chunk) + size += len(chunk) + return {"bytes": size, "sha256": digest.hexdigest()} + + +def git(*arguments: str) -> str: + # Read-only Git queries are the only child commands of preparation. + result = subprocess.run(["git", *arguments], cwd=ROOT, check=True, capture_output=True) + return result.stdout.decode("utf-8").strip() + + +def fixture_rows(first: int, count: int) -> bytes: + # Original text_client.cpp fixture, not captured terminal or image content. + return "".join(f"TF_FIND_{row:03d} needle 中文 e\u0301\r\n" for row in range(first, first + count)).encode("utf-8") + + +def redraw(expanded: bool) -> bytes: + data = b"\x1b[?25l\x1b[H" + for row in range(75, 80): + data += fixture_rows(row, 1)[:-2] + b"\x1b[K\r\n" + data += b"TF_FIND_READY 080\x1b[K\r\n" + data += b"\r\n".join([b"\x1b[K"] * (4 if expanded else 1)) + if expanded: + data += b"\x1b[7;1H" + return data + b"\x1b[?25h" + + +def prepare(archive: Path, output: Path) -> dict: + require(not git("status", "--porcelain", "--untracked-files=all"), "commit preparation sources before freezing") + source_commit = git("rev-parse", "HEAD") + require(git("merge-base", BASE, source_commit) == BASE, "preparation is not based on the failed source") + require(output.is_relative_to(ROOT / "local"), "private plan and generated input must stay in this worktree's ignored local directory") + require(not output.exists(), "output must be new; existing plans and attempts are immutable") + normal, expanded = redraw(False), redraw(True) + require(len(normal) == 210 and len(expanded) == 231, "constructed block length differs") + transport = normal * 3 + expanded + normal + require(len(transport) == 1071 and sha(transport) == TRANSPORT_SHA, "constructed transport identity differs") + selected = fixture_rows(0, 80) + b"TF_FIND_READY 080\r\n" + require(len(selected) == 2499, "original fixture literal size differs") + before = file_identity(archive) + require(before["sha256"] == ARCHIVE_SHA, "failure archive identity differs") + with zipfile.ZipFile(archive) as bundle: + entry = bundle.getinfo(MEMBER) + require(entry.file_size == 1071, "failure transport length differs") + observed = bundle.read(entry) + require(observed == transport, "constructed bytes differ from the archived transport") + require(file_identity(archive) == before, "failure archive changed during preparation") + sources = [] + for name in SOURCES: + path = ROOT / name + sources.append({"path": name, "git_blob": git("rev-parse", f"{source_commit}:{name}"), **file_identity(path)}) + comparisons = [] + for name in ORIGINAL_EIGHT: + failed = git("rev-parse", f"{BASE}:{name}") + current = git("rev-parse", f"{COMPARISON}:{name}") + require(failed == current, "original eight files differ at the explicit comparison source") + require(failed == git("rev-parse", f"{source_commit}:{name}"), "preparation changed original code") + comparisons.append({"path": name, "git_blob": failed}) + plan = { + "schema": "termforge-resize-repaint-plan-v1", "issue": 156, + "protocol": "termforge-resize-repaint-witness-v1", "execution_authorized": False, + "source_commit": source_commit, "failed_source_commit": BASE, + "comparison_commit": COMPARISON, "original_eight_equal": comparisons, "source_files": sources, + "archive": {"path": str(archive), **before, "transport_member": MEMBER, "unchanged_after_read": True}, + "input": {"file": "transport.bin", "bytes": len(transport), "sha256": sha(transport), + "origin": "constructed from original TermForge synthetic markers and fixed VT; archive byte equality checked", + "block_lengths": [210, 210, 210, 231, 210], + "block_sha256": [sha(part) for part in [normal, normal, normal, expanded, normal]], + "selected_literal_bytes": len(selected), "selected_literal_sha256": sha(selected), + "seed_feed_bytes": len(b"\x1b[2J\x1b[H" + selected), + "seed_feed_sha256": sha(b"\x1b[2J\x1b[H" + selected)}, + "cases": CASES, "case_attempts_each": 1, "maximum_batches": 1, + "initial": {"columns": 111, "rows": 7, "history_capacity": 100, "document_rows_required": 82, + "history_rows_required": 75, "cursor_row_required": 6, "cursor_column_required": 0, + "selection_bytes_required": 2499, "identity_scope": "fresh parser relative IDs; not CI absolute IDs"}, + "leading_grids_columns_rows": [[112, 7], [112, 7], [111, 7]], + "expanded_grid_columns_rows": [149, 10], "restored_grid_columns_rows": [111, 7], + "budgets": {"future_process_timeout_seconds": 10, "stdout_bytes_max": 2097152, + "stderr_bytes_max": 65536, "checkpoints_required": 51, "checkpoint_bytes_max": 40000, + "document_rows_max": 110, "copy_bytes_max": 8192}, + "build_intent": {"generator": "Visual Studio 17 2022", "architecture": "x64", "configuration": "Release", + "target": "resize_repaint_witness", "parallel": 1, + "definitions": {"BUILD_TESTING": "OFF", "TERMFORGE_BUILD_QT_SHELL": "OFF", + "TERMFORGE_BUILD_CANDIDATE_ADAPTER": "OFF"}, + "language": "C++17", "target_options": ["/W4", "/utf-8"], + "actual_compiler": None, "actual_flags": None, "actual_executable": None, + "actual_compile_log": None, "not_built_or_run": True}, + "later_execution_contract": {"absolute_executable_and_input": True, "recheck_all_frozen_inputs_before_launch": True, + "retain_stdout_stderr_exit_even_on_failure": True, "postcheck_all_sources_and_archive": True, + "no_cut_scan_retry_or_selection": True, "no_ctest_registration": True}, + "diagnostic_complete": None, "semantic_acceptance": False, "ci_cause_established": False, + "limitations": ["preparation only; no compiler, core or witness process executed", + "missing CI parser offsets/cursor prevent attribution to its actual timing", + "synthetic seed recreates required shape, not every pre-stage CI input or ID gap", + "native/API completion is not parser or child acknowledgement", + "FNV summaries are comparison aids, SHA-256 binds input/source/raw identity"], + } + output.mkdir(parents=True, exist_ok=False) + (output / "transport.bin").write_bytes(transport) + encoded = (json.dumps(plan, ensure_ascii=False, indent=2) + "\n").encode("utf-8") + (output / "plan.json").write_bytes(encoded) + return {"source_commit": source_commit, "plan_sha256": sha(encoded), "transport_sha256": sha(transport), + "source_files": len(sources), "cases": len(CASES), "execution_authorized": False} + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--archive", type=Path, required=True) + parser.add_argument("--out", type=Path, required=True) + arguments = parser.parse_args() + print(json.dumps(prepare(arguments.archive.resolve(strict=True), arguments.out.resolve()), sort_keys=True)) diff --git a/experiments/core/resize_repaint_witness.cpp b/experiments/core/resize_repaint_witness.cpp new file mode 100644 index 00000000..ce3b3f1a --- /dev/null +++ b/experiments/core/resize_repaint_witness.cpp @@ -0,0 +1,229 @@ +// Fixed #156 mechanism diagnosis through the real public core/selection APIs. +#include "terminal.hpp" +#include "text_document.hpp" +#include "text_selection.hpp" +#include +#include +#include +#include +#include +#include + +namespace { +using namespace termforge; +constexpr std::string_view protocol = "termforge-resize-repaint-witness-v1"; +constexpr std::string_view transport_sha256 = "c1d7cb18d5da399a838c997e0abe9375fd4db037e9f8f609ac02e1a58878cb84"; +constexpr size_t copy_limit = 8192; +constexpr std::array boundaries{0, 210, 420, 630, 861, 1071}; +struct Case { const char* name; size_t fourth_prefix; bool predicts_bad_state; }; +constexpr std::array cases{{{"A", 231, false}, {"B", 204, true}, + {"C", 225, false}, {"D", 219, true}}}; + +void require(bool condition, const char* message) { + if (!condition) throw std::runtime_error(message); +} +uint64_t fnv(std::string_view value) { + uint64_t hash = 14695981039346656037ull; + for (unsigned char byte : value) { hash ^= byte; hash *= 1099511628211ull; } + return hash; +} +void quoted(std::ostream& out, std::string_view value) { + Screen::quoted(out, std::string(value)); +} +// Same original fixture generator as text_client.cpp at the failed source. +std::string rows(unsigned first, unsigned count, bool matches) { + std::ostringstream out; + for (unsigned row = first; row < first + count; ++row) { + out << (matches ? "TF_FIND_" : "TF_EVICT_") << std::setw(3) << std::setfill('0') << row; + if (matches) out << " needle \xe4\xb8\xad\xe6\x96\x87 e\xcc\x81"; + out << "\r\n"; + } + return out.str(); +} +std::string selected_text() { return rows(0, 80, true) + "TF_FIND_READY 080\r\n"; } +std::string redraw(bool expanded) { + std::string result = "\x1b[?25l\x1b[H"; + for (unsigned row = 75; row < 80; ++row) { + const auto line = rows(row, 1, true); + result += line.substr(0, line.size() - 2) + "\x1b[K\r\n"; + } + result += "TF_FIND_READY 080\x1b[K\r\n"; + const int blank_rows = expanded ? 4 : 1; + for (int index = 0; index < blank_rows; ++index) { + result += "\x1b[K"; + if (index + 1 < blank_rows) result += "\r\n"; + } + if (expanded) result += "\x1b[7;1H"; + result += "\x1b[?25h"; + return result; +} +std::string expected_transport() { + const auto normal = redraw(false), expanded = redraw(true); + require(normal.size() == 210 && expanded.size() == 231, "constructed redraw size differs"); + return normal + normal + normal + expanded + normal; +} +std::string read_transport(const char* path) { + std::ifstream stream(path, std::ios::binary); + require(bool(stream), "transport input cannot be opened"); + std::array buffer{}; + stream.read(buffer.data(), static_cast(buffer.size())); + require(!stream.bad() && stream.gcount() == 1071, "transport input must contain exactly 1071 bytes"); + std::string result(buffer.data(), static_cast(stream.gcount())); + require(result == expected_transport(), "transport differs from the fixed constructed bytes"); + return result; +} +const char* copy_status(SelectionCopyStatus value) { + switch (value) { + case SelectionCopyStatus::ok: return "ok"; + case SelectionCopyStatus::empty: return "empty"; + case SelectionCopyStatus::invalidated: return "invalidated"; + case SelectionCopyStatus::limit_exceeded: return "limit_exceeded"; + } + throw std::runtime_error("unknown selection copy status"); +} +void position(std::ostream& out, TextPosition value) { + out << "{\"line_id\":" << value.line_id << ",\"version\":" << value.version + << ",\"column\":" << value.column << ",\"epoch\":" << value.epoch << '}'; +} +void range(std::ostream& out, const std::optional& value) { + if (!value) { out << "null"; return; } + out << "{\"begin\":"; position(out, value->begin); + out << ",\"end\":"; position(out, value->end); out << '}'; +} +uint64_t span_hash(const ProjectedLine& value) { + std::ostringstream canonical; + for (const auto span : value.spans) + canonical << span.byte_begin << ',' << span.byte_end << ',' + << span.column_begin << ',' << span.column_end << ';'; + return fnv(canonical.str()); +} +// Match ShellWindow::select_all_text's public range construction, including +// its excluded empty endpoint after a hard break. Never inject line identities. +bool select_all(TextSelection& selection, const TextDocument& document) { + for (size_t end = document.size(); end > 0; --end) { + const auto row = document.line(end - 1); + if (row.projection.spans.empty() && row.ending == LineEnding::none) continue; + auto last = document.position(end - 1, row.projection.spans.empty() ? 0 : row.projection.spans.back().column_end); + if (row.ending == LineEnding::hard_break && end < document.size()) last = document.position(end, 0); + const auto first = document.position(0, 0); + return first && last && selection.set(document, {*first, *last}); + } + selection.clear(); return false; +} +struct CaseResult { bool bad_state; size_t checkpoints; }; +CaseResult run_case(Case item, std::string_view transport) { + Parser parser(7, 111, 100, ParseMode::recovery); + TextSelection selection; + const auto expected = selected_text(); + size_t offset = 0, checkpoint_count = 0; + std::optional first_invalidation; + std::cout << "{\"schema\":\"termforge-resize-repaint-case-begin-v1\",\"case\":"; + quoted(std::cout, item.name); + std::cout << ",\"fourth_prefix_bytes\":" << item.fourth_prefix + << ",\"predicts_bad_state\":" << (item.predicts_bad_state ? "true" : "false") << "}\n"; + const auto checkpoint = [&](const char* operation, const char* label) { + TextDocument document(parser.screen); + require(document.size() <= 110, "diagnostic document bound exceeded"); + const auto before = selection.range(); + const bool reconciled = selection.reconcile(document); + if (before && !reconciled && !first_invalidation) first_invalidation = checkpoint_count; + const auto copied = selection.copy(document, copy_limit); + std::ostringstream out; + out << "{\"schema\":\"termforge-resize-repaint-checkpoint-v1\",\"case\":"; + quoted(out, item.name); out << ",\"sequence\":" << checkpoint_count++ << ",\"operation\":"; + quoted(out, operation); out << ",\"label\":"; quoted(out, label); + out << ",\"transport_consumed_bytes\":" << offset << ",\"grid_columns\":" << parser.screen.width() + << ",\"grid_rows\":" << parser.screen.height() << ",\"cursor_row\":" << parser.screen.row + << ",\"cursor_column\":" << parser.screen.column << ",\"wrap_pending\":" << (parser.screen.wrap_pending ? "true" : "false") + << ",\"history_rows\":" << parser.screen.history.size() << ",\"document_rows\":" << document.size() + << ",\"discarded_rows\":" << parser.screen.discarded << ",\"buffer_epoch\":" << document.epoch() + << ",\"range_before_reconcile\":"; range(out, before); + out << ",\"reconciled\":" << (reconciled ? "true" : "false") << ",\"range_after_reconcile\":"; + range(out, selection.range()); out << ",\"copy_status\":"; quoted(out, copy_status(copied.status)); + out << ",\"copy_bytes\":" << copied.text.size() << ",\"copy_fnv1a64\":\"" << fnv(copied.text) + << "\",\"copy_matches_initial_literal\":" << (copied.status == SelectionCopyStatus::ok && copied.text == expected ? "true" : "false") + << ",\"first_invalidation_sequence\":"; + if (first_invalidation) out << *first_invalidation; else out << "null"; + out << ",\"lines\":["; + for (size_t index = 0; index < document.size(); ++index) { + const auto row = document.line(index); + if (index) out << ','; + out << "{\"index\":" << index << ",\"id\":" << row.projection.id + << ",\"version\":" << row.projection.version << ",\"columns\":" << row.columns + << ",\"ending\":" << static_cast(row.ending) << ",\"joins_next\":" << (row.joins_next ? "true" : "false") + << ",\"text_bytes\":" << row.projection.text.size() << ",\"text_fnv1a64\":\"" << fnv(row.projection.text) + << "\",\"span_count\":" << row.projection.spans.size() << ",\"span_fnv1a64\":\"" << span_hash(row.projection) << "\"}"; + } + out << "]}"; + require(out.str().size() <= 40000, "diagnostic checkpoint byte bound exceeded"); + std::cout << out.str() << '\n' << std::flush; + }; + parser.feed("\x1b[2J\x1b[H" + expected); + checkpoint("seed-feed", "original-fixture-body"); + require(expected.size() == 2499 && parser.screen.history.size() == 75 && + parser.screen.retained_size() == 82 && parser.screen.row == 6 && parser.screen.column == 0, + "initial fixture shape differs; stop without altering seed or identities"); + require(select_all(selection, TextDocument(parser.screen)), "initial Select All range was rejected"); + checkpoint("selection", "actual-select-all-policy"); + const auto initial = selection.copy(TextDocument(parser.screen), copy_limit); + require(initial.status == SelectionCopyStatus::ok && initial.text == expected, + "initial Select All is not the fixed 2499-byte literal"); + const auto resize = [&](int rows, int columns, const char* label) { + parser.screen.resize(rows, columns); checkpoint("resize", label); + }; + const auto feed = [&](size_t end, const char* label) { + require(end > offset && end <= transport.size(), "invalid fixed feed interval"); + parser.feed(transport.substr(offset, end - offset)); offset = end; + checkpoint("feed", label); + }; + constexpr std::array columns{112, 112, 111}; + for (size_t index = 0; index < columns.size(); ++index) { + resize(7, columns[index], "declared-leading-grid"); + feed(boundaries[index + 1], "complete-leading-redraw"); + } + resize(10, 149, "zoom75-expanded-grid"); + feed(boundaries[3] + item.fourth_prefix, "fourth-redraw-prefix"); + resize(7, 111, "restore-grid-at-declared-cut"); + if (offset < boundaries[4]) feed(boundaries[4], "fourth-redraw-original-tail"); + feed(boundaries[5], "complete-fifth-redraw"); + const auto final = selection.copy(TextDocument(parser.screen), copy_limit); + const bool bad = final.status != SelectionCopyStatus::ok || final.text != expected; + std::cout << "{\"schema\":\"termforge-resize-repaint-case-result-v1\",\"case\":"; + quoted(std::cout, item.name); std::cout << ",\"status\":"; + quoted(std::cout, bad ? "observed_bad_state" : "selection_retained"); + std::cout << ",\"semantic_acceptance\":false,\"ci_cause_established\":false,\"transport_consumed_bytes\":" << offset + << ",\"checkpoints\":" << checkpoint_count + << ",\"prediction_matches\":" << (bad == item.predicts_bad_state ? "true" : "false") << "}\n" << std::flush; + require(checkpoint_count == (item.fourth_prefix == 231 ? 12u : 13u), "fixed checkpoint count differs"); + return {bad, checkpoint_count}; +} +} // namespace + +int main(int argc, char** argv) { + size_t completed = 0, bad_states = 0, checkpoints = 0; + try { + require(argc == 3 && std::string_view(argv[1]) == "--transport", "usage: resize_repaint_witness --transport fixed-input.bin"); + const auto transport = read_transport(argv[2]); + std::cout << "{\"schema\":\"termforge-resize-repaint-input-v1\",\"protocol\":"; + quoted(std::cout, protocol); std::cout << ",\"transport_expected_sha256\":"; + quoted(std::cout, transport_sha256); + std::cout << ",\"transport_bytes\":" << transport.size() << ",\"transport_fnv1a64\":\"" << fnv(transport) + << "\",\"byte_equal_to_constructed_fixture\":true,\"semantic_acceptance\":false}\n"; + for (const auto item : cases) { + const auto result = run_case(item, transport); + ++completed; bad_states += result.bad_state ? 1u : 0u; + checkpoints += result.checkpoints; + } + std::cout << "{\"schema\":\"termforge-resize-repaint-summary-v1\",\"diagnostic_complete\":true,\"cases_completed\":" + << completed << ",\"observed_bad_states\":" << bad_states + << ",\"checkpoints\":" << checkpoints + << ",\"semantic_acceptance\":false,\"ci_cause_established\":false,\"cli_zero_means\":\"four declared cases recorded\"}\n"; + require(bool(std::cout), "diagnostic output write failed"); + return 0; + } catch (const std::exception& error) { + std::cout << "{\"schema\":\"termforge-resize-repaint-summary-v1\",\"diagnostic_complete\":false,\"cases_completed\":" + << completed << ",\"semantic_acceptance\":false,\"ci_cause_established\":false}\n" << std::flush; + std::cerr << "resize repaint witness: " << error.what() << '\n'; + return 2; + } +} From 8294802af81212545def9f076d990f81294bc884 Mon Sep 17 00:00:00 2001 From: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com> Date: Thu, 29 Oct 2026 07:07:03 +0800 Subject: [PATCH 2/4] docs: record limited resize repaint mechanism witness for #156 --- docs/EVIDENCE.md | 1 + docs/FEATURES.md | 2 +- .../README.md | 30 + .../validation.json | 749 ++++++++++++++++++ 4 files changed, 781 insertions(+), 1 deletion(-) create mode 100644 experiments/shell/results/2026-10-29-resize-repaint-witness/README.md create mode 100644 experiments/shell/results/2026-10-29-resize-repaint-witness/validation.json diff --git a/docs/EVIDENCE.md b/docs/EVIDENCE.md index 2646d3a3..e1255597 100644 --- a/docs/EVIDENCE.md +++ b/docs/EVIDENCE.md @@ -62,6 +62,7 @@ R1 固定总出口的源码为 `ce9b24d`,早期 `2dc8d6d` / `9b16acc` 仍分 | 范围 | 结果与复现入口 | 可以支持的结论与限制 | |---|---|---| +| 默认核心缩小与重绘交错(#156) | [固定四-case机制诊断](../experiments/shell/results/2026-10-29-resize-repaint-witness/README.md)、[脱敏验证](../experiments/shell/results/2026-10-29-resize-repaint-witness/validation.json) | A/C保留2499B,B/D在第五段重绘首次失效且行分配路径不同;只见证机制,原CI切点/根因未知,未修生产。witness结束后Job仍active1,发起一次终止后归零;成员身份/逐句柄退出未知,不称全树自然退出。 | | 持续 cmd 输出与原始 Ctrl-C 回归(#36 未关闭) | [受监督入口](../experiments/conpty/README.md#持续-cmd-输出与-ctrlc-独立回归)、[三次 fresh 公开记录及本地字节复核](../experiments/conpty/results/2026-10-26-ctrl-c-retest/validation.json) | 原百万次输出、单次 ETX、五秒期限和退出 37 保留;三次 fresh 原始字节/Job0 本地重算。后续成功未解释历史失败,未改产品 Ctrl-C 路径。 | | 持续输出中断的原失败记录 | [#36](https://github.com/JavaZeroo/termforge/issues/36)、[ConPTY 输入机制研究](research/conpty-ctrl-c-input.md)、[原 R1 历史证据](../experiments/shell/results/2026-10-23-r1-foundations/validation.json) | 原 Windows 11 回归中的 normal/resize 超时与 ETW/插桩观察;调试扰动及管道读完成缺口保留。不是当前全套结果,后续未复现不能抹去此失败。 | | controller B 正常结束后 cmd 退出未验收(#44) | [原失败脱敏记录](../experiments/shell/results/2026-10-26-controller-exit/validation.json)、[新退出诊断及有界重放](../experiments/shell/results/2026-10-26-controller-exit-observation/validation.json)、[关闭合同](https://github.com/JavaZeroo/termforge/issues/44) | 原 child 收完 32B、退出 0/join/Job0;cmd 只留下 close 后 0xC000013A,close 前未知。新观察分列输入、wait、pre-close 与清理;多轮未复现不构成历史修复,继续阻塞 #38。 | diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 5a1f8621..574cc8ab 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -42,7 +42,7 @@ Qt 构建显式准备并部署[固定微软 CRT 14.51.36247.0](../third_party/ms | 中文 IME 与键盘 | **限定验收**:基础按键/修饰键/UTF-16 与实际接收字节;[固定 ZWJ/keycap 输入](../experiments/shell/results/2026-10-26-unicode-keyboard/validation.json)在默认/候选各两轮精确接收。固定 Microsoft 拼音[产品场景](../research/ime/results/2026-10-24-product-ime-contexts/validation.json)覆盖两区域组合/提交/取消、候选、输出/resize/zoom/受控 DPI、隐藏/关闭、历史阅读和原生控件 | 限定 Windows Server 2025 固定拼音及已有场景;同次组合由八会话工作流另验收。固定字素绘制/选择已由 #39 限定完成,但所有输入法、应用键盘模式、完整 IME 和真实不同 DPI 跨屏仍未完成 | R1 / R2 | | VT 核心 | **实现中,未验收**:默认自研支持基础光标/擦除(含 ECH)、CR/LF/BS/TAB、有限 SGR 和有界恢复。显式候选 `.4` 接入 `Term/Processor`、C++ 拥有值适配、稳定行元数据、每缓冲区 margin 与流式字素;[共同轨迹](../experiments/differential/results/2026-10-26-candidate-common-v6/summary.json)及[源 margin 合同](../experiments/shell/results/2026-10-26-margin-state/validation.json)为各自固定版本结果 | [#27](https://github.com/JavaZeroo/termforge/issues/27) 的 origin/wrap、插删、模式/resize 交叉未闭合;[#41](https://github.com/JavaZeroo/termforge/issues/41) 系统 ConPTY 已丢失的 margin 不能由末端补回。ECH pending-wrap 差异见[限定合同](research/more-capture-ech.md);#36/#38、完整呈现和平台支持独立验收 | R2 / R4 | | Unicode 与文字显示 | **实现中,未验收**:默认自研保留 Unicode 15。显式候选 `.4` 的 [#39 Unicode 17 流式字素合同](research/streaming-graphemes.md)已限定验收:固定 ZWJ/keycap 的单 lead/两列、光标、SGR/查询、原子选择复制、单列 resize 与有界无损分片;实际 ConPTY/DWrite 核对固定样本的单 glyph、字体和网格 | [#30](https://github.com/JavaZeroo/termforge/issues/30) 仍需完整输入/IME 交叉;所有脚本/整形、通用 fallback、所有原生重放、真彩色/更多属性、Powerline 和真实跨屏未验收。分段 helper 的规范数据通过不代表完整终端 Unicode 正确性;[#54](https://github.com/JavaZeroo/termforge/issues/54) 保留已观察的性能成本 | R2 / R4 | -| resize 与 reflow | **限定验收**:默认按 ADR-0005 物理行裁剪;候选在[固定 ConPTY 重放](../experiments/core/results/2026-10-26-resize-replay/validation.json)与连续同步中保持行身份、Find/选区和有界历史,淘汰/清空不复活;候选 `.4` 另覆盖主/备用屏缩到单列 | [#29](https://github.com/JavaZeroo/termforge/issues/29) 的完整 resize 交叉未完成;固定事务不等于完整 reflow 或 WindTerm 等价。系统/实验 ConPTY、备用屏/滚动区、真实 DPI、呈现、性能及 #36/#38 分别验收;默认缩窄不可恢复 | R2 | +| resize 与 reflow | **限定验收**:默认按 ADR-0005 物理行裁剪;候选在[固定 ConPTY 重放](../experiments/core/results/2026-10-26-resize-replay/validation.json)与连续同步中保持行身份、Find/选区和有界历史,淘汰/清空不复活;候选 `.4` 另覆盖主/备用屏缩到单列 | [#29](https://github.com/JavaZeroo/termforge/issues/29) 的完整 resize 交叉未完成;固定事务不等于完整 reflow 或 WindTerm 等价。[#156固定交错诊断](../experiments/shell/results/2026-10-29-resize-repaint-witness/README.md)见证默认核心在两种时序下选区失效,原CI切点与根因仍未知,未修生产。系统/实验 ConPTY、备用屏/滚动区、真实 DPI、呈现、性能及 #36/#38 分别验收;默认缩窄不可恢复 | R2 | | 本地 shell 选择 | **实现中,未验收**:`ShellLaunch` 分离可执行文件、参数、工作目录及 shell 命令差异;cmd、Windows PowerShell 5.1、PowerShell 7、显式 Ubuntu WSL 各有[两轮真实启动/目录/尺寸/正常退出证据](../experiments/shell/results/2026-10-24-r2-shell-lifecycle/validation.json),无效程序启动错误可见且可关闭后恢复 cmd。四 shell 测试已补 [WSL 原生尺寸程序返回后的新提示符同步](research/wsl-size-return.md),正常退出证据只在实际全部回收后写入;默认/system 的事件反例、原两轮及完整回归分别留证 | 仅声明上述固定入口和隔离目录;#80 原 hosted stage6 是否同因仍未知,#81 hosted 准备超时另行定位;任意 profile/参数、通用分屏/排序、全部运行时错误提示及管理员 shell 未完成 | R2;权限场景 R4 | | 常用 TUI | **实现中,未验收**:显式候选 + 系统 ConPTY 有固定 Vim 进入、编辑、60×12 resize、退出写盘、主屏恢复及光标回复的[产品证据](../experiments/core/CANDIDATE.md);More 尾部 ECH 与捕获端点有[限定修复](research/more-capture-ech.md) | [#28](https://github.com/JavaZeroo/termforge/issues/28) 的更多应用及完整输入/输出模式未完成;PR #50 实验后端的 GUI Vim [#52](https://github.com/JavaZeroo/termforge/issues/52) 仍有失败;[native 捕获目录复用](research/vim-fixture-isolation.md)已独立定位并修正,不能代替 GUI 或完整 TUI 验收。headless 比较与自有 DIB 不等于真实呈现,`presented_done=null` | R2 | diff --git a/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md b/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md new file mode 100644 index 00000000..6a4f5867 --- /dev/null +++ b/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md @@ -0,0 +1,30 @@ +# #156 缩小与重绘交错:限定 C++ 机制诊断 + +固定执行源 `178faba6c245298a1410d6954b6a7e1df1e9bbd7` 的一次四-case 诊断中,A/C 保留原2499B选区,B/D在第五段重绘时首次失效。它证明所列交错能通过真实 Parser/TextDocument/TextSelection 形成坏状态,**没有确定原 CI 的实际切点、调度或唯一根因,也没有修复生产逻辑**。`semantic_acceptance=false`、`ci_cause_established=false`、`ci_actual_cut_known=false`。 + +[执行前合同](../../../../docs/research/resize-repaint-witness-plan.md)、[诊断源码](../../../core/resize_repaint_witness.cpp)与[脱敏验证](validation.json)分别保留计划、实现和实际结果。准备提交与执行提交同为 `178faba`;本报告是后续文档发布,不充当运行源。原 false plan、授权执行 plan、原 CI artifact、全部编译/运行/分析 raw 均保留本地,不随报告上传。 + +## 固定输入与一次结果 + +诊断基于实际失败源 `58fee2805cde34c67683a79473ca56f9df3cbf69`,原八个相关文件与比较源 `6a10e5322a1bddeb038670e50f32ff6deac145cf` 的 blob 相同。没有运行 Win32/Qt UI、ConPTY 或原版。使用现有 recovery Parser、TextDocument、TextSelection 的公开边界,以原合成 fixture 函数生成 `TF_FIND_000..079` 和 READY 行;111×7、history capacity100时实际得到 history75/document82,并按真实 Select All 范围规则复制2499B。行 ID 由新 Parser 自然分配,不补造 CI 启动前的绝对偏移。 + +1071B transport 由原创标记和 VT 构造,与固定 CI member 在内存中逐字节相等,SHA-256为 `c1d7cb18d5da399a838c997e0abe9375fd4db037e9f8f609ac02e1a58878cb84`;五段为210/210/210/231/210B。四个 case 各一次,完整保留原字节与次序,不去重、不扫描切点、不重试。前三段各在112×7、112×7、111×7喂入,第四段先扩为149×10,再在固定前缀处缩回111×7,喂原尾及完整第五段。尺寸统一为列×行,offset为累计 transport 字节数。 + +| Case | 第四段缩小切点 | 缩小与原尾的实际观察 | 第五段后的结果 | +| --- | --- | --- | --- | +| A | 完整231B,offset861 | cursor row6;缩小后history75/document82 | 2499B保留 | +| B | 204B,offset834 | cursor row6;缩小后75/82。原27B尾在7行网格继续LF,使history78/document85,选区仍为2499B | 首次invalidated,sequence12/offset1071 | +| C | CUP 7;1已完成225B,offset855 | cursor row6;缩小后75/82;剩余6B show cursor无此变化 | 2499B保留 | +| D | CUP之前219B,offset849 | cursor row9;缩小本身使history78/document85;原12B尾后选区仍为2499B | 首次invalidated,sequence12/offset1071 | + +B/D在第五段Home重绘后,原相对ID79..82对应的文字摘要改变,选区按既有 policy 失效;这不是纯version变化导致的失效。B缩小时丢弃扩展空行ID83..85,再由原尾滚动分配ID86..88;D缩小时移动前三行入history并保留ID83..85。两条分配路径和尾部version不同,不能把B/D当作同一条时序。B的部分尾version与旧CI相似,只能作为机制比较,不能据此认定CI在offset834缩小;CI每阶段的真实消费offset/parser cursor仍缺失。 + +## 构建、记录与监督边界 + +一次独立configure/build成功,0 warning/error;Visual Studio 2022 x64 Release,MSVC `19.42.34433.0`,实际编译参数含 `/O2 /MD /std:c++17 /W4 /utf-8`。只构建显式 `EXCLUDE_FROM_ALL` witness,关闭Qt/candidate/BUILD_TESTING,不注册CTest。EXE为112128B,SHA-256 `3fdd9172e955a468fc9db7a540dcc5042156cde2aafa8e0bee1786cb6f0189c4`;15个冻结源、输入、原archive、compiler/flags/EXE后验0变。 + +实际输出61条JSONL、51个checkpoint、817861B stdout,stderr为空,无超时或输出溢出。每次feed/resize均reconcile并记录cursor/history、行ID/version、文字/span摘要、选区与首失效点;FNV摘要用于比较变化,输入/源/EXE/raw身份另以SHA-256绑定。CLI0仅表示四个预定诊断记录齐全,包含两个`observed_bad_state`,不表示产品正确性通过。10s进程守卫和输出上限是诊断资源边界,不是性能结论。 + +每个阶段的GO host先进入独占Job后才启动子命令。configure/build结束时分别为Job0/30/0、0/20/0,无终止请求。witness root已回收并关闭handle,但其结束后仍观察到Job active1/total5/terminated0;监督器发起一次TerminateJobObject,再观察到0/5/0。没有为该剩余成员保留逐进程handle/身份,无法判断它是谁或是否在请求前后自然退出。terminated计数0不能证明没有影响;**不宣称全树自然退出**。 + +此诊断没有观测真实CI调度、child尺寸确认、Qt产品路线、画面呈现、WindTerm等价或性能,也未更改旧严格判据。后续定位与生产修复归[#156](https://github.com/JavaZeroo/termforge/issues/156);原失败与未知不因机制见证而转为通过。 diff --git a/experiments/shell/results/2026-10-29-resize-repaint-witness/validation.json b/experiments/shell/results/2026-10-29-resize-repaint-witness/validation.json new file mode 100644 index 00000000..d4529ae2 --- /dev/null +++ b/experiments/shell/results/2026-10-29-resize-repaint-witness/validation.json @@ -0,0 +1,749 @@ +{ + "schema": "termforge-resize-repaint-witness-validation-v1", + "issue": 156, + "kind": "mechanism-diagnostic", + "diagnostic_complete": true, + "semantic_acceptance": false, + "ci_cause_established": false, + "ci_actual_cut_known": false, + "production_fix_implemented": false, + "source_identity": { + "failed_ci_source_commit": "58fee2805cde34c67683a79473ca56f9df3cbf69", + "diagnostic_execution_source_commit": "178faba6c245298a1410d6954b6a7e1df1e9bbd7", + "original_eight_comparison_commit": "6a10e5322a1bddeb038670e50f32ff6deac145cf", + "original_eight_blob_equal": true, + "frozen_source_file_count": 15, + "frozen_files": [ + { + "path": "experiments/core/terminal.hpp", + "git_blob": "228ca86b5ddd1af7d98ca2e990252db32bf4b9d8", + "bytes": 12270, + "sha256": "ed3c030611a6df38df26057a8c2834f2808cd05306e73aead79927b1f76fe5ca" + }, + { + "path": "experiments/core/screen.hpp", + "git_blob": "cedebb2fec44efc8fa0737b15f346a9eb106a0c5", + "bytes": 17242, + "sha256": "04c19f09ebc0c468efbef8dd4c9da8f4bcd44e94000a87c56239756c0df1b474" + }, + { + "path": "experiments/core/text_document.hpp", + "git_blob": "ac104aedca2102c3f9928ec64b787fe042aabb4d", + "bytes": 3850, + "sha256": "a51903b9091471b0d52c47f34b966f56b23045042c007fe8cd6f6e1b1302934c" + }, + { + "path": "experiments/core/text_selection.hpp", + "git_blob": "824d02ec7f9ad3360ce499f4bf3946e0031e690d", + "bytes": 9883, + "sha256": "5c3848d06bcb34f036aabec7d3e8a953796caed1ba90a8c8d40b62d3e2242bb0" + }, + { + "path": "experiments/shell/shell.cpp", + "git_blob": "70decfd90c287d4b6a3381c5cb4a3fbda4ccf184", + "bytes": 84863, + "sha256": "cc3830a52aebfad69871d974fed6c3f295f58e1e75feb451f7cfc11e0e56a3ef" + }, + { + "path": "experiments/shell/resize.hpp", + "git_blob": "da9f739d18f21ac14a137beeedaedc80f9d98feb", + "bytes": 3859, + "sha256": "14e44837d8fc2d0b88356db824e46616ef6c210dcf9b668445478bac06284415" + }, + { + "path": "experiments/shell/workspace_actions_scenario.hpp", + "git_blob": "b046f297192d4990332a27a008a78df198a960e1", + "bytes": 33825, + "sha256": "0da18068dffcf702e1c5a3bd7e524660d24a59ca3416dc3ce7167940a85527a0" + }, + { + "path": "experiments/shell/text_client.cpp", + "git_blob": "2aec79e842b5191f3b8417f3cb95bd0aadf91ec5", + "bytes": 16420, + "sha256": "aea8ed527e6e79fbe61446afadbb25d4fa0b7ddef4966930583ac8fa04cadd15" + }, + { + "path": "experiments/core/text_projection.hpp", + "git_blob": "fcef22e60e8ad61aec9b055088bca08dd3bb30d7", + "bytes": 1784, + "sha256": "3853bcf053964e54ea00bb7acfd0d302abd536ae0ed4eddfe791a6bcffdb6914" + }, + { + "path": "experiments/core/unicode_width.hpp", + "git_blob": "0b6e3a18c430edbf662ff8881c3b1825d6ef775b", + "bytes": 32445, + "sha256": "d48bf60090a9c6a4263bb46ac587b13814b52c0dbe9d2649cee20e832a1e1926" + }, + { + "path": "experiments/shell/text_interactions.hpp", + "git_blob": "3a372c7c9bc87a447698685afebfb308813457ee", + "bytes": 6447, + "sha256": "a38d05fe29930749b045af283415be138c9f2bda2fdc2de6fc84bd86c30d7473" + }, + { + "path": "CMakeLists.txt", + "git_blob": "54241eb034cbb4b24b9bd784d7d9fd70da3d6bca", + "bytes": 27140, + "sha256": "74df83374ed0e05b0afd6706ab53996cdc072ea73ee123052b92c80bef571655" + }, + { + "path": "experiments/core/resize_repaint_witness.cpp", + "git_blob": "ce3b3f1a4214acf68d2104c2097e811d39831206", + "bytes": 13083, + "sha256": "4be4b1574f5da2ab854658f176a479e52e86f0bb8f0258c912ed4c8926da9381" + }, + { + "path": "experiments/core/prepare_resize_repaint_witness.py", + "git_blob": "5b5655291f38f13701cfb1f42fdc6503b16c2693", + "bytes": 9482, + "sha256": "df5900851a32ecfebc1e8c1cfcc22f5687fcb7a8f37980cee20419d13368e64b" + }, + { + "path": "docs/research/resize-repaint-witness-plan.md", + "git_blob": "21ed257ab86be4f8db5bc5c8d163a75d22732ddf", + "bytes": 7442, + "sha256": "e067e3bc297973e4f509d37b519a7398448d5f27dc68ec4f9cc893c8d73782cc" + } + ] + }, + "plan_identity": { + "preparation": { + "execution_authorized": false, + "bytes": 9039, + "sha256": "b60d1eca333528ca434b40ac482f7856b8852dc57aea7894405c76e3f3a5b576" + }, + "authorized_execution": { + "execution_authorized": true, + "bytes": 3143, + "sha256": "e34a219329f76400c8df8008c8b201be4dd96a7e56c2d5632e1543bc89d7fc35" + }, + "both_retained_unmodified": true + }, + "original_ci_archive_identity": { + "bytes": 4722483, + "sha256": "ea38ca1099f6f52420d77bee16796d04e986eab02c8912a692e013bf4d12282a", + "retained_locally": true, + "included_in_git": false + }, + "synthetic_input": { + "origin": "original-termforge-markers-and-fixed-vt", + "transport": { + "bytes": 1071, + "sha256": "c1d7cb18d5da399a838c997e0abe9375fd4db037e9f8f609ac02e1a58878cb84" + }, + "archive_transport_byte_equal": true, + "block_bytes": [ + 210, + 210, + 210, + 231, + 210 + ], + "block_sha256": [ + "2f9e22d1b637e223fee1aa4fa0f9bcf3dab37dbccc29702cbfa8c3b591cd8de6", + "2f9e22d1b637e223fee1aa4fa0f9bcf3dab37dbccc29702cbfa8c3b591cd8de6", + "2f9e22d1b637e223fee1aa4fa0f9bcf3dab37dbccc29702cbfa8c3b591cd8de6", + "0ace2466754cef766944ccf2b80dce8bf85947eb7debaa057a8f7d61044d1610", + "2f9e22d1b637e223fee1aa4fa0f9bcf3dab37dbccc29702cbfa8c3b591cd8de6" + ], + "markers": { + "numbered_prefix": "TF_FIND_", + "first": 0, + "last": 79, + "ready": "TF_FIND_READY 080" + }, + "selected_literal": { + "bytes": 2499, + "sha256": "d02b18d30baf87f899b290ee2f3cb7243e6b313f9cfdfb8dce58ac6d0aebc937" + }, + "seed_feed": { + "bytes": 2506, + "sha256": "5f68f0634f6d10641466fc9fbe513c7db6dac3812fca332a3406524e1aab90b8" + }, + "initial_grid_columns_rows": [ + 111, + 7 + ], + "history_capacity": 100, + "initial_history_rows": 75, + "initial_document_rows": 82, + "initial_cursor_row_column": [ + 6, + 0 + ], + "leading_grids_columns_rows": [ + [ + 112, + 7 + ], + [ + 112, + 7 + ], + [ + 111, + 7 + ] + ], + "expanded_grid_columns_rows": [ + 149, + 10 + ], + "restored_grid_columns_rows": [ + 111, + 7 + ], + "identity_scope": "fresh-parser-relative-ids-no-injected-ci-offset" + }, + "execution_scope": { + "configure_count": 1, + "build_count": 1, + "fixed_batch_count": 1, + "case_attempts_each": 1, + "cut_scans": 0, + "retries": 0, + "ctest_registered": false, + "qt_or_win32_ui_executed": false, + "conpty_or_original_executed": false + }, + "build_identity": { + "configuration": "Release", + "generator": "Visual Studio 17 2022", + "architecture": "x64", + "vctools_version": "14.42.34433", + "compiler": { + "name": "cl.exe", + "version": "19.42.34433.0", + "bytes": 862832, + "sha256": "42fd88579adc0e2418a0a71ec9adcfcf677d39ff2724c9d6ac9d901264812bf2" + }, + "cmake": { + "name": "cmake.exe", + "version": "3.31.0", + "bytes": 12054480, + "sha256": "c52712b2e10098baa2bd9b2fb22b6bb276c8ec46d840f0e8487eda7f76a1727b" + }, + "supervisor_python": { + "name": "python.exe", + "bytes": 274424, + "sha256": "0b471133e110cfb53a061cad528ce8e517d7b9ac41a0a396c39ad795a487fc14", + "reported_runtime_version": "3.12.10", + "recorded_executable_role": "venv-launcher", + "underlying_runtime_executable_identity": null + }, + "observed_compile_switches": [ + "/O2", + "/Ob2", + "/MD", + "/std:c++17", + "/W4", + "/utf-8", + "/EHsc", + "/GS" + ], + "complete_flags_retained_locally": true, + "compiler_command_tlog": { + "bytes": 1080, + "sha256": "1f3c522aed0fc422476686e563dcc46a25436fc0bd08fa6f0d39810dadff4f45" + }, + "executable": { + "name": "resize_repaint_witness.exe", + "bytes": 112128, + "sha256": "3fdd9172e955a468fc9db7a540dcc5042156cde2aafa8e0bee1786cb6f0189c4" + }, + "warnings": 0, + "errors": 0 + }, + "cases": [ + { + "case": "A", + "fourth_prefix_bytes": 231, + "cut_global_offset": 861, + "status": "selection_retained", + "checkpoint_count": 12, + "initial_copy_bytes": 2499, + "final_copy_bytes": 2499, + "first_invalidation_sequence": null, + "final_history_rows": 75, + "final_document_rows": 82, + "relative_final_tail_ids": [ + 76, + 77, + 78, + 79, + 80, + 81, + 82 + ], + "final_tail_versions": [ + 160, + 160, + 160, + 160, + 160, + 118, + 11 + ], + "existing_identity_text_digest_changes": [], + "cut_checkpoints": [ + { + "stage": "fourth-redraw-prefix", + "sequence": 9, + "transport_consumed_bytes": 861, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 85, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "restore-grid-at-declared-cut", + "sequence": 10, + "transport_consumed_bytes": 861, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 82, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "complete-fifth-redraw", + "sequence": 11, + "transport_consumed_bytes": 1071, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 82, + "copy_bytes": 2499, + "copy_status": "ok" + } + ] + }, + { + "case": "B", + "fourth_prefix_bytes": 204, + "cut_global_offset": 834, + "status": "observed_bad_state", + "checkpoint_count": 13, + "initial_copy_bytes": 2499, + "final_copy_bytes": 0, + "first_invalidation_sequence": 12, + "final_history_rows": 78, + "final_document_rows": 85, + "relative_final_tail_ids": [ + 79, + 80, + 81, + 82, + 86, + 87, + 88 + ], + "final_tail_versions": [ + 160, + 160, + 125, + 36, + 29, + 22, + 3 + ], + "existing_identity_text_digest_changes": [ + { + "index": 78, + "id": 79, + "version": 160, + "text_digest_changed": true, + "span_digest_changed": false + }, + { + "index": 79, + "id": 80, + "version": 160, + "text_digest_changed": true, + "span_digest_changed": false + }, + { + "index": 80, + "id": 81, + "version": 125, + "text_digest_changed": true, + "span_digest_changed": true + }, + { + "index": 81, + "id": 82, + "version": 36, + "text_digest_changed": true, + "span_digest_changed": true + } + ], + "cut_checkpoints": [ + { + "stage": "fourth-redraw-prefix", + "sequence": 9, + "transport_consumed_bytes": 834, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 85, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "restore-grid-at-declared-cut", + "sequence": 10, + "transport_consumed_bytes": 834, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 82, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "fourth-redraw-original-tail", + "sequence": 11, + "transport_consumed_bytes": 861, + "cursor_row": 6, + "history_rows": 78, + "document_rows": 85, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "complete-fifth-redraw", + "sequence": 12, + "transport_consumed_bytes": 1071, + "cursor_row": 6, + "history_rows": 78, + "document_rows": 85, + "copy_bytes": 0, + "copy_status": "invalidated" + } + ] + }, + { + "case": "C", + "fourth_prefix_bytes": 225, + "cut_global_offset": 855, + "status": "selection_retained", + "checkpoint_count": 13, + "initial_copy_bytes": 2499, + "final_copy_bytes": 2499, + "first_invalidation_sequence": null, + "final_history_rows": 75, + "final_document_rows": 82, + "relative_final_tail_ids": [ + 76, + 77, + 78, + 79, + 80, + 81, + 82 + ], + "final_tail_versions": [ + 160, + 160, + 160, + 160, + 160, + 118, + 11 + ], + "existing_identity_text_digest_changes": [], + "cut_checkpoints": [ + { + "stage": "fourth-redraw-prefix", + "sequence": 9, + "transport_consumed_bytes": 855, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 85, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "restore-grid-at-declared-cut", + "sequence": 10, + "transport_consumed_bytes": 855, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 82, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "fourth-redraw-original-tail", + "sequence": 11, + "transport_consumed_bytes": 861, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 82, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "complete-fifth-redraw", + "sequence": 12, + "transport_consumed_bytes": 1071, + "cursor_row": 6, + "history_rows": 75, + "document_rows": 82, + "copy_bytes": 2499, + "copy_status": "ok" + } + ] + }, + { + "case": "D", + "fourth_prefix_bytes": 219, + "cut_global_offset": 849, + "status": "observed_bad_state", + "checkpoint_count": 13, + "initial_copy_bytes": 2499, + "final_copy_bytes": 0, + "first_invalidation_sequence": 12, + "final_history_rows": 78, + "final_document_rows": 85, + "relative_final_tail_ids": [ + 79, + 80, + 81, + 82, + 83, + 84, + 85 + ], + "final_tail_versions": [ + 160, + 160, + 125, + 36, + 30, + 23, + 4 + ], + "existing_identity_text_digest_changes": [ + { + "index": 78, + "id": 79, + "version": 160, + "text_digest_changed": true, + "span_digest_changed": false + }, + { + "index": 79, + "id": 80, + "version": 160, + "text_digest_changed": true, + "span_digest_changed": false + }, + { + "index": 80, + "id": 81, + "version": 125, + "text_digest_changed": true, + "span_digest_changed": true + }, + { + "index": 81, + "id": 82, + "version": 36, + "text_digest_changed": true, + "span_digest_changed": true + } + ], + "cut_checkpoints": [ + { + "stage": "fourth-redraw-prefix", + "sequence": 9, + "transport_consumed_bytes": 849, + "cursor_row": 9, + "history_rows": 75, + "document_rows": 85, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "restore-grid-at-declared-cut", + "sequence": 10, + "transport_consumed_bytes": 849, + "cursor_row": 6, + "history_rows": 78, + "document_rows": 85, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "fourth-redraw-original-tail", + "sequence": 11, + "transport_consumed_bytes": 861, + "cursor_row": 6, + "history_rows": 78, + "document_rows": 85, + "copy_bytes": 2499, + "copy_status": "ok" + }, + { + "stage": "complete-fifth-redraw", + "sequence": 12, + "transport_consumed_bytes": 1071, + "cursor_row": 6, + "history_rows": 78, + "document_rows": 85, + "copy_bytes": 0, + "copy_status": "invalidated" + } + ] + } + ], + "recording": { + "jsonl_records": 61, + "checkpoints": 51, + "row_span_summary": "decimal-fnv1a64-comparison-aid", + "identity_hash": "sha256", + "stdout": { + "bytes": 817861, + "sha256": "ee89e36c05db592741a3c2700bd3bc944f7cf0f2600fbe47a680781fec4cb634" + }, + "stderr": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "local_analysis": { + "bytes": 11691, + "sha256": "cfe9bfecb6664636d3d8ec3ce03f9e9a1ceef5bea2a28165ef756d5217321f39" + }, + "all_raw_retained_locally": true, + "raw_included_in_git": false + }, + "supervision": { + "stages": [ + { + "stage": "configure", + "returncode": 0, + "timed_out": false, + "output_overflow": false, + "root_reaped": true, + "root_handle_closed": true, + "pre_go_job": { + "active": 1, + "total": 1, + "terminated": 0 + }, + "job_after_wrapper_reaped": { + "active": 0, + "total": 30, + "terminated": 0 + }, + "job_termination_requests": 0, + "job_before_handle_close": { + "active": 0, + "total": 30, + "terminated": 0 + }, + "stdout": { + "bytes": 597, + "sha256": "78c382c011f60f875a7d959625a250f09df294ca05e6d254828091dcec4719fb" + }, + "stderr": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + { + "stage": "build", + "returncode": 0, + "timed_out": false, + "output_overflow": false, + "root_reaped": true, + "root_handle_closed": true, + "pre_go_job": { + "active": 1, + "total": 1, + "terminated": 0 + }, + "job_after_wrapper_reaped": { + "active": 0, + "total": 20, + "terminated": 0 + }, + "job_termination_requests": 0, + "job_before_handle_close": { + "active": 0, + "total": 20, + "terminated": 0 + }, + "stdout": { + "bytes": 4532, + "sha256": "4a85b850861430b63743bf122dcf7576644e1ad1f1e028bef77dd0bd78c48444" + }, + "stderr": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + { + "stage": "witness", + "returncode": 0, + "timed_out": false, + "output_overflow": false, + "root_reaped": true, + "root_handle_closed": true, + "pre_go_job": { + "active": 1, + "total": 1, + "terminated": 0 + }, + "job_after_wrapper_reaped": { + "active": 1, + "total": 5, + "terminated": 0 + }, + "job_termination_requests": 1, + "job_before_handle_close": { + "active": 0, + "total": 5, + "terminated": 0 + }, + "stdout": { + "bytes": 817861, + "sha256": "ee89e36c05db592741a3c2700bd3bc944f7cf0f2600fbe47a680781fec4cb634" + }, + "stderr": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + } + ], + "witness_job_after_termination_request": { + "active": 0, + "total": 5, + "terminated": 0 + }, + "witness_remaining_member_identity": null, + "remaining_member_process_handles_retained": false, + "all_descendants_natural_exit_proven": false, + "termination_counter_zero_is_natural_exit_proof": false, + "process_guard_seconds": 10, + "cleanup_seconds_shared_per_stage": 5, + "stdout_bytes_max": 2097152, + "stderr_bytes_max": 65536, + "performance_claim": false + }, + "post_audit": { + "source_input_archive_compiler_flags_executable_changes": 0, + "raw_artifact_changes": 0, + "preparation_and_execution_plan_changes": 0, + "production_source_changes": 0 + }, + "limitations": { + "ci_stage_parser_offsets_missing": true, + "ci_stage_parser_cursor_missing": true, + "ci_absolute_initial_id_gaps_reproduced": false, + "similar_tail_versions_establish_cause": false, + "render_or_child_ack_observed": false, + "qt_product_acceptance": false, + "windterm_equivalence": false, + "performance_acceptance": false + } +} From bf569516ced888f0e6809231326c0dd8fe5e4a83 Mon Sep 17 00:00:00 2001 From: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com> Date: Thu, 29 Oct 2026 07:23:29 +0800 Subject: [PATCH 3/4] diagnostics: flush final witness summary before checking output --- experiments/core/resize_repaint_witness.cpp | 1 + .../shell/results/2026-10-29-resize-repaint-witness/README.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/experiments/core/resize_repaint_witness.cpp b/experiments/core/resize_repaint_witness.cpp index ce3b3f1a..e46edfd5 100644 --- a/experiments/core/resize_repaint_witness.cpp +++ b/experiments/core/resize_repaint_witness.cpp @@ -218,6 +218,7 @@ int main(int argc, char** argv) { << completed << ",\"observed_bad_states\":" << bad_states << ",\"checkpoints\":" << checkpoints << ",\"semantic_acceptance\":false,\"ci_cause_established\":false,\"cli_zero_means\":\"four declared cases recorded\"}\n"; + std::cout.flush(); require(bool(std::cout), "diagnostic output write failed"); return 0; } catch (const std::exception& error) { diff --git a/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md b/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md index 6a4f5867..62af2151 100644 --- a/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md +++ b/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md @@ -4,6 +4,8 @@ [执行前合同](../../../../docs/research/resize-repaint-witness-plan.md)、[诊断源码](../../../core/resize_repaint_witness.cpp)与[脱敏验证](validation.json)分别保留计划、实现和实际结果。准备提交与执行提交同为 `178faba`;本报告是后续文档发布,不充当运行源。原 false plan、授权执行 plan、原 CI artifact、全部编译/运行/分析 raw 均保留本地,不随报告上传。 +后续诊断源码补充了最终summary的stdout显式flush后再检查失败状态的守卫;旧唯一四-case执行仍绑定`178faba`及其61条完整记录,新守卫未重跑witness,不能转记为该运行源。 + ## 固定输入与一次结果 诊断基于实际失败源 `58fee2805cde34c67683a79473ca56f9df3cbf69`,原八个相关文件与比较源 `6a10e5322a1bddeb038670e50f32ff6deac145cf` 的 blob 相同。没有运行 Win32/Qt UI、ConPTY 或原版。使用现有 recovery Parser、TextDocument、TextSelection 的公开边界,以原合成 fixture 函数生成 `TF_FIND_000..079` 和 READY 行;111×7、history capacity100时实际得到 history75/document82,并按真实 Select All 范围规则复制2499B。行 ID 由新 Parser 自然分配,不补造 CI 启动前的绝对偏移。 From 6f23b66db78744ece209adf0eeb393740a622d29 Mon Sep 17 00:00:00 2001 From: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com> Date: Thu, 29 Oct 2026 07:28:13 +0800 Subject: [PATCH 4/4] docs: preserve compile-only identity for witness output guard --- .../README.md | 2 + .../build-only-validation.json | 193 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 experiments/shell/results/2026-10-29-resize-repaint-witness/build-only-validation.json diff --git a/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md b/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md index 62af2151..1a5ebdcd 100644 --- a/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md +++ b/experiments/shell/results/2026-10-29-resize-repaint-witness/README.md @@ -6,6 +6,8 @@ 后续诊断源码补充了最终summary的stdout显式flush后再检查失败状态的守卫;旧唯一四-case执行仍绑定`178faba`及其61条完整记录,新守卫未重跑witness,不能转记为该运行源。 +该守卫的独立[仅编译记录](build-only-validation.json)绑定`bf569516ced888f0e6809231326c0dd8fe5e4a83`:全新目录一次configure/build成功、0 warning/error,没有执行新EXE或写出失败注入;旧EXE、原验证与raw未覆盖。 + ## 固定输入与一次结果 诊断基于实际失败源 `58fee2805cde34c67683a79473ca56f9df3cbf69`,原八个相关文件与比较源 `6a10e5322a1bddeb038670e50f32ff6deac145cf` 的 blob 相同。没有运行 Win32/Qt UI、ConPTY 或原版。使用现有 recovery Parser、TextDocument、TextSelection 的公开边界,以原合成 fixture 函数生成 `TF_FIND_000..079` 和 READY 行;111×7、history capacity100时实际得到 history75/document82,并按真实 Select All 范围规则复制2499B。行 ID 由新 Parser 自然分配,不补造 CI 启动前的绝对偏移。 diff --git a/experiments/shell/results/2026-10-29-resize-repaint-witness/build-only-validation.json b/experiments/shell/results/2026-10-29-resize-repaint-witness/build-only-validation.json new file mode 100644 index 00000000..af57ebec --- /dev/null +++ b/experiments/shell/results/2026-10-29-resize-repaint-witness/build-only-validation.json @@ -0,0 +1,193 @@ +{ + "schema": "termforge-resize-repaint-flush-build-only-validation-v1", + "issue": 156, + "kind": "compile-only-output-guard-fix", + "compile_source_commit": "bf569516ced888f0e6809231326c0dd8fe5e4a83", + "previous_publication_commit": "8294802af81212545def9f076d990f81294bc884", + "guard_change": "explicit-final-stdout-flush-before-stream-state-check", + "diagnostic_source": { + "path": "experiments/core/resize_repaint_witness.cpp", + "git_blob": "e46edfd5984ee578e5cf4293c464321f736a0dd2", + "bytes": 13110, + "sha256": "8066db7dd8a3b1243e2eecfdf89dfbc9a3179b143570aa09d224c70d35a3ee33" + }, + "plan": { + "bytes": 6664, + "sha256": "7edc6b13b53f4f02b64b61f7740f3159a948c693ca495431856ea784bd5bb0e8", + "execution_authorized": true, + "allowed_stages": [ + "configure", + "build" + ], + "witness_runs_permitted": 0 + }, + "execution_counts": { + "configure": 1, + "build": 1, + "witness": 0, + "four_case_batches": 0, + "ctest": 0, + "output_failure_injections": 0, + "cut_scans": 0, + "retries": 0 + }, + "build": { + "result": "compiled", + "warnings": 0, + "errors": 0, + "generator": "Visual Studio 17 2022", + "architecture": "x64", + "configuration": "Release", + "vctools_version": "14.42.34433", + "target": "resize_repaint_witness", + "exclude_from_all": true, + "build_testing": false, + "qt_shell": false, + "candidate_adapter": false, + "compiler": { + "name": "cl.exe", + "version": "19.42.34433.0", + "bytes": 862832, + "sha256": "42fd88579adc0e2418a0a71ec9adcfcf677d39ff2724c9d6ac9d901264812bf2" + }, + "cmake": { + "name": "cmake.exe", + "version": "3.31.0", + "bytes": 12054480, + "sha256": "c52712b2e10098baa2bd9b2fb22b6bb276c8ec46d840f0e8487eda7f76a1727b" + }, + "observed_compile_switches": [ + "/O2", + "/Ob2", + "/MD", + "/std:c++17", + "/W4", + "/utf-8", + "/EHsc", + "/GS" + ], + "complete_flags_retained_locally": true, + "compiler_command_tlog": { + "bytes": 1080, + "sha256": "1f3c522aed0fc422476686e563dcc46a25436fc0bd08fa6f0d39810dadff4f45" + }, + "executable": { + "name": "resize_repaint_witness.exe", + "bytes": 112128, + "sha256": "3980f04e32efbf875daeeb5b9fc5c331eb8fd057e69a18e7986258da9acaa014", + "executed": false + }, + "private_compile_result": { + "bytes": 9589, + "sha256": "1fe2e09fdc627b61058ac367d87a856823b335e77ca3e4baeec292bc0f9f87ef" + } + }, + "supervision": { + "configure_timeout_seconds": 60, + "build_timeout_seconds": 120, + "cleanup_shared_seconds_per_stage": 5, + "stages": [ + { + "stage": "configure", + "returncode": 0, + "timed_out": false, + "output_overflow": false, + "root_reaped": true, + "root_handle_closed": true, + "pre_go_job": { + "active": 1, + "total": 1, + "terminated": 0 + }, + "job_after_wrapper_reaped": { + "active": 0, + "total": 30, + "terminated": 0 + }, + "job_before_handle_close": { + "active": 0, + "total": 30, + "terminated": 0 + }, + "job_termination_requests": 0, + "stdout": { + "bytes": 603, + "sha256": "51b54f655fc012955e8deee257f97c64af15a4eb2b29d71919691dc07bcecd23" + }, + "stderr": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + { + "stage": "build", + "returncode": 0, + "timed_out": false, + "output_overflow": false, + "root_reaped": true, + "root_handle_closed": true, + "pre_go_job": { + "active": 1, + "total": 1, + "terminated": 0 + }, + "job_after_wrapper_reaped": { + "active": 0, + "total": 20, + "terminated": 0 + }, + "job_before_handle_close": { + "active": 0, + "total": 20, + "terminated": 0 + }, + "job_termination_requests": 0, + "stdout": { + "bytes": 4598, + "sha256": "bcb841d6664694ba6900f41608f0689d1528ae5ef39f8328bd7afbb421e256d9" + }, + "stderr": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + } + ] + }, + "old_four_case_evidence": { + "execution_source_commit": "178faba6c245298a1410d6954b6a7e1df1e9bbd7", + "jsonl_records": 61, + "checkpoints": 51, + "stdout": { + "bytes": 817861, + "sha256": "ee89e36c05db592741a3c2700bd3bc944f7cf0f2600fbe47a680781fec4cb634" + }, + "analysis": { + "bytes": 11691, + "sha256": "cfe9bfecb6664636d3d8ec3ce03f9e9a1ceef5bea2a28165ef756d5217321f39" + }, + "original_executable": { + "bytes": 112128, + "sha256": "3fdd9172e955a468fc9db7a540dcc5042156cde2aafa8e0bee1786cb6f0189c4" + }, + "original_public_validation": { + "bytes": 21023, + "sha256": "bd842024d69b3f4ebb6423f51668ee98aa57992c556289ec23ef5b84e76e2e24" + }, + "preserved_old_artifact_count": 20, + "old_plans_input_archive_exe_raw_analysis_unchanged": true, + "old_source_git_blob_retained": true, + "new_guard_not_attributed_to_old_run": true + }, + "post_audit": { + "new_compile_source_files_rechecked": 15, + "source_tools_and_retained_old_artifact_changes": 0 + }, + "witness_executed": false, + "output_failure_path_exercised": false, + "semantic_acceptance": false, + "ci_cause_established": false, + "ci_actual_cut_known": false, + "production_fix_implemented": false, + "all_raw_retained_locally": true, + "private_paths_pids_exception_strings_published": false +}