Files
ARCADIA-Studio/harness/save-as-diagnostics-20261001.md
T

148 lines
8.8 KiB
Markdown

# Protected source destination diagnostics (#46)
Contribution for [issue 46](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/46).
Code commit `0e83157e09d52e6152df91208e41693b62da2d46` and evidence checkpoint
`046cdc1b463371c1868efcd800b3c333d7a50ac2` are published and ref-verified on
`codex/save-as-diagnostics-01a0d717-20261001`. The tested source was based on
`ea23e229260d7d050b3c3b88e77c3a851e936abe`. Merge checkpoint `8e59309cbc2fee08c4c3f9b6415c88b56c027a4a`
adds published compact Help evidence from `6ea7518e` without changing any crate,
Cargo, example, documentation or specification inputs relative to the tested code.
The bounded contribution validation below is complete. [Fresh scoped package
validation](release-save-diagnostics-validation-20261001.md) supplies later
extracted-runtime evidence and links confirmed scoped publication. Broader
follow-up integration remains separate.
Windows only; no Linux/WSL validation is claimed
or requested. The earlier #39 release remains separate and retains its old wording.
## Problem and bounded change
Source Save As preserves relative included-file paths. Existing disk expectations
are reused only when both the physical root directory and entry filename match.
Saving a multi-file project under a new entry name in the same directory therefore
establishes a new destination and refuses already-existing included files. This is
intentional protection, consistent with the visible Save As guidance and the
[source integration contract](release-source-integration.md). It does not authorize
overwriting the existing includes, even when their bytes match the loaded project.
Previously, this new-destination collision reused the core `Conflict` message
describing files changed outside the editor. That diagnosis was misleading when
no observed file had changed. A private closure in desktop `write_snapshot_inner`
now formats conflicts from `new_project` and `expect_new_file` as existing protected
destination files. It suggests a fresh directory for Save As, or Save All at the
current entry when the document has an original destination. A new-include
collision while saving an existing project instead asks the user to review that
include's destination.
Conflicts reported by `save_project` retain the external-change diagnostic: these
checks compare against established observations. Non-conflict errors retain their
existing messages. The change affects only desktop error presentation; core and
server APIs, schema, source formatting, disk expectations, no-overwrite guards,
save transactions, and document/history behavior are unchanged.
## Review and verification
Independent review found no production blocker, but identified a test-helper
compile error: `write_snapshot` returns `SaveFailure`, while the helper promised
`String`. The first frozen candidate failed with Rust E0308 at
`app/save_as_tests.rs:42`. The only correction was returning `error.message` after
dispatching the cloned failure and checking preserved editor state. The failed
run was retained rather than replaced by the passing result.
The corrected targeted run completed **29 passed, 0 failed, 0 ignored**; 1,520
tests were filtered out. Its log records the Windows GNU LLVM debug executable
under the shared `target-gnullvm` directory. This is targeted test evidence, not
a full-suite or packaged-application claim.
New boundary regressions exercise:
- Same-root/new-entry refusal with all original source bytes unchanged and no
new entry, preserving accepted snapshot, revision, raw draft, current path,
dirty state, and available Undo/Redo history.
- Fresh-root/pre-existing-include refusal before any bundle file is written,
preserving the unrelated destination bytes and editor state.
- A genuine external dependency edit retaining the external-change message and
both changed dependency and entry bytes; successful existing Save All after
restoring observed bytes; successful fresh-directory Save As with complete
source-bundle and decoded-model equality after reopening through core APIs.
Existing source collision coverage remains in
`crates/oa-core/tests/source_files.rs::new_destinations_require_explicit_missing_expectations_and_reject_collisions`.
No expectation was relaxed to make the new tests pass.
## Completed bounded acceptance and evidence
Strict all-target desktop Clippy and the GUI development build completed
successfully. The parent-observed executed commands were:
```powershell
cargo test --locked -p oa-desktop -- save_as_tests source_project_tests repair_save_state_tests --test-threads=1
cargo clippy --locked -p oa-desktop --all-targets -- -D warnings
cargo build --locked -p oa-desktop --bin arcadia-studio
```
The configured Windows GNU LLVM environment used the shared `target-gnullvm`
directory, one build job and disabled incremental compilation. Command scope is
parent-observed; the stdout logs alone do not record flags. This is not a new
full-suite result.
An independent native reviewer exercised the exact frozen desktop build, with
16 screenshots and a predeclared single Activity-name change. Same-root/new-entry
Save As refused the protected dependency with the accurate destination diagnostic;
unsaved state and authored name remained visible. Its full pointer tooltip was
readable at normal and minimum sizes, including both recovery choices. Existing
Save All and fresh-directory Save As succeeded. A separately loaded clean project
with a parent-injected valid external comment retained the genuine external-change
diagnostic and refused to overwrite it; restoring exact baseline bytes allowed
Save All recovery. The desktop closed normally with exit 0, empty stdout/stderr,
and unchanged executable/runtime hashes.
Eight byte-oracle checkpoints compare every relative filename and byte of the
37-file fixture. Collision preserved baseline bytes and created no new entry;
existing Save All and fresh Save As changed only the declared Activity name;
external refusal retained the injected comment; restoration and recovery matched
pristine bytes. Fresh Save As wrote 30 source files; the other seven companion
files were prepared by the parent, not copied by the application.
A separately pinned reused server decoded the complete pristine and saved
30-file source requests. Full returned source bundles equal those requests;
the complete parsed Project differs only in the declared Activity name.
The final independent review reconciled phase receipts, final actual directories,
requests/responses and persisted server envelopes. The parser server came from
source `715036e132677dd2bc2fb37ed316d93dc9987aec`, not a #46 rebuild. Its owned
forced termination returned 1 after acknowledged import/read; no graceful-shutdown
claim is made.
| Exact artifact | SHA256 |
| --- | --- |
| Native desktop | `e9cce9355525ecdc59bfae12608b1e0272167acef5a86b25368ef547e08886ff` |
| Runtime | `f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4` |
| Reused parser server | `6cebacc117e46fdab023c6402a5cebd6929fb55993ae8ff6b89cd1c6c1170237` |
| First failed test log | `b19127590c07949232db015b09aa965d77c93a1d0a0d1d496fb05373f2686a82` |
| Corrected targeted test log | `9079652120e18a7176feb8e5f4ac289cbf0c27f979a0c042fef5d8b4e2e252d4` |
The [byte-preserved evidence packet](experiments/save-as-diagnostics-20261001/README.md)
contains the first failure/diff/hashes, passing gate logs, launch/freeze/oracle
scripts, original native captures and receipts, parser requests/responses, donor
identity and [final independent review](experiments/save-as-diagnostics-20261001/final-review.md).
Its inventory and read-only `verify.py` allow another checkout to check hashes,
phase receipt byte sets and complete source/model equality without the local
binaries or live server store. Replaying native interaction is a separate check.
## Contribution limits and subsequent delivery
The longer persistent collision footer truncates; its pointer tooltip is readable.
Keyboard-only tooltip access remains untested. On a clean document, the header
“All changes saved” describes absence of local edits; it does not override the
explicit external-conflict footer. No exhaustive save-error, concurrency-race,
new-platform or complete OA/SA acceptance is claimed. The original contribution
review alone did not establish packaged delivery; the later
[fresh package validation](release-save-diagnostics-validation-20261001.md) and
[confirmed publication](experiments/save-diagnostics-package-20261001/publication.md)
supply that separate evidence.
The independent final review found no material blocker within this bounded
contribution. Source and its byte-preserved evidence are published, and scoped
release 9 delivers the correction. Broader follow-up integration and live
coordination remain in [Gitea issue 46](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/46).
Earlier #39 release 8 remains unchanged and does not contain this diagnostic fix.