diff --git a/.github/scripts/check-packaged-agent-proof.py b/.github/scripts/check-packaged-agent-proof.py index 9cdc0208..4af53933 100644 --- a/.github/scripts/check-packaged-agent-proof.py +++ b/.github/scripts/check-packaged-agent-proof.py @@ -2463,13 +2463,47 @@ def plugin_stdio_handoff( f"could not derive release target from {archive.name}", ) prior_dir = plugin_data / "codestory-cli" / prior_version - prior_bin = prior_dir / "bin" / ("codestory-cli.cmd" if os.name == "nt" else "codestory-cli") + prior_bin = prior_dir / "bin" / ( + "codestory-cli.exe" if os.name == "nt" else "codestory-cli" + ) prior_bin.parent.mkdir(parents=True) if os.name == "nt": - prior_bin.write_text( - f"@echo off\r\nif \"%1\"==\"--version\" (echo codestory-cli {prior_version}& exit /b 0)\r\nexit /b 90\r\n", + prior_source = prior_dir / "rollback-version.rs" + prior_source.write_text( + f'''fn main() {{ + let args = std::env::args().skip(1).collect::>(); + if args.len() == 1 && args[0] == "--version" {{ + println!("codestory-cli {prior_version}"); + return; + }} + std::process::exit(90); +}} +''', encoding="utf-8", ) + compiled = subprocess.run( + ["rustc", str(prior_source), "-o", str(prior_bin)], + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + timeout=timeout_secs, + check=False, + ) + require( + compiled.returncode == 0 and prior_bin.is_file(), + "managed_plugin_convergence", + artifact, + f"could not compile native rollback fixture: {compiled.stderr}", + ) + pe = prior_bin.read_bytes() + pe_offset = int.from_bytes(pe[0x3C:0x40], "little") + machine = int.from_bytes(pe[pe_offset + 4 : pe_offset + 6], "little") + require( + machine == {"windows-x64": 0x8664, "windows-arm64": 0xAA64}.get(target), + "managed_plugin_convergence", + artifact, + f"native rollback fixture machine 0x{machine:04x} did not match {target}", + ) else: prior_bin.write_text( f"#!/bin/sh\nif [ \"$1\" = \"--version\" ]; then echo 'codestory-cli {prior_version}'; exit 0; fi\nexit 90\n", diff --git a/.github/workflows/post-publish-release-smoke.yml b/.github/workflows/post-publish-release-smoke.yml index 6c97be94..c877cb8d 100644 --- a/.github/workflows/post-publish-release-smoke.yml +++ b/.github/workflows/post-publish-release-smoke.yml @@ -18,6 +18,7 @@ permissions: contents: read env: + RELEASE_RUST_TOOLCHAIN: "1.95.0" APPLE_DEVELOPER_TEAM_ID: "PKUJNR8D6F" jobs: @@ -154,6 +155,13 @@ jobs: shell: pwsh run: pwsh -File scripts/install-codestory.ps1 -SelfTest + - name: Install pinned Rust for Windows rollback proof + if: runner.os == 'Windows' + shell: pwsh + run: | + rustup toolchain install "${{ env.RELEASE_RUST_TOOLCHAIN }}" --profile minimal + rustup default "${{ env.RELEASE_RUST_TOOLCHAIN }}" + - name: Prove managed plugin handoff run: >- python .github/scripts/check-packaged-agent-proof.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d357bdd..57b44350 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,9 @@ rollback. The Codex worktree setup dispatcher now owns one version-checked, locked setup path for Windows, macOS, and Linux; the shell and PowerShell entrypoints are thin compatibility adapters. +- Windows packaged upgrade proof now seeds rollback with a native executable + fixture, preserving direct-process verification after batch CLI overrides + became unsupported. - The packaged plugin now launches the CodeStory CLI directly without a shell and rejects Windows batch-file overrides. Managed CLI, model, and native backend downloads enforce declared byte limits while streaming and remove