From f734d29bc4f8a120eac59da3acac3169d49231b2 Mon Sep 17 00:00:00 2001 From: JavaZero <71128095+JavaZeroo@users.noreply.github.com> Date: Tue, 27 Oct 2026 18:44:42 +0800 Subject: [PATCH 1/2] perf: run frozen R54 costs in an audited hosted Windows job (#54) --- .github/workflows/r54-cost.yml | 53 +++++++ CMakeLists.txt | 2 +- experiments/measure/R54-COST.md | 2 + experiments/measure/R54-HOSTED.md | 36 +++++ experiments/measure/r54_build.py | 196 +++++++++++++++++++++++++ experiments/measure/r54_hosted.py | 70 +++++++++ experiments/measure/r54_publish.py | 148 +++++++++++++++++++ experiments/measure/test_r54_hosted.py | 87 +++++++++++ 8 files changed, 593 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/r54-cost.yml create mode 100644 experiments/measure/R54-HOSTED.md create mode 100644 experiments/measure/r54_build.py create mode 100644 experiments/measure/r54_hosted.py create mode 100644 experiments/measure/r54_publish.py create mode 100644 experiments/measure/test_r54_hosted.py diff --git a/.github/workflows/r54-cost.yml b/.github/workflows/r54-cost.yml new file mode 100644 index 00000000..023fdf31 --- /dev/null +++ b/.github/workflows/r54-cost.yml @@ -0,0 +1,53 @@ +name: Frozen R54 hosted cost batches + +on: + push: + branches: ['perf/grapheme-hosted-r54'] + paths: + - '.github/workflows/r54-cost.yml' + - 'experiments/measure/*.py' + - 'experiments/candidates/alacritty/Cargo.toml' + - 'experiments/candidates/alacritty/src/measure.rs' + +permissions: + contents: read + +concurrency: + group: r54-cost-${{ github.ref }} + cancel-in-progress: false + +jobs: + fixed-cost: + runs-on: windows-2025 + timeout-minutes: 30 + env: + PYTHONUTF8: '1' + CARGO_HOME: ${{ github.workspace }}/local/r54-cargo-home + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 + with: + python-version: '3.12' + - name: Install fixed host observer + run: python -m pip install -r benchmarks/requirements.txt + - name: Select fixed compiler + run: rustup default 1.92.0 + - name: Verify runner and publication contracts before measurement + run: python -m unittest experiments.measure.test_r54_contract.CostPlanTests experiments.measure.test_r54_batch experiments.measure.test_r54_hosted -v + - name: Build audited pair and execute the two frozen batches + id: measure + run: python -m experiments.measure.r54_hosted --out local/r54-raw + - name: Prepare the reviewed synthetic artifact whitelist + if: always() && steps.measure.outcome != 'skipped' + run: python -m experiments.measure.r54_publish --raw local/r54-raw --out local/r54-public + - name: Preserve complete or failed synthetic evidence + if: always() && steps.measure.outcome != 'skipped' + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: r54-cost-${{ github.run_id }}-${{ github.run_attempt }} + retention-days: 30 + if-no-files-found: error + path: local/r54-public/ diff --git a/CMakeLists.txt b/CMakeLists.txt index c6a2ffbf..5825ca6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,7 +292,7 @@ if(BUILD_TESTING) endif() termforge_add_python_test(core -m unittest experiments.core.test_core experiments.core.test_unicode -v) termforge_add_python_test(recovery -m unittest experiments.core.test_recovery -v) - termforge_add_python_test(measure -m unittest experiments.measure.test_measure experiments.measure.test_r54_contract.CostPlanTests experiments.measure.test_r54_batch -v) + termforge_add_python_test(measure -m unittest experiments.measure.test_measure experiments.measure.test_r54_contract.CostPlanTests experiments.measure.test_r54_batch experiments.measure.test_r54_hosted -v) termforge_add_python_test(binary_paths -m unittest experiments.test_build_paths -v) termforge_add_python_test(conpty_margin_contract -m unittest experiments.conpty.test_margin_contract -v) termforge_add_python_test(benchmark_tools -m unittest discover -s benchmarks/tests -v) diff --git a/experiments/measure/R54-COST.md b/experiments/measure/R54-COST.md index fe49fa22..d9abf9f2 100644 --- a/experiments/measure/R54-COST.md +++ b/experiments/measure/R54-COST.md @@ -93,3 +93,5 @@ Windows 1–64 逻辑 CPU 上使用 [GetSystemTimes](https://learn.microsoft.com 全部 112 个位置完整有效后才生成统计;缺失、重复、乱序或失败不能得到成功摘要。摘要逐批、逐 route/chunk 列出七个配对 CPU ns/B 比值,以及各源 CPU/墙钟 ns/B 全部值、中位数、范围和 MAD。合成进程测试覆盖整个顺序、原始字节和停止规则,其虚构时长只验证统计与进程协议,绝不作为性能样本。 实际受控重复样本、allocator/projection 扰动归因、预算提案和优化验收仍由 #54 接续;构建、短 sanity、执行器测试或环境预检均不关闭该 issue。 + +独立 Windows 虚拟机上的来源构建、顺序执行、白名单产物和宿主限制见 [R54 hosted 流程](R54-HOSTED.md)。该入口复用本合同,不把CI可运行或环境预检通过解释为产品性能验收。 diff --git a/experiments/measure/R54-HOSTED.md b/experiments/measure/R54-HOSTED.md new file mode 100644 index 00000000..90b7fd72 --- /dev/null +++ b/experiments/measure/R54-HOSTED.md @@ -0,0 +1,36 @@ +# R54:独立 Windows 虚拟机上的固定批次 + +本流程接续 [#54](https://github.com/JavaZeroo/termforge/issues/54) 和 [v1 合同](R54-COST.md),不改变源码、负载、两批各112个位置、计时端点、统计或预算。主工作站已有一次活动预检拒绝;不在同一宿主循环等绿,改在一个新的 GitHub-hosted `windows-2025` 虚拟机上建立完整来源和环境记录。它是本次 headless 核心成本研究的环境,不代替 Windows 11 x64 产品或 WindTerm 性能验收。 + +## 运行与停止 + +[工作流](../../.github/workflows/r54-cost.yml)只在实验分支 `perf/grapheme-hosted-r54` 的执行相关源码变化时启动,不在 PR 事件上重复触发,也不改变 main 的默认构建。每次工作流用独立 run ID、attempt、源码和输出目录;拒绝对旧 workflow run 的 attempt 2 及后续重跑。新的源码修订保留旧失败,并构成另一个明确身份,不替代已取得的样本。 + +同一虚拟机依次完成固定 Python/Rust、纯合同测试、两份来源构建、四次短正确性检查,再运行原两个种子。构建和测试结束后才开始成本预检与计时。没有自动恢复、补样、重试或放宽5%环境诊断护栏的入口;第一批失败即保留当前位置,第二批不启动。两批成功也只写 `complete_diagnostic`,`performance_gate=not_evaluated`。 + +同一任务的新 `CARGO_HOME` 用于获取锁定依赖;两个编译目标目录独立。脚本拒绝未知编译环境覆盖与 Cargo 配置文件,只覆盖原 `.3/.4` 的 Cargo.toml/src/measure.rs。每份仍使用 Rust1.92.0、MSVC x64、Release、locked/offline、no-default-features和jobs=1。完整源码前后哈希、真实命令/日志、实际linker及EXE、编译模式和四次原状态摘要由 [builder](r54_build.py) 留证;由原 [输入校验器](r54_inputs.py)重新读取验证之后才进入测量。 + +构建/准备调用各有期限,构建为600秒、短正确性调用为10秒;这些不是产品性能门槛。构建超时终止直接子进程并阻止全部测量,不据此声称已回收其派生进程;虚拟机生命周期由CI提供者管理。实际成本仍使用原内部60秒/子进程90秒期限,整个job30分钟。正常构建返回后才允许成本入口,不能将超时残留视作空闲。 + +## 宿主限制 + +保留 GitHub事件、run ID/attempt、实际提交、runner类型、系统映像、OS build/UBR、CPU与电源策略。固定两个种子的同口径结果分别报告,不混入主工作站原构建或历史12样本。`hosted_identity` 只检查该流程需要的元数据;分析时还须从GitHub作业记录核对实际runner与源码身份,环境变量本身不是物理隔离证明。 + +GitHub runner服务、操作系统后台任务、虚拟机邻居、物理CPU频率和调度仍可能影响结果。原5%筛选只描述guest可观察CPU活动;它不是用户确认的数值性能容差,也不证明物理宿主独占。出现噪声、失败或两批不一致时保留全部观察,再提出下一项可检验的调查。 + +## 发布边界 + +[发布器](r54_publish.py)只接受本流程的真实GitHub-hosted首次作业,并使用固定文件白名单。它不递归上传工作目录、checkout、编译缓存或个人文件。仅保存本次公开源码/合成输入产生的结果;完整进程名称/PID记录与未知环境字段不导出,工作区、runner profile和临时路径前缀改为别名。没有读取完整进程命令行或任意环境变量的步骤。 + +两个核心的成本及短正确性 stdout/stderr 按原字节保留,包括失败或无效编码;其生产者只接收公开固定合成负载。完整构建日志保留内容并替换宿主路径前缀。JSON/JSONL记录只做上述元数据筛选和路径处理,不改变时间、工作量、状态摘要、顺序或失败状态。中断留下的JSONL半行不修补、不删除,保留全部行和解析失败位置,独立样本原始流仍导出。`publication.json`列出每份原文件和发布文件的SHA、大小及处理方式。导出前核对原始 `hosted.json` 的run ID/attempt/SHA;空目录或另一次作业不生成成功包。发布目录在所有文件完成后才生效,上传仅指向该目录;未通过检查的半成品目录不会上传。 + +原始完整进程身份只在临时虚拟机内保留,公开结果保留全机CPU原计数、全部成本原始流及其来源。不能用未导出的逐进程字段做外部归因声明;后续若需要这种归因,另行预声明可公开的受控观测。所有CI结果须下载复核其清单、原始样本和统计后才能写入 #54 的成本结论。 + +## 手动入口(只供同一受控作业) + +```powershell +python -m experiments.measure.r54_hosted --out local/r54-raw +python -m experiments.measure.r54_publish --raw local/r54-raw --out local/r54-public +``` + +本机不得伪造GitHub环境变量运行该流程。普通本地准备可使用 `r54_build --out <新目录>`,要求实际Windows、已提交的干净源码及显式任务缓存;本轮不重复已有主工作站成本预检。测试只验证既有构建输入/产物边界,正式成本样本来自上述实际作业。 diff --git a/experiments/measure/r54_build.py b/experiments/measure/r54_build.py new file mode 100644 index 00000000..21fc4c8f --- /dev/null +++ b/experiments/measure/r54_build.py @@ -0,0 +1,196 @@ +"""Create the audited R54 Windows build bundle before any cost measurements.""" +import argparse +import json +import os +from pathlib import Path +import re +import subprocess + +from experiments.measure.r54_batch import capture, sha, utc, write_json +from experiments.measure.r54_contract import ROOT, SOURCES, expected_sample, prepare +from experiments.measure.r54_inputs import IDENTITY, OVERLAYS, git, load_builds, require +from experiments.measure.run import validate_result + +OVERRIDES = ('RUSTFLAGS', 'CARGO_ENCODED_RUSTFLAGS', 'CARGO_BUILD_TARGET', 'CARGO_BUILD_RUSTFLAGS', + 'CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS', 'CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER', + 'RUSTC', 'RUSTC_WRAPPER', 'RUSTC_WORKSPACE_WRAPPER') +RECORDED_ENVIRONMENT = OVERRIDES + ('CARGO_HOME', 'RUSTUP_HOME', 'RUSTUP_TOOLCHAIN', 'CARGO_TERM_COLOR', 'LIB', 'INCLUDE') + + +def run_logged(command, directory, prefix, *, cwd=ROOT, environment=None, timeout=300): + """Build/setup logs are byte-exact; failure prevents entering the cost runner.""" + result = dict(command=command, started_utc=utc(), exit_code=None, timed_out=False) + stdout, stderr = directory / (prefix + '.stdout'), directory / (prefix + '.stderr') + try: + with stdout.open('xb') as output, stderr.open('xb') as error: + try: + process = subprocess.run(command, cwd=cwd, env=environment, stdin=subprocess.DEVNULL, + stdout=output, stderr=error, timeout=timeout) + result['exit_code'] = process.returncode + except subprocess.TimeoutExpired: + result.update(timed_out=True, error='build/setup direct-child timeout; no process-tree cleanup claim') + require(result['exit_code'] == 0, f'{prefix} failed; preserve logs, no automatic retry') + except BaseException as error: + result['error'] = f'{type(error).__name__}: {error}' + raise + finally: + result['finished_utc'] = utc() + result['logs'] = {path.name: dict(bytes=path.stat().st_size, sha256=sha(path)) + for path in (stdout, stderr) if path.exists()} + write_json(directory / (prefix + '.process.json'), result) + return result + + +def reject_hidden_configuration(checkout, environment): + # Cargo searches the working directory's ancestors and CARGO_HOME. A clean, + # explicit cache prevents inherited config from changing the fixed flags. + cargo_home = environment.get('CARGO_HOME') + require(bool(cargo_home), 'CARGO_HOME must name an explicit task-owned cache') + locations = [checkout, *checkout.parents, Path(cargo_home)] + for location in locations: + config_dir = location if location == Path(cargo_home) else location / '.cargo' + require(not any((config_dir / name).exists() for name in ('config', 'config.toml')), + 'unreviewed Cargo configuration file') + + +def prepare_builds(output): + output = Path(output).resolve() + output.mkdir(parents=True, exist_ok=False) + status = dict(schema='termforge-r54-build-preparation-v1', status='preparing', started_utc=utc(), + source=git(ROOT, 'rev-parse', 'HEAD'), runner_sha256=sha(Path(__file__)), + formal_cost_samples=0, performance_gate='not_evaluated') + write_json(output / 'preparation.json', status) + try: + environment = {name: os.environ.get(name) for name in RECORDED_ENVIRONMENT} + for name in OVERRIDES: + require(environment[name] in (None, ''), f'unreviewed compiler override: {name}') + for name, value in os.environ.items(): + if value and name.startswith(('CARGO_', 'RUST')) and name not in RECORDED_ENVIRONMENT: + raise ValueError(f'unreviewed compiler environment name: {name}') + require(os.name == 'nt', 'the frozen build pair targets Windows x64') + require(not git(ROOT, 'status', '--porcelain'), 'prepare from a committed, clean source tree') + frozen = prepare(output / 'plan-v1.json') + builds = {} + for variant, source in SOURCES.items(): + checkout = output / ('source-' + variant) + run_logged(['git', 'worktree', 'add', '--detach', str(checkout), source['commit']], + output, variant + '-checkout', timeout=60) + require(git(checkout, 'rev-parse', 'HEAD') == source['commit'] and + not git(checkout, 'status', '--porcelain'), 'checkout identity or cleanliness mismatch') + reject_hidden_configuration(checkout, environment) + files = git(checkout, 'ls-files', 'experiments/candidates/alacritty').splitlines() + before = {name: sha(checkout / name) for name in files} + for name in OVERLAYS: + (checkout / name).write_bytes((ROOT / name).read_bytes()) + after = {name: sha(checkout / name) for name in files} + changed = git(checkout, 'diff', '--name-only').splitlines() + require(set(changed) == set(OVERLAYS), 'unexpected source changes during overlay') + require(all(before[name] == after[name] for name in files if name not in OVERLAYS), + 'original lockfile, adapter or vendor changed') + patch = output / (variant + '-harness.patch') + patch.write_bytes(subprocess.check_output(['git', 'diff', '--', *OVERLAYS], cwd=checkout, timeout=30)) + target = output / ('target-' + variant + '-unwrapped') + require(not target.exists(), 'target directory already exists') + command = ['cargo', '+1.92.0', 'build', '--manifest-path', + str(checkout / 'experiments/candidates/alacritty/Cargo.toml'), + '--release', '--locked', '--offline', '--no-default-features', '--jobs', '1', + '--bin', 'alacritty-measure', '--target', 'x86_64-pc-windows-msvc', + '--target-dir', str(target), '-vv'] + builds[variant] = dict(commit=source['commit'], tree=git(checkout, 'rev-parse', 'HEAD^{tree}'), + candidate_tree=git(checkout, 'rev-parse', 'HEAD:experiments/candidates/alacritty'), + version=source['version'], overlay_files=list(OVERLAYS), changed_paths=changed, + before_files=before, after_files=after, overlay_patch_sha256=sha(patch), + command=command, target_dir=str(target), status='not_built') + plan = dict(schema='termforge-r54-local-build-plan-v1', harness_source=status['source'], + protocol_sha256=frozen['protocol_sha256'], frozen_plan=dict(sha256=sha(output / 'plan-v1.json')), + rustc_vv=subprocess.check_output(['rustc', '+1.92.0', '-Vv'], timeout=30).decode('utf-8'), + cargo_vv=subprocess.check_output(['cargo', '+1.92.0', '-Vv'], timeout=30).decode('utf-8'), + environment=environment, additional_build_environment={'RUSTC_LOG': 'rustc_codegen_ssa::back::link=info'}, + builds=builds, formal_samples=0, performance_gate='not_evaluated') + write_json(output / 'build-plan.json', plan) + for variant, spec in builds.items(): + checkout = output / ('source-' + variant) + run_logged(['cargo', '+1.92.0', 'fetch', '--locked', '--manifest-path', + str(checkout / 'experiments/candidates/alacritty/Cargo.toml'), + '--target', 'x86_64-pc-windows-msvc'], output, variant + '-fetch', cwd=checkout) + receipt = dict(variant=variant, build_plan_sha256=sha(output / 'build-plan.json'), + command=spec['command'], status='running', formal_samples=0, performance_gate='not_evaluated') + write_json(output / (variant + '-build.json'), receipt) + try: + require(all(sha(checkout / name) == digest for name, digest in spec['after_files'].items()), + 'fetch changed fixed build inputs') + receipt.update(run_logged(spec['command'], output, variant + '-build', cwd=checkout, + environment=dict(os.environ, **plan['additional_build_environment']), timeout=600)) + require(all(sha(checkout / name) == digest for name, digest in spec['after_files'].items()), + 'build changed fixed inputs') + binary = Path(spec['target_dir']) / 'x86_64-pc-windows-msvc/release/alacritty-measure.exe' + receipt['binary'] = dict(bytes=binary.stat().st_size, sha256=sha(binary)) + run_logged([str(binary), '--identity'], output, variant + '-identity', cwd=checkout, timeout=10) + receipt['identity'] = json.loads((output / (variant + '-identity.stdout')).read_bytes().decode('utf-8')) + require(receipt['identity'] == IDENTITY, 'compiled allocator mode mismatch') + receipt['status'] = 'built_identity_only' + except BaseException as error: + receipt.update(status='failed', error=f'{type(error).__name__}: {error}') + raise + finally: + write_json(output / (variant + '-build.json'), receipt) + audit(output, plan) + load_builds(output / 'plan-v1.json', output) + status['status'] = 'built_and_audited' + except BaseException as error: + status.update(status='failed', error=f'{type(error).__name__}: {error}') + raise + finally: + status['finished_utc'] = utc() + write_json(output / 'preparation.json', status) + return status + + +def audit(output, plan): + import tomllib + rustc = Path(subprocess.check_output(['rustup', 'which', '--toolchain', '1.92.0', 'rustc'], timeout=30).decode('utf-8').strip()) + report = dict(schema='termforge-r54-local-build-audit-v1', builds={}, short_sanity_calls=[], + compiler=dict(sha256=sha(rustc), rustc_vv=plan['rustc_vv']), passed=False, + formal_samples=0, performance_gate='not_evaluated', environment_idle='not_measured') + try: + for variant, spec in plan['builds'].items(): + receipt_path = output / (variant + '-build.json') + receipt = json.loads(receipt_path.read_text(encoding='utf-8')) + checkout = output / ('source-' + variant) + metadata = tomllib.loads((checkout / 'experiments/candidates/alacritty/vendor/alacritty_terminal/Cargo.toml').read_text(encoding='utf-8')) + require(metadata['package']['version'] == SOURCES[variant]['version'], 'vendor version mismatch') + log = (output / (variant + '-build.stderr')).read_text(encoding='utf-8') + names = {json.loads('"' + value + '"') for value in re.findall(r'invoking linker "([^\n]+?)"', log)} + require(len(names) == 1, 'build log must identify one actual linker') + linker = Path(next(iter(names))) + require(linker.name == 'link.exe' and linker.is_file(), 'actual MSVC linker missing') + report['builds'][variant] = dict(source=spec['commit'], version=metadata['package']['version'], + candidate_tree=spec['candidate_tree'], tracked_candidate_files=len(spec['after_files']), + changed_paths=spec['changed_paths'], binary=receipt['binary'], identity=receipt['identity'], + linker=dict(path=str(linker), sha256=sha(linker)), receipt_sha256=sha(receipt_path)) + binary = Path(spec['target_dir']) / 'x86_64-pc-windows-msvc/release/alacritty-measure.exe' + for route in ('project', 'interactive'): + directory = output / f'sanity-{variant}-{route}' + directory.mkdir() + response = capture([str(binary), route, '4096', '0', '0.1'], directory, timeout=10) + report['short_sanity_calls'].append(dict(variant=variant, route=route, passed=False, **response)) + require(response['exit_code'] == 0 and not response['timed_out'], 'short correctness call failed') + result = json.loads((directory / 'stdout.bin').read_bytes().decode('utf-8')) + validate_result(result, .1, expected_sample(dict(variant=variant, route=route, chunk=4096))) + report['short_sanity_calls'][-1]['passed'] = True + require(report['builds']['baseline']['linker'] == report['builds']['candidate']['linker'], 'source pair used different linkers') + report['passed'] = True + finally: + write_json(output / 'build-audit.json', report) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--out', type=Path, required=True) + args = parser.parse_args() + value = prepare_builds(args.out) + print(json.dumps(value)) + + +if __name__ == '__main__': + main() diff --git a/experiments/measure/r54_hosted.py b/experiments/measure/r54_hosted.py new file mode 100644 index 00000000..a59cb725 --- /dev/null +++ b/experiments/measure/r54_hosted.py @@ -0,0 +1,70 @@ +"""One owned GitHub-hosted Windows build followed by the original R54 batches.""" +import argparse +import json +import os +from pathlib import Path + +from experiments.measure.r54_batch import run, sha, utc, write_json +from experiments.measure.r54_build import prepare_builds +from experiments.measure.r54_contract import ROOT, SEEDS +from experiments.measure.r54_inputs import git, require + + +def hosted_identity(): + names = ('GITHUB_ACTIONS', 'RUNNER_ENVIRONMENT', 'RUNNER_OS', 'GITHUB_REPOSITORY', + 'GITHUB_SHA', 'GITHUB_REF', 'GITHUB_RUN_ID', 'GITHUB_RUN_NUMBER', 'GITHUB_RUN_ATTEMPT', + 'GITHUB_EVENT_NAME', 'ImageOS', 'ImageVersion') + identity = {name: os.environ.get(name) for name in names} + require(identity['GITHUB_ACTIONS'] == 'true' and identity['RUNNER_ENVIRONMENT'] == 'github-hosted' and + identity['RUNNER_OS'] == 'Windows' and os.name == 'nt', 'requires an actual GitHub-hosted Windows job') + require(identity['GITHUB_REPOSITORY'] == 'JavaZeroo/termforge' and identity['GITHUB_EVENT_NAME'] == 'push', + 'unexpected repository or event') + require(identity['GITHUB_REF'] == 'refs/heads/perf/grapheme-hosted-r54', 'unexpected experiment branch') + require(identity['GITHUB_RUN_ATTEMPT'] == '1', 'a workflow rerun must not replace the first attempt') + require(identity['GITHUB_SHA'] == git(ROOT, 'rev-parse', 'HEAD'), 'workflow/source identity mismatch') + return identity + + +def execute(output): + output = Path(output).resolve() + require(output.is_relative_to(ROOT / 'local'), 'hosted artifacts must stay under the workspace local directory') + output.mkdir(parents=True, exist_ok=False) + manifest = dict(schema='termforge-r54-hosted-v1', status='preparing', started_utc=utc(), + source=git(ROOT, 'rev-parse', 'HEAD'), runner_sha256=sha(Path(__file__)), + performance_gate='not_evaluated', batches=[]) + try: + manifest['hosted_identity'] = hosted_identity() + write_json(output / 'hosted.json', manifest) + prepare_builds(output / 'bundle') + declaration = dict(host_kind='hosted_vm', no_known_concurrent_build_or_test=True, + known_concurrent_work=['This job completed setup, tests and both builds before measurement.', + 'GitHub runner service and operating-system background services remain.', + 'Physical host scheduling and neighboring virtual machines are unobserved.']) + write_json(output / 'environment-declaration.json', declaration) + for seed in SEEDS: + manifest['status'] = 'running' + manifest['active_seed'] = seed + write_json(output / 'hosted.json', manifest) + result = run(output / 'bundle/plan-v1.json', output / 'bundle', output / 'environment-declaration.json', + output / f'batch-{seed}', seed) + manifest['batches'].append(result) + require(result['status'] == 'complete_diagnostic', f'batch {seed} stopped; remaining seeds not launched') + manifest.update(status='complete_diagnostic', active_seed=None) + except BaseException as error: + manifest.update(status='failed', error=f'{type(error).__name__}: {error}') + raise + finally: + manifest['finished_utc'] = utc() + write_json(output / 'hosted.json', manifest) + return manifest + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--out', type=Path, required=True) + args = parser.parse_args() + print(json.dumps(execute(args.out))) + + +if __name__ == '__main__': + main() diff --git a/experiments/measure/r54_publish.py b/experiments/measure/r54_publish.py new file mode 100644 index 00000000..c239b493 --- /dev/null +++ b/experiments/measure/r54_publish.py @@ -0,0 +1,148 @@ +"""Publish a fixed synthetic-artifact whitelist from the owned hosted job.""" +import argparse +import hashlib +import json +import os +from pathlib import Path +import re + +from experiments.measure.r54_batch import sha, write_json +from experiments.measure.r54_contract import ROOT, SEEDS +from experiments.measure.r54_hosted import hosted_identity +from experiments.measure.r54_inputs import require + + +def public_environment(value): + """CPU counters remain; process names/PIDs and unrecognized fields do not.""" + fields = ('status', 'host', 'started_utc', 'finished_utc', 'intervals', 'declaration', 'policy', 'power_policy', 'error') + result = {name: value[name] for name in fields if name in value} + if 'host' in result: + host = value['host'] + result['host'] = {name: host[name] for name in ('platform', 'python', 'psutil', 'cpu_logical', 'cpu_physical', 'cpu', 'windows') if name in host} + return result + + +def validate_raw_identity(root, identity): + value = json.loads((root / 'hosted.json').read_text(encoding='utf-8')) + require(value['schema'] == 'termforge-r54-hosted-v1' and value['hosted_identity'] == identity and + value['source'] == identity['GITHUB_SHA'], 'raw evidence belongs to another run, attempt or source') + + +def publish_jsonl(original, replacements): + # JSONL is appended, unlike the atomic JSON manifests. A stop can leave an + # incomplete final row. Preserve it and the complete rows, mark the parse + # problem, and continue exporting independently retained sample streams. + status = dict(complete=True, error=None) + for index, line in enumerate(original.splitlines(), start=1): + try: + json.loads(line.decode('utf-8')) + except (UnicodeDecodeError, json.JSONDecodeError) as error: + status.update(complete=False, error=f'{type(error).__name__}: {error}', error_line=index) + break + data = original + for before, after in replacements: + data = data.replace(before.encode('utf-8'), after.encode('utf-8')) + return data, status + + +def selected_paths(root): + """No recursive directory export: only named builder and runner artifacts.""" + names = ['hosted.json', 'environment-declaration.json'] + names += ['bundle/' + name for name in ('preparation.json', 'plan-v1.json', 'build-plan.json', 'build-audit.json')] + for variant in ('baseline', 'candidate'): + names += [f'bundle/{variant}-harness.patch', f'bundle/{variant}-build.json'] + for step in ('checkout', 'fetch', 'build', 'identity'): + names += [f'bundle/{variant}-{step}.{suffix}' for suffix in ('stdout', 'stderr', 'process.json')] + for route in ('project', 'interactive'): + names += [f'bundle/sanity-{variant}-{route}/{stream}.bin' for stream in ('stdout', 'stderr')] + for seed in SEEDS: + prefix = f'batch-{seed}/' + names += [prefix + name for name in ('manifest.json', 'runner.json', 'environment.json', 'environment-policy.json', + 'environment-declaration.json', 'samples/context.json', 'samples/manifest.json', 'samples/samples.jsonl', 'samples/summary.json')] + for directory in ('baseline-identity', 'candidate-identity', 'power-policy', 'power-policy-after'): + names += [prefix + directory + '/' + name for name in ('record.json', 'stdout.bin', 'stderr.bin')] + for sequence in range(112): + names += [prefix + f'samples/{sequence:03d}/' + name for name in ('record.json', 'stdout.bin', 'stderr.bin')] + return [Path(name) for name in names if (root / name).is_file()] + + +def publish(root, output): + identity = hosted_identity() + root, output = Path(root).resolve(), Path(output).resolve() + require(root.is_relative_to(ROOT / 'local') and output.is_relative_to(ROOT / 'local'), 'publication paths must stay in workspace local') + require(root != output and not output.is_relative_to(root), 'public output must be separate from raw records') + require(not output.exists(), 'public output already exists') + validate_raw_identity(root, identity) + staging = output.with_name(output.name + '.partial') + require(staging.is_relative_to(ROOT / 'local'), 'staging path escaped workspace') + staging.mkdir(parents=True, exist_ok=False) + prefixes = [(str(ROOT), '${WORKSPACE}'), (os.environ.get('USERPROFILE', ''), '${PROFILE}'), + (os.environ.get('RUNNER_TEMP', ''), '${RUNNER_TEMP}')] + replacements = [] + for prefix, replacement in prefixes: + if prefix: + replacements += [(form, replacement) for form in (prefix.replace('\\', '\\\\'), prefix, prefix.replace('\\', '/'))] + + def text(value): + for before, after in replacements: + value = value.replace(before, after) + return value + + def transform(value): + if isinstance(value, dict): + return {key: transform(item) for key, item in value.items()} + if isinstance(value, list): + return [transform(item) for item in value] + return text(value) if isinstance(value, str) else value + + inventory = [] + for relative in selected_paths(root): + source = root / relative + require(source.resolve().is_relative_to(root), 'artifact path escaped raw directory') + original = source.read_bytes() + jsonl_status = None + # The measurement EXE consumes only public, fixed synthetic workloads. + # Preserve its raw streams even on failure. Other logs can contain host + # path prefixes; redact those without discarding their full contents. + raw_sample = bool(re.fullmatch(r'(?:batch-\d+/samples/\d{3}|bundle/sanity-(?:baseline|candidate)-(?:project|interactive))/(?:stdout|stderr)\.bin', relative.as_posix())) + if raw_sample: + data, treatment = original, 'byte_exact_owned_synthetic_stream' + elif relative.suffix == '.json': + value = json.loads(original.decode('utf-8')) + if relative.name == 'environment.json': + value = public_environment(value) + data = (json.dumps(transform(value), ensure_ascii=False, indent=2, allow_nan=False) + '\n').encode('utf-8') + treatment = 'json_whitelist_and_path_redaction' + elif relative.suffix == '.jsonl': + data, jsonl_status = publish_jsonl(original, replacements) + treatment = 'jsonl_path_redaction' + else: + data = original + for before, after in replacements: + data = data.replace(before.encode('utf-8'), after.encode('utf-8')) + treatment = 'complete_log_with_path_prefix_redaction' + target = staging / relative + target.parent.mkdir(parents=True, exist_ok=True) + target.write_bytes(data) + inventory.append(dict(path=relative.as_posix(), original_bytes=len(original), + original_sha256=hashlib.sha256(original).hexdigest(), + published_bytes=len(data), published_sha256=sha(target), treatment=treatment, + jsonl_status=jsonl_status)) + write_json(staging / 'publication.json', dict(schema='termforge-r54-hosted-publication-v1', + hosted_identity=identity, artifacts=inventory, raw_process_identities_published=False, + full_environment_variables_published=False, performance_gate='not_evaluated', + limitation='guest CPU evidence cannot establish exclusive physical host or stable frequency')) + staging.rename(output) + return dict(files=len(inventory), output=str(output), performance_gate='not_evaluated') + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--raw', type=Path, required=True) + parser.add_argument('--out', type=Path, required=True) + args = parser.parse_args() + print(json.dumps(publish(args.raw, args.out))) + + +if __name__ == '__main__': + main() diff --git a/experiments/measure/test_r54_hosted.py b/experiments/measure/test_r54_hosted.py new file mode 100644 index 00000000..28782dd6 --- /dev/null +++ b/experiments/measure/test_r54_hosted.py @@ -0,0 +1,87 @@ +"""Build input and publication boundaries; no performance workloads in tests.""" +import json +import os +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest + + +ROOT = Path(__file__).resolve().parents[2] + + +class BuildBoundaryTests(unittest.TestCase): + def test_unreviewed_compiler_override_stops_before_source_checkout(self): + with tempfile.TemporaryDirectory() as folder: + output = Path(folder) / 'bundle' + result = subprocess.run( + [sys.executable, '-m', 'experiments.measure.r54_build', '--out', str(output)], + cwd=ROOT, env=dict(os.environ, RUSTFLAGS='-C opt-level=0'), + capture_output=True, timeout=20) + self.assertNotEqual(result.returncode, 0) + manifest = json.loads((output / 'preparation.json').read_text(encoding='utf-8')) + self.assertEqual(manifest['status'], 'failed') + self.assertIn('RUSTFLAGS', manifest['error']) + self.assertFalse((output / 'source-baseline').exists()) + self.assertFalse((output / 'plan-v1.json').exists()) + + +class PublicationBoundaryTests(unittest.TestCase): + def test_interrupted_jsonl_tail_remains_visible_without_losing_complete_samples(self): + from experiments.measure.r54_publish import publish_jsonl + original = b'{"command":["/ci/work/tool.exe"],"cpu":2.0}\n{"command":[' + data, status = publish_jsonl(original, [('/ci/work', '${WORKSPACE}')]) + self.assertEqual(data, b'{"command":["${WORKSPACE}/tool.exe"],"cpu":2.0}\n{"command":[') + self.assertFalse(status['complete']) + self.assertIn('JSONDecodeError', status['error']) + self.assertEqual(status['error_line'], 2) + + def test_missing_or_different_raw_run_identity_is_rejected(self): + from experiments.measure.r54_publish import validate_raw_identity + identity = dict(GITHUB_RUN_ID='123', GITHUB_RUN_ATTEMPT='1', GITHUB_SHA='a' * 40) + with tempfile.TemporaryDirectory() as folder: + root = Path(folder) + with self.assertRaises(FileNotFoundError): + validate_raw_identity(root, identity) + path = root / 'hosted.json' + path.write_text(json.dumps(dict(schema='termforge-r54-hosted-v1', source='a' * 40, + hosted_identity=identity)), encoding='utf-8') + validate_raw_identity(root, identity) + with self.assertRaises(ValueError): + validate_raw_identity(root, dict(identity, GITHUB_RUN_ID='124')) + + def test_export_inventory_does_not_include_unrelated_or_arbitrary_files(self): + from experiments.measure.r54_publish import selected_paths + with tempfile.TemporaryDirectory() as folder: + root = Path(folder) + files = ['bundle/plan-v1.json', 'bundle/credentials.json', + 'batch-20261026/samples/000/stdout.bin', + 'batch-20261026/samples/000/unrelated.txt', + 'batch-20261026/samples/999/stdout.bin', 'personal-session.log'] + for name in files: + path = root / name + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(b'fixture') + self.assertEqual({path.as_posix() for path in selected_paths(root)}, + {'bundle/plan-v1.json', 'batch-20261026/samples/000/stdout.bin'}) + + def test_environment_export_keeps_cpu_evidence_and_omits_process_identities(self): + from experiments.measure.r54_publish import public_environment + value = dict(status='rejected_busy_host', host=dict(platform='Windows', cpu_logical=4), + intervals=[dict(busy_percent=7.5, total_seconds=4, busy_seconds=.3)], + processes_before=[dict(pid=123, name='private-name', cpu_times=dict(user=2))], + processes_after=[dict(pid=123, name='private-name', cpu_times=dict(user=3))], + unexpected_private_field='do-not-publish') + result = public_environment(value) + self.assertEqual(result['intervals'], value['intervals']) + self.assertEqual(result['host']['cpu_logical'], 4) + self.assertEqual(result['status'], 'rejected_busy_host') + self.assertNotIn('private-name', json.dumps(result)) + self.assertNotIn('do-not-publish', json.dumps(result)) + self.assertNotIn('processes_before', result) + + + +if __name__ == '__main__': + unittest.main() From ed0c12597d3b80a8806b2c6c24032cffaacf0945 Mon Sep 17 00:00:00 2001 From: JavaZero <71128095+JavaZeroo@users.noreply.github.com> Date: Tue, 27 Oct 2026 19:07:04 +0800 Subject: [PATCH 2/2] fix: preserve reviewed hosted evidence and redact short Windows paths (#54) --- .github/workflows/r54-cost.yml | 2 + docs/EVIDENCE.md | 1 + docs/FEATURES.md | 2 +- experiments/measure/R54-HOSTED.md | 6 +- experiments/measure/r54_publish.py | 52 ++- .../results/2026-10-27-r54-hosted/README.md | 24 ++ .../2026-10-27-r54-hosted/evidence.zip | Bin 0 -> 164608 bytes .../2026-10-27-r54-hosted/validation.json | 316 ++++++++++++++++++ .../results/2026-10-27-r54-hosted/verify.py | 78 +++++ experiments/measure/test_r54_hosted.py | 9 + 10 files changed, 474 insertions(+), 16 deletions(-) create mode 100644 experiments/measure/results/2026-10-27-r54-hosted/README.md create mode 100644 experiments/measure/results/2026-10-27-r54-hosted/evidence.zip create mode 100644 experiments/measure/results/2026-10-27-r54-hosted/validation.json create mode 100644 experiments/measure/results/2026-10-27-r54-hosted/verify.py diff --git a/.github/workflows/r54-cost.yml b/.github/workflows/r54-cost.yml index 023fdf31..e84887ef 100644 --- a/.github/workflows/r54-cost.yml +++ b/.github/workflows/r54-cost.yml @@ -18,6 +18,8 @@ concurrency: jobs: fixed-cost: + # A code/evidence correction must not silently launch replacement samples. + if: github.event.created == true runs-on: windows-2025 timeout-minutes: 30 env: diff --git a/docs/EVIDENCE.md b/docs/EVIDENCE.md index 3370ac10..e7402838 100644 --- a/docs/EVIDENCE.md +++ b/docs/EVIDENCE.md @@ -163,5 +163,6 @@ python -m unittest experiments.shell.test_workflow_sessions -v |---|---|---| | 候选 `.3`→`.4` 字素改动 | [固定字素验证](../experiments/shell/results/2026-10-26-streaming-graphemes/validation.json)、[性能限制与原始样本身份](research/streaming-graphemes.md)、[#54](https://github.com/JavaZeroo/termforge/issues/54) | 同宿主交错诊断中 project/interactive 吞吐中位数约下降 16%/9%;共享宿主、allocator 包装、无真实呈现/输入时延,使其不能作为正式预算或性能通过。#54 受控定位仍阻塞 #34 的性能裁决。 | | 固定字素成本的批次协议与执行 | [R54 v1 合同和构建/环境记录](../experiments/measure/R54-COST.md)、[执行器](../experiments/measure/r54_batch.py)、[合成进程回归](../experiments/measure/test_r54_batch.py)、[实际预检及限定验证](../experiments/measure/results/2026-10-27-r54-runner/validation.json) | 固定两个种子、各 112 个位置,字节原样保留、首错停止、完整批次后逐组配对统计。共享工作站十区间活动预检未通过,未启动成本样本;测量相关 26 项测试通过,首次 Linux 候选 CI 的采样依赖导入错误及修正分别留证。5% 是环境诊断护栏,并非产品性能容差;实际批次、扰动归因及用户预算确认由 #54 接续。 | +| 首次 hosted 字素成本批次 | [来源、停止位置与归档](../experiments/measure/results/2026-10-27-r54-hosted/README.md)、[机器可读记录](../experiments/measure/results/2026-10-27-r54-hosted/validation.json) | 两份固定构建与4次sanity通过,空闲预检通过;第24位置的未归属CPU活动估计5.410%触发原5%护栏,保留23个有效记录和1个失败记录,第二批未启动。全部24次输出正确,但批次不完整,不生成配对成本摘要;临时VM逐进程归因、完整受控批次和预算仍未完成。 | 目前没有足够证据判断 TermForge 距离 WindTerm 快或慢多少。正式结论必须同时提供负载/配置/环境身份、正确性、完成端点、观测开销、重复样本与限制。未知字段保持未知;历史校准未完成不转成要求用户反复手动运行的前置。执行规则见 [ADR-0002](adr/0002-automation-first-investigation.md),核心选型重审见 [ADR-0003](adr/0003-core-reference-and-reuse.md)。 diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 3eead283..6619b2a3 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -71,7 +71,7 @@ | 自动正确性与构建 | **限定验收**:Windows shell/ConPTY/呈现及 Windows/Linux 核心 CI、差分/恢复/队列/生命周期场景 | 产品打包、干净机器使用、依赖升级、长期回归和更广平台矩阵;#40 的 CI 纯夹具超时、窄窗口选择 #73、四 shell 原事件 #80、hosted 准备 #81 和[复制夹具 OpenClipboard 5 #85](https://github.com/JavaZeroo/termforge/issues/85) 等独立失败仍未闭合;#72 保存判据与 #80 同步条件的限定修正不代替其他配置或未知根因验收 | R2 / R4 | | Windows 产品交付 | **实现中,未验收**:首个 [v0.1.0-alpha.1 预发布](releases/v0.1.0-alpha.1.md)提供 Windows x64、静态 MSVC 运行库、附资源许可和构建身份的免安装 ZIP;未签名,已验环境限 Windows 11 本机与 Server 2025 CI,布局仍写入 LOCALAPPDATA | 这是 R1 体验包,尚非 R2 日常开发版;干净机器与更广平台矩阵、签名/安装、配置升级及持续运行仍待完成。Windows 10 未验收,Server 2022 已知资源门槛未过 | R2 / R3 | | Linux/macOS 与其他架构 | **未实现**客户端;Linux 核心 CI 已有。[官方平台范围台账](../research/windterm-2.7.0-platform-scope.md)已固定 2.7.0 的 Windows x86/x64、macOS x64、Linux x64 资产及声明下限;这不是 TermForge 支持或实测结论 | 最终需真实 Linux/macOS 客户端;平台调查可提前进行,整合及完整验收排在 Windows 11 x64 完整版本之后。其他系统版本、最低版本和架构由用户后续明确;旧系统及 ARM 等保持调查记录,不自动承诺或排除,也不能由核心 CI 推断产品支持 | 持续调查;R5 全平台出口 | -| 吞吐、响应、内存与稳定性 | **实现中,未验收**:已有机制实验、连续 CPU 区间校准与合成回归;候选字素改动的受限诊断中 project/interactive 吞吐中位数约下降 16%/9%,由 [#54](https://github.com/JavaZeroo/termforge/issues/54) 跟踪。[冻结批次执行器](../experiments/measure/R54-COST.md#冻结批次执行器windows)核对构建来源、原始输出、停止规则与逐轮配对统计;其环境护栏和合成进程测试不构成正式成本样本 | 共享宿主、allocator 包装与缺少真实呈现/输入时延端点使该诊断不构成正式预算。仍需同负载/同正确性、无插桩对照、观测开销和长期/多会话公平性;可靠原版基线后提出逐项预算及允许波动范围,**由用户明确确认**。与 WindTerm 的实际差距**待取证** | 当前优先;贯穿 R1–R5 | +| 吞吐、响应、内存与稳定性 | **实现中,未验收**:已有机制实验、连续 CPU 区间校准与合成回归;候选字素改动的受限诊断中 project/interactive 吞吐中位数约下降 16%/9%,由 [#54](https://github.com/JavaZeroo/termforge/issues/54) 跟踪。[冻结批次执行器](../experiments/measure/R54-COST.md#冻结批次执行器windows)核对构建来源、原始输出、停止规则与逐轮配对统计;[独立 hosted 构建与实测](../experiments/measure/results/2026-10-27-r54-hosted/README.md)已验证来源和失败保留,但首批因环境护栏停止,尚无完整成本批次 | 旧诊断的共享宿主、allocator 包装与缺少真实呈现/输入时延端点使其不构成正式预算;新的不完整批次也不作吞吐结论。仍需同负载/同正确性、无插桩对照、观测开销和长期/多会话公平性;可靠原版基线后提出逐项预算及允许波动范围,**由用户明确确认**。与 WindTerm 的实际差距**待取证** | 当前优先;贯穿 R1–R5 | | 大历史与动态内存压缩 | **未实现**产品能力;WindTerm 压缩属于官方性能声明,内部机制尚未证实 | 1/10/100 万行等明确规模下的内存/滚动/搜索/淘汰实验;根据瓶颈决定独立存储/压缩实现 | R4 | | 完整目标验收 | **待取证**:已有固定版本和局部观察,没有完整行为/性能对照矩阵 | 先在 Windows 11 x64 完整验收功能/行为/UI/性能及独立构建,再完成 Linux/macOS 全平台出口;重要差异和性能容差须有用户确认,Windows 通过不代表全平台完成;不依赖 WindTerm 二进制或专有资源 | R5 分平台出口 | diff --git a/experiments/measure/R54-HOSTED.md b/experiments/measure/R54-HOSTED.md index 90b7fd72..ee25c865 100644 --- a/experiments/measure/R54-HOSTED.md +++ b/experiments/measure/R54-HOSTED.md @@ -4,7 +4,7 @@ ## 运行与停止 -[工作流](../../.github/workflows/r54-cost.yml)只在实验分支 `perf/grapheme-hosted-r54` 的执行相关源码变化时启动,不在 PR 事件上重复触发,也不改变 main 的默认构建。每次工作流用独立 run ID、attempt、源码和输出目录;拒绝对旧 workflow run 的 attempt 2 及后续重跑。新的源码修订保留旧失败,并构成另一个明确身份,不替代已取得的样本。 +[工作流](../../.github/workflows/r54-cost.yml)只在实验分支 `perf/grapheme-hosted-r54` 的创建 push 事件执行成本作业,不在 PR 事件或后续源码/证据修正时自动补跑,也不改变 main 的默认构建。每次工作流用独立 run ID、attempt、源码和输出目录;拒绝对旧 workflow run 的 attempt 2 及后续重跑。首次运行后,新的调查需先明确假设、范围和新身份,再审查执行入口,不能由导出器修正偷偷触发替代样本。 同一虚拟机依次完成固定 Python/Rust、纯合同测试、两份来源构建、四次短正确性检查,再运行原两个种子。构建和测试结束后才开始成本预检与计时。没有自动恢复、补样、重试或放宽5%环境诊断护栏的入口;第一批失败即保留当前位置,第二批不启动。两批成功也只写 `complete_diagnostic`,`performance_gate=not_evaluated`。 @@ -22,6 +22,8 @@ GitHub runner服务、操作系统后台任务、虚拟机邻居、物理CPU频 [发布器](r54_publish.py)只接受本流程的真实GitHub-hosted首次作业,并使用固定文件白名单。它不递归上传工作目录、checkout、编译缓存或个人文件。仅保存本次公开源码/合成输入产生的结果;完整进程名称/PID记录与未知环境字段不导出,工作区、runner profile和临时路径前缀改为别名。没有读取完整进程命令行或任意环境变量的步骤。 +Windows 长路径及实际8.3别名均纳入替换,兼容大小写、正斜杠和编译器转义形式;通过[GetShortPathNameW](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getshortpathnamew)查询,失败则不发布,不能猜测短名。首次作业导出曾漏掉两份构建日志中的短profile前缀;原包保留,审阅后的公开副本另列哈希及转换,不回填为旧运行使用了修正版导出器。 + 两个核心的成本及短正确性 stdout/stderr 按原字节保留,包括失败或无效编码;其生产者只接收公开固定合成负载。完整构建日志保留内容并替换宿主路径前缀。JSON/JSONL记录只做上述元数据筛选和路径处理,不改变时间、工作量、状态摘要、顺序或失败状态。中断留下的JSONL半行不修补、不删除,保留全部行和解析失败位置,独立样本原始流仍导出。`publication.json`列出每份原文件和发布文件的SHA、大小及处理方式。导出前核对原始 `hosted.json` 的run ID/attempt/SHA;空目录或另一次作业不生成成功包。发布目录在所有文件完成后才生效,上传仅指向该目录;未通过检查的半成品目录不会上传。 原始完整进程身份只在临时虚拟机内保留,公开结果保留全机CPU原计数、全部成本原始流及其来源。不能用未导出的逐进程字段做外部归因声明;后续若需要这种归因,另行预声明可公开的受控观测。所有CI结果须下载复核其清单、原始样本和统计后才能写入 #54 的成本结论。 @@ -34,3 +36,5 @@ python -m experiments.measure.r54_publish --raw local/r54-raw --out local/r54-pu ``` 本机不得伪造GitHub环境变量运行该流程。普通本地准备可使用 `r54_build --out <新目录>`,要求实际Windows、已提交的干净源码及显式任务缓存;本轮不重复已有主工作站成本预检。测试只验证既有构建输入/产物边界,正式成本样本来自上述实际作业。 + +首次真实作业的来源、全部原始产物、环境护栏停止位置和独立复核见[固定记录](results/2026-10-27-r54-hosted/README.md)。这是不完整批次,没有配对成本摘要或性能通过结论。 diff --git a/experiments/measure/r54_publish.py b/experiments/measure/r54_publish.py index c239b493..5a9787a0 100644 --- a/experiments/measure/r54_publish.py +++ b/experiments/measure/r54_publish.py @@ -28,6 +28,38 @@ def validate_raw_identity(root, identity): value['source'] == identity['GITHUB_SHA'], 'raw evidence belongs to another run, attempt or source') +def windows_short_path(path): + """Ask Windows for the actual alias; guessing RUNNER~1 is not reliable.""" + import ctypes + from ctypes import wintypes + function = ctypes.WinDLL('kernel32', use_last_error=True).GetShortPathNameW + function.argtypes = [wintypes.LPCWSTR, wintypes.LPWSTR, wintypes.DWORD] + function.restype = wintypes.DWORD + length = function(path, None, 0) + if not length: + raise ctypes.WinError(ctypes.get_last_error()) + buffer = ctypes.create_unicode_buffer(length) + copied = function(path, buffer, length) + if not copied or copied >= length: + raise ValueError('short-path lookup failed or changed during publication') + return buffer.value + + +def replacement_forms(prefixes): + forms = [] + for prefix, alias in prefixes: + forms.extend((form, alias) for form in (prefix.replace('\\', '\\\\'), prefix, prefix.replace('\\', '/'))) + return sorted(set(forms), key=lambda item: len(item[0]), reverse=True) + + +def redact_paths(data, replacements): + # Preserve arbitrary log bytes. The hosted Windows path prefixes are ASCII + # and may use a different case or a compiler-escaped 8.3 alias. + for before, after in replacements: + data = re.sub(re.escape(before.encode('utf-8')), lambda _: after.encode('utf-8'), data, flags=re.IGNORECASE) + return data + + def publish_jsonl(original, replacements): # JSONL is appended, unlike the atomic JSON manifests. A stop can leave an # incomplete final row. Preserve it and the complete rows, mark the parse @@ -39,10 +71,7 @@ def publish_jsonl(original, replacements): except (UnicodeDecodeError, json.JSONDecodeError) as error: status.update(complete=False, error=f'{type(error).__name__}: {error}', error_line=index) break - data = original - for before, after in replacements: - data = data.replace(before.encode('utf-8'), after.encode('utf-8')) - return data, status + return redact_paths(original, replacements), status def selected_paths(root): @@ -78,15 +107,12 @@ def publish(root, output): staging.mkdir(parents=True, exist_ok=False) prefixes = [(str(ROOT), '${WORKSPACE}'), (os.environ.get('USERPROFILE', ''), '${PROFILE}'), (os.environ.get('RUNNER_TEMP', ''), '${RUNNER_TEMP}')] - replacements = [] - for prefix, replacement in prefixes: - if prefix: - replacements += [(form, replacement) for form in (prefix.replace('\\', '\\\\'), prefix, prefix.replace('\\', '/'))] + prefixes = [(prefix, alias) for prefix, alias in prefixes if prefix] + prefixes += [(windows_short_path(prefix), alias) for prefix, alias in prefixes] + replacements = replacement_forms(prefixes) def text(value): - for before, after in replacements: - value = value.replace(before, after) - return value + return redact_paths(value.encode('utf-8'), replacements).decode('utf-8') def transform(value): if isinstance(value, dict): @@ -117,9 +143,7 @@ def transform(value): data, jsonl_status = publish_jsonl(original, replacements) treatment = 'jsonl_path_redaction' else: - data = original - for before, after in replacements: - data = data.replace(before.encode('utf-8'), after.encode('utf-8')) + data = redact_paths(original, replacements) treatment = 'complete_log_with_path_prefix_redaction' target = staging / relative target.parent.mkdir(parents=True, exist_ok=True) diff --git a/experiments/measure/results/2026-10-27-r54-hosted/README.md b/experiments/measure/results/2026-10-27-r54-hosted/README.md new file mode 100644 index 00000000..429335cf --- /dev/null +++ b/experiments/measure/results/2026-10-27-r54-hosted/README.md @@ -0,0 +1,24 @@ +# #54 首次 hosted 固定批次:环境护栏停止 + +固定源码 `f734d29bc4f8a120eac59da3acac3169d49231b2` 在 [GitHub run 40490861301](https://github.com/JavaZeroo/termforge/actions/runs/40490861301) 的首次 `windows-2025` 作业中完成两份构建、来源审计及4次短正确性检查。原协议、两个种子、各112位置、2秒CPU/墙钟下限、5%环境诊断护栏均未改变。 + +第一批的十个空闲区间为1.154%–3.125%,通过预检。随后执行24个位置:23个记录有效,第24个(sequence 23,candidate/interactive/chunk 1)输出正确且退出0,但未归属CPU活动上界估计为5.410447761%,超过5%护栏,故停止。原始数据全部保留,没有续跑、补样、删除慢样本或启动第二批。 + +该位置全机总CPU区间为8.375秒,busy为2.484375秒,内层测量进程CPU为2.03125秒,余额0.453125秒。余额包含内层区间以外的准备、oracle、启动和runner工作,不能直接称为其他进程的后台CPU,更不能据此定位具体进程。临时VM的逐进程身份未导出,不能追溯补造归因。 + +**完整批次数为0,不生成配对成本摘要,不从这个前缀计算或验收吞吐回归。** `performance_gate=not_evaluated`;5%不是用户批准的产品性能容差。物理宿主独占、邻居VM、频率稳定、输入/传输/呈现及WindTerm等价仍未测。 + +- [validation.json](validation.json):源码/树、构建/二进制、宿主、停止位置、限制及同源码回归CI。 +- [evidence.zip](evidence.zip):审阅后的164,608B公开副本,SHA-256 `9ade502f03419f55295b4e9f4df9dc136c5c4d50ace02d41417fea1de6952917`。内含131个文件:130份白名单证据和`publication.json`;56份合成stdout/stderr原字节保留。全部24次输出的正确性和完整字段已独立复查。 +- 提供者原归档165,170B、SHA-256 `6a2713dd96d86ce66e2462a142d46b72e915ccc4cfd45bd3b42c5e7486c3cef5`保存在local。产物复审发现两份构建日志各有10处未处理的8.3短profile前缀;未发现凭据。公开副本仅补做这些前缀的别名替换,并更新清单,保留转换前/后哈希和`post_publication_review`;成本数据、顺序和停止状态未改,不冒充原ZIP字节。 +- 复查副本的来源、固定白名单、长/短路径及秘密字段后,未发现逐进程名称/PID、凭据或未处理的workspace/profile前缀。旧作业确实使用旧导出器;后续实现修正不回填旧运行身份,也不触发补跑成本批次。 + +测量源码对应的默认PR/push回归均通过(Windows46/46、Linux29/29);候选两条CI也通过(measurement Windows40/40,Linux39通过/1个Windows专属跳过)。当时相关本地measurement31/31;后续短路径修正另有失败反例、实际Windows别名查询及32/32回归。普通CI与成本作业分开,不用CI成功抵消成本批次失败。日志哈希指向本地保留的UTF-8/LF解码文本,并非提供者日志ZIP原件。 + +归档复查命令不会执行成本负载或修改数据: + +```powershell +python experiments/measure/results/2026-10-27-r54-hosted/verify.py +``` + +下一项调查由[#54](https://github.com/JavaZeroo/termforge/issues/54)接续:另行预声明有界诊断,观测整个测量子进程及runner的CPU,区分自身区间外工作与外部guest活动;本次失败和v1规则保持。扰动/组件归因、完整受控批次及用户预算确认仍未完成。 diff --git a/experiments/measure/results/2026-10-27-r54-hosted/evidence.zip b/experiments/measure/results/2026-10-27-r54-hosted/evidence.zip new file mode 100644 index 0000000000000000000000000000000000000000..3f12caf74b37410a5974f2407e1a1ac3827e0d51 GIT binary patch literal 164608 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.a)@ihr8h^O44f3wjUSSiTbaZdmRZ_UA8Q^a0C$W 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]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 literal 0 HcmV?d00001 diff --git a/experiments/measure/results/2026-10-27-r54-hosted/validation.json b/experiments/measure/results/2026-10-27-r54-hosted/validation.json new file mode 100644 index 00000000..199ea78f --- /dev/null +++ b/experiments/measure/results/2026-10-27-r54-hosted/validation.json @@ -0,0 +1,316 @@ +{ + "schema": "termforge-r54-hosted-validation-v1", + "status": "incomplete_first_batch_stopped_by_environment_guard", + "source": "f734d29bc4f8a120eac59da3acac3169d49231b2", + "tree": "361683a329aa7c24d34fc34158b42ea55f4786f7", + "reviewed_local_source": "a8daaab2202fa5a36cbad216959355583eba78f0", + "base": "a7b9685a20396779dc9dff51018470b7638bfdce", + "pr_merge_source": "38c6703403948f79c7112d7340df4087d0689edc", + "pr_merge_tree_matches_reviewed": true, + "protocol_sha256": "fb86f093a1c526979816574ef65896501eaeb9e9c34e7d9a6f2fdd5b61a8e7f6", + "review": { + "standards_remaining": 0, + "spec_remaining": 0, + "read_only": true + }, + "local_validation": { + "measurement_tests": 31, + "passed": 31, + "unittest_seconds": 13.809, + "ctest_seconds": 13.99, + "stdout_sha256": "f31c7251649be1d7d9157eeb3a9d83c8d397e6cadd4a5f80347f689637b6caf5", + "stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "hosted": { + "run": 40490861301, + "job": 122144148028, + "attempt": 1, + "conclusion": "failure", + "url": "https://github.com/JavaZeroo/termforge/actions/runs/40490861301", + "runner_labels": [ + "windows-2025" + ], + "contract_tests_passed": 22, + "decoded_job_log_sha256": "fbb8fad6fda8eaad64a940cbd0dae55fdec9690c9cde3b2da7df857c4b0ee1ad", + "build_status": "built_and_audited", + "sanity_passed": 4 + }, + "compiler": { + "rustc_vv": "rustc 1.92.0 (ded5c06cf 2025-12-08)\nbinary: rustc\ncommit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234\ncommit-date: 2025-12-08\nhost: x86_64-pc-windows-msvc\nrelease: 1.92.0\nLLVM version: 21.1.3\n", + "cargo_vv": "cargo 1.92.0 (344c4567c 2025-10-21)\nrelease: 1.92.0\ncommit-hash: 344c4567c634a25837e3c3476aac08af84cf9203\ncommit-date: 2025-10-21\nhost: x86_64-pc-windows-msvc\nlibgit2: 1.9.1 (sys:0.20.2 vendored)\nlibcurl: 8.15.0-DEV (sys:0.4.83+curl-8.15.0 vendored ssl:Schannel)\nos: Windows 10.0.26100 (Windows 11 ServerDatacenter) [64-bit]\n", + "sha256": "5f3b5087b95e250378dd7bd829ae627d51c149468aae1e38c0f2a85c17cd374e" + }, + "builds": { + "baseline": { + "source": "65988f5f20f62294ff52fcac5b5b81e563f93f3b", + "version": "0.26.1-dev+termforge.3", + "candidate_tree": "38f901ce2407d73ab7d4ae70987c294849bafa92", + "tracked_candidate_files": 80, + "changed_paths": [ + "experiments/candidates/alacritty/Cargo.toml", + "experiments/candidates/alacritty/src/measure.rs" + ], + "binary": { + "bytes": 523264, + "sha256": "ac7c1d4ba996f9fe2c0d911a077bcab557f5b0b7332cde757dfb3f7db2c499a1" + }, + "identity": { + "allocator_wrapper_compiled": false, + "projection_selectable": true, + "schema": "termforge-core-cost-build-v1", + "timing_gates_compiled": true + }, + "linker": { + "path": "C:\\Program Files\\Microsoft Visual Studio\\18\\Enterprise\\VC\\Tools\\MSVC\\14.51.36231\\bin\\HostX64\\x64\\link.exe", + "sha256": "a8c42e25c91ca2453e1110540ac08f0fc12d7539454a11b9af8baeecb469837d" + }, + "receipt_sha256": "7cabd0c3610017fdb2f296999e2d96083bf5f4ba245aa0b414aab1d1527fa9ea" + }, + "candidate": { + "source": "3d6d44d3b3e9a9a3e41da98e8711e9f19a211fd8", + "version": "0.26.1-dev+termforge.4", + "candidate_tree": "2cce55fcf2d379440110bbbf8612117cce3edf64", + "tracked_candidate_files": 84, + "changed_paths": [ + "experiments/candidates/alacritty/Cargo.toml", + "experiments/candidates/alacritty/src/measure.rs" + ], + "binary": { + "bytes": 580096, + "sha256": "e674f0df59af27151fe2c1ad916b6cb4f4dd6ccd783ed225fe0107e13b74ae0a" + }, + "identity": { + "allocator_wrapper_compiled": false, + "projection_selectable": true, + "schema": "termforge-core-cost-build-v1", + "timing_gates_compiled": true + }, + "linker": { + "path": "C:\\Program Files\\Microsoft Visual Studio\\18\\Enterprise\\VC\\Tools\\MSVC\\14.51.36231\\bin\\HostX64\\x64\\link.exe", + "sha256": "a8c42e25c91ca2453e1110540ac08f0fc12d7539454a11b9af8baeecb469837d" + }, + "receipt_sha256": "eeef0cfd10f469bb44ddade96cae6c81263c600cfa014a984bc4466a452c14f9" + } + }, + "batches": [ + { + "seed": 20261026, + "status": "failed", + "attempted": 24, + "valid_samples": 23, + "error": "ValueError: ValueError: sample 23 failed: ValueError: host activity guard failed; sample retained, batch stopped", + "host": { + "platform": "Windows-2025Server-10.0.26100-SP0", + "python": "3.12.10", + "psutil": "7.2.2", + "cpu_logical": 4, + "cpu_physical": 2, + "cpu": { + "ProcessorNameString": "AMD EPYC 9V45 96-Core Processor ", + "Identifier": "AMD64 Family 26 Model 2 Stepping 1" + }, + "windows": { + "CurrentBuildNumber": "26100", + "UBR": 33650, + "DisplayVersion": "24H2" + } + }, + "environment_status": "low_activity_observed", + "busy_percent": [ + 1.5625, + 1.5625, + 1.953125, + 1.171875, + 1.550387596899225, + 1.550387596899225, + 1.953125, + 3.125, + 1.171875, + 1.1538461538461537 + ] + } + ], + "all_attempted_output_oracles_passed": 24, + "all_attempted_processes_exit_zero": 24, + "stopped_sample": { + "item": { + "sequence": 23, + "repeat": 1, + "route": "interactive", + "chunk": 1, + "variant": "candidate", + "observe": 0 + }, + "status": "failed", + "error": "ValueError: host activity guard failed; sample retained, batch stopped", + "guest_total_cpu_seconds": 8.375, + "guest_busy_cpu_seconds": 2.484375, + "inner_measured_process_cpu_seconds": 2.03125, + "unattributed_cpu_seconds": 0.453125, + "unattributed_busy_percent_upper_estimate": 5.41044776119403 + }, + "second_seed_started": false, + "full_batches_completed": 0, + "paired_cost_summary_produced": false, + "performance_gate": "not_evaluated", + "numerical_product_budget": null, + "archive": { + "path": "evidence.zip", + "bytes": 164608, + "sha256": "9ade502f03419f55295b4e9f4df9dc136c5c4d50ace02d41417fea1de6952917", + "provider_artifact": 12728432619, + "files": 131, + "inventory_verified_files": 130, + "byte_exact_synthetic_streams": 56, + "individual_publication_sha256": "75f98a70ae4567eebb7686c5284a84df5f4b137220fe0032cbd6579aa82c36dd", + "privacy_review": "Reviewed public copy additionally replaces the observed Windows 8.3 profile aliases in two build logs. No process identities, credentials or remaining workspace/profile prefixes found. Measurement streams unchanged.", + "provider_archive_bytes": 165170, + "provider_archive_sha256": "6a2713dd96d86ce66e2462a142d46b72e915ccc4cfd45bd3b42c5e7486c3cef5", + "provider_original_retained_locally": true, + "post_publication_review": [ + { + "path": "bundle/baseline-build.stderr", + "previous_published_sha256": "812ba8957f4fcf9b5019361b2b022ad529b695dbc89f89b7bec7c95b89969626", + "reviewed_sha256": "585a85a2909b2e5325e6573ee5c9cf6e03a1a389adf09409b7f9da92dd87bee1", + "replacements": 10 + }, + { + "path": "bundle/candidate-build.stderr", + "previous_published_sha256": "44c59810fe10f93df597115060e6cf86749350a96f92fe9df174d0241da66579", + "reviewed_sha256": "b25d91f15ca587c2fa37420f3bc2a5ca357426a73eb5cc2885b522f87fb66860", + "replacements": 10 + } + ] + }, + "ci": [ + { + "run": 40490884320, + "event": "pull_request", + "name": "default", + "jobs": [ + { + "job": 122144220963, + "platform": "windows-2025", + "passed": 46, + "collected": 46, + "seconds": 276.62, + "decoded_log_sha256": "46d7dc7a0d2adcd51de07e6aa27c132a155f3e313a4bf947bd220df426d98002" + }, + { + "job": 122144221116, + "platform": "ubuntu-24.04", + "passed": 29, + "collected": 29, + "seconds": 16.67, + "decoded_log_sha256": "1df6af066a76fa8d090a46f38a1612d7d1d4c6e3b3db9a5b9a858d19fccb752d" + } + ], + "conclusion": "success", + "attempt": 1, + "url": "https://github.com/JavaZeroo/termforge/actions/runs/40490884320" + }, + { + "run": 40490861189, + "event": "push", + "name": "default", + "jobs": [ + { + "job": 122144147319, + "platform": "windows-2025", + "passed": 46, + "collected": 46, + "seconds": 282.38, + "decoded_log_sha256": "318d044f96dcccb27983100d3fdbd897073142e63e656e369f6d838d45991d16" + }, + { + "job": 122144147638, + "platform": "ubuntu-24.04", + "passed": 29, + "collected": 29, + "seconds": 16.02, + "decoded_log_sha256": "14366db79e80b31887b26d5e97d0bc9bdd7de001f83812400afd00c63c09f51b" + } + ], + "conclusion": "success", + "attempt": 1, + "url": "https://github.com/JavaZeroo/termforge/actions/runs/40490861189" + }, + { + "run": 40490883616, + "event": "pull_request", + "name": "candidate", + "measurement_jobs": [ + { + "job": 122144218593, + "platform": "windows-2025", + "passed": 40, + "collected": 40, + "skipped": 0, + "seconds": 30.304, + "decoded_log_sha256": "713d9b818aa14dd38480205e81c9d90eee74e94b717ca81ecdbb1b67dade0df9" + }, + { + "job": 122144218760, + "platform": "ubuntu-24.04", + "passed": 39, + "collected": 40, + "skipped": 1, + "seconds": 22.982, + "decoded_log_sha256": "b3e3033bd7c232de80b702c7945c1292dbe1ef1e9630416c8021318521fae7e0" + } + ], + "conclusion": "success", + "attempt": 1, + "url": "https://github.com/JavaZeroo/termforge/actions/runs/40490883616" + }, + { + "run": 40490861431, + "event": "push", + "name": "candidate", + "measurement_jobs": [ + { + "job": 122144148011, + "platform": "windows-2025", + "passed": 40, + "collected": 40, + "skipped": 0, + "seconds": 29.831, + "decoded_log_sha256": "f2ecb43c16ef0a8c3f6d75b6d1989f16b9027af852def85c03cb94dbd8f39f00" + }, + { + "job": 122144147926, + "platform": "ubuntu-24.04", + "passed": 39, + "collected": 40, + "skipped": 1, + "seconds": 25.717, + "decoded_log_sha256": "8015b82b14881aff82fa1d71db2a1e801d83aa604ac8a83a5a49d281c36f5f2f" + } + ], + "conclusion": "success", + "attempt": 1, + "url": "https://github.com/JavaZeroo/termforge/actions/runs/40490861431" + } + ], + "ci_logs_representation": "decoded UTF-8, LF; hashes identify retained local text, not provider ZIP bytes", + "limitations": [ + "The batch is incomplete: do not calculate or accept a throughput regression from this prefix.", + "5 percent is the frozen guest CPU diagnostic guard, not a user-approved product performance tolerance.", + "The remainder includes preparation/oracle/startup and runner CPU excluded by the inner timing interval; it does not identify the responsible process.", + "Per-process identities were not exported from the temporary VM; they cannot support retrospective attribution.", + "Physical host exclusivity, neighboring VM load, frequency stability, GUI/input/receive/presentation and WindTerm equivalence remain unmeasured.", + "No workflow rerun, skipped sample, replacement sample, relaxed guard or resumed second seed." + ], + "next_investigation": "Separately predeclare a bounded diagnostic of whole-child lifetime CPU and runner CPU to distinguish own work from external guest activity; preserve this first failure and the v1 acceptance rules.", + "post_run_publication_fix": { + "reason": "Windows compiler logs used short profile aliases absent from the original prefix list.", + "native_windows_short_path_lookup": "passed_same_directory", + "path_variant_regression": "red_then_green", + "measurement_tests": 32, + "passed": 32, + "unittest_seconds": 15.152, + "stdout_sha256": "c8c96d18f0a4f88593607294a831a3163735f74fa9e650a1c74424008b61e95c", + "cost_execution": "not_repeated; branch update no longer launches cost job", + "original_cost_source_unchanged": true + } +} diff --git a/experiments/measure/results/2026-10-27-r54-hosted/verify.py b/experiments/measure/results/2026-10-27-r54-hosted/verify.py new file mode 100644 index 00000000..ebe62162 --- /dev/null +++ b/experiments/measure/results/2026-10-27-r54-hosted/verify.py @@ -0,0 +1,78 @@ +"""Verify the immutable first hosted failure archive; do not run measurements.""" +import hashlib +import io +import json +from pathlib import Path +import sys +import zipfile + +sys.path.insert(0, str(Path(__file__).resolve().parents[4])) +from experiments.measure.r54_contract import validate_sample + + +def main(): + data = Path(__file__).with_name('evidence.zip').read_bytes() + assert len(data) == 164608 + assert hashlib.sha256(data).hexdigest() == '9ade502f03419f55295b4e9f4df9dc136c5c4d50ace02d41417fea1de6952917' + with zipfile.ZipFile(io.BytesIO(data)) as archive: + read = lambda name: json.loads(archive.read(name).decode('utf-8')) + publication = read('publication.json') + review = publication['post_publication_review'] + assert review['source_provider_archive_sha256'] == '6a2713dd96d86ce66e2462a142d46b72e915ccc4cfd45bd3b42c5e7486c3cef5' + assert review['measurement_streams_unchanged'] is True + assert {item['path'] for item in review['changes']} == {'bundle/baseline-build.stderr', 'bundle/candidate-build.stderr'} + inventory = {item['path']: item for item in publication['artifacts']} + assert len(inventory) == len(publication['artifacts']) == 130 + assert len(archive.namelist()) == 131 + assert set(archive.namelist()) == set(inventory) | {'publication.json'} + exact = 0 + for name, item in inventory.items(): + payload = archive.read(name) + assert len(payload) == item['published_bytes'], name + assert hashlib.sha256(payload).hexdigest() == item['published_sha256'], name + if item['treatment'] == 'byte_exact_owned_synthetic_stream': + assert item['original_bytes'] == len(payload), name + assert item['original_sha256'] == item['published_sha256'], name + exact += 1 + assert exact == 56 + hosted = read('hosted.json') + assert hosted['status'] == 'failed' and hosted['performance_gate'] == 'not_evaluated' + assert hosted['source'] == 'f734d29bc4f8a120eac59da3acac3169d49231b2' + assert hosted['hosted_identity'] == publication['hosted_identity'] + assert hosted['hosted_identity']['GITHUB_RUN_ID'] == '40490861301' + assert hosted['hosted_identity']['GITHUB_RUN_ATTEMPT'] == '1' + prefix = 'batch-20261026/' + manifest = read(prefix + 'manifest.json') + assert manifest['status'] == 'failed' and manifest['attempted'] == 24 and manifest['valid_samples'] == 23 + plan = read('bundle/plan-v1.json') + schedule = plan['protocol']['schedules'][0] + assert schedule['seed'] == 20261026 + records = [] + for sequence in range(24): + directory = prefix + f'samples/{sequence:03d}/' + record = read(directory + 'record.json') + assert record['item'] == schedule['samples'][sequence] + assert record['status'] == ('valid' if sequence < 23 else 'failed') + assert record['exit_code'] == 0 and not record['timed_out'] + result = read(directory + 'stdout.bin') + assert result == record['result'] + validate_sample(result, record['item']) + for name, identity in record['streams'].items(): + payload = archive.read(directory + name) + assert len(payload) == identity['bytes'] and hashlib.sha256(payload).hexdigest() == identity['sha256'] + environment = record['environment'] + remainder = environment['busy_seconds'] - result['interval_cpu_seconds'] + upper = remainder * 100 / environment['total_seconds'] + assert abs(upper - environment['unattributed_busy_percent_upper_estimate']) < 1e-12 + assert (0 <= upper <= 5) if sequence < 23 else upper > 5 + records.append(record) + assert [json.loads(line) for line in archive.read(prefix + 'samples/samples.jsonl').splitlines()] == records + assert prefix + 'samples/summary.json' not in inventory + assert not any(name.startswith('batch-20261027/') for name in inventory) + print(json.dumps(dict(archive_files=131, hashed_evidence_files=130, byte_exact_streams=56, + attempted=24, valid_records=23, correct_outputs=24, + full_batches=0, performance_gate='not_evaluated'))) + + +if __name__ == '__main__': + main() diff --git a/experiments/measure/test_r54_hosted.py b/experiments/measure/test_r54_hosted.py index 28782dd6..a66be4d7 100644 --- a/experiments/measure/test_r54_hosted.py +++ b/experiments/measure/test_r54_hosted.py @@ -28,6 +28,15 @@ def test_unreviewed_compiler_override_stops_before_source_checkout(self): class PublicationBoundaryTests(unittest.TestCase): + def test_public_logs_redact_long_short_escaped_and_case_variants_without_changing_other_bytes(self): + from experiments.measure.r54_publish import replacement_forms, redact_paths + forms = replacement_forms([(r'C:\Users\runneradmin', '${PROFILE}'), + (r'C:\Users\RUNNER~1', '${PROFILE}')]) + original = (b'C:\\Users\\runneradmin\\Temp\\a C:\\\\Users\\\\RUNNER~1\\\\Temp\\\\b ' + b'c:/users/runner~1/Temp/c\xff\n') + self.assertEqual(redact_paths(original, forms), + b'${PROFILE}\\Temp\\a ${PROFILE}\\\\Temp\\\\b ${PROFILE}/Temp/c\xff\n') + def test_interrupted_jsonl_tail_remains_visible_without_losing_complete_samples(self): from experiments.measure.r54_publish import publish_jsonl original = b'{"command":["/ci/work/tool.exe"],"cpu":2.0}\n{"command":['