Files
ARCADIA-Studio/harness/release-save-as-runtime-packaging.md
T

6.8 KiB

Save-as history and Windows runtime packaging — 2026-09-06

Save-as decision and evidence

Native investigation reproduced an extra Undo step after saving to a different entry basename: the first Undo reversed only the file-key rename, while the second reversed the semantic edit. Saving the undone state also cleared Redo. Message::Saved had committed the rebased receipt through Document::apply_bundle.

The fix adopts a verified save receipt as a source-location change, without adding history or clearing Redo. Uniform entry names across retained history are rebased together, preserving exact source text, model meaning, and stack lengths. If history contains explicitly authored entry-name changes, historical snapshots retain those names; adoption changes only the current snapshot. Revision and receipt-content checks reject stale or altered receipts, and raw drafts also prevent a late receipt from changing their source location.

Before disk I/O, source Save-as rejects a chosen basename that collides (case-insensitively) with a non-entry file in any retained current/past/future snapshot. This conservative restriction avoids swapping historical files or rewriting includes. JSON export is exempt. All planned snapshots must compile to the same models and exact relocated source before adoption; failure leaves history unchanged. The bounded history may be compiled during both preflight and receipt adoption. Revisit that cost only with measured latency evidence.

The focused cargo test --locked -p oa-desktop save_as run passed 11 tests, 0 failures (.local/save-as-focused-test.log). Seven new regressions cover uniform history and existing Redo, explicit entry-name history, past/future filename collisions, stale/changed receipts, actual disk write receipts followed by Undo/save/Redo, rejection before disk I/O, and preservation of a newer raw draft. Implementation: document.rs, document_save_as_tests.rs, app.rs, and app/save_as_tests.rs under crates/oa-desktop/src.

Fixed-binary native Save-as acceptance remains pending. Recheck with a recorded binary hash: apply a semantic change; Save-as to a new basename; one model Undo must restore the original semantics and exact original source text; save that undone state; Redo must remain available and restore the edited text. Reopen the saved file to confirm disk still contains the explicitly saved undone state until another Save. Repeat Save-as with available Redo and verify a historical filename collision is refused before creating the destination. Record source hashes before edit, after edit, and after Undo. A separate successful state-view routing check does not establish this result.

Observed GNU/LLVM runtime closure

Read-only PE import inspection used LLVM-MinGW 20260826 UCRT llvm-readobj --coff-imports; no builds, application launches, system changes, or runtime copying were performed for this inspection. These are the inspected debug outputs, not release packages:

File under .local/target-gnullvm/debug Bytes SHA-256
arcadia-studio.exe 101734912 70069d6cbbe1917e1597794b3e190ff9cf23664d458f794b3270ddbe6ee683a2
arcadia-server.exe 37165056 fc942ecf222a2032eb5e28c68d1125ef09fd15cc81864dd77eeb119af8fdae48

Both import libunwind.dll directly. It is the only non-Windows dependency in their observed static import closure. The x86_64 runtime is at .local/toolchain/llvm-mingw-20260826-ucrt-x86_64/x86_64-w64-mingw32/bin/libunwind.dll: 190976 bytes, SHA-256 f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4. The toolchain's top-level bin/libunwind.dll is byte-identical.

That DLL recursively imports only KERNEL32 and UCRT API sets (stdio, runtime, environment, private, filesystem, locale, convert, string, heap). Neither binary nor libunwind imports libc++, libwinpthread, libomp, LLVM, Clang, or sanitizer DLLs. The remaining executable imports are Windows API sets and OS DLLs: kernel32, user32, ole32/oleaut32, bcrypt/bcryptprimitives, advapi32, dwmapi, gdi32, shell32, imm32, uxtheme, ws2_32, ntdll, and opengl32 (case-insensitive union).

The root's observed failure without toolchain PATH and successful launch with it is consistent with the missing libunwind import. Staging the required runtime next to both executables uses the ordinary application-directory DLL lookup; no registry or machine PATH change is needed. See Microsoft's DLL search order. Include the LLVM-MinGW distribution's LICENSE.TXT (LLVM Apache-2.0 with LLVM Exceptions and included notices) alongside runtime provenance. Do not copy OS DLLs from System32 or the whole compiler directory.

Static imports are not the complete graphics-runtime test: the resolved WGPU/ash implementation can load backend DLLs dynamically (for example vulkan-1.dll, and optional DXC paths). Import inspection cannot establish driver compatibility. Repeat inspection against the actual final binaries and perform the clean-environment staged smoke in Windows packaging.

Packaging baseline and remaining gates

At inspection, no tracked packaging builder existed. harness/verification-v2-packages.md describes historical staging/archive checks, but its D: evidence and dist outputs are absent here. .github/workflows/ci.yml builds a Windows/Linux matrix and uploads executable-only artifacts; it is not a GNU/LLVM dependency staging recipe. The repository origin is GitLab and no GitLab pipeline is present. CI is unchanged. The Docker build-context regression was separately corrected with COPY build ./build; no Docker execution is claimed.

The new scripts/package-windows.ps1 provides a repeatable packaging operation for explicitly selected, already-built x86_64 MSVC or gnullvm inputs. It must not imply a release build or acceptance simply because packaging succeeds. Current native Save-as recheck, clean-PATH staged desktop/server operation, final release-build import inspection, and release acceptance remain separate gates.

Script verification on this machine packaged the existing debug gnullvm inputs into ignored .local/package-script-qa/ArcadiaStudio-qa-debug-20260906-a-x86_64-pc-windows-gnullvm.zip: 42 files, 27747149 bytes, SHA-256 8935db6c0fb1e02366b2354139bc1bb5ac111ec438f319fad32121e73cf19559. Staged-source and archive-entry hash/count verification passed. Separate refusal checks passed for an existing output name, missing executable inputs, and selecting MSVC while supplying binaries that import the unstaged LLVM runtime. No application was launched by this verification, and no actual MSVC binary package was available to test. The script's final additional check binds staging to the binary hash inspected before import scanning, rejecting binaries changed during packaging.