Preserve authored source and reports through desktop migration

This commit is contained in:
2026-09-06 04:43:41 +03:00
parent 74989b6f25
commit f5467e50c5
3 changed files with 139 additions and 3 deletions
+102 -3
View File
@@ -2612,8 +2612,14 @@ impl App {
.discovered(&disk.bundle, disk.reachable.clone());
self.show_source_file(false);
self.source_diagnostics = self.document.compiled().diagnostics.clone();
self.status =
"Source project opened. Included files and comments are preserved.".into();
self.migration = self.document.compiled().decoded.migration.clone();
if self.migration.is_some() {
self.status = "Imported earlier source schema. Review Model checks; Save all explicitly writes the upgraded source while retaining comments and includes.".into();
self.page = Page::Validation;
} else {
self.status =
"Source project opened. Included files and comments are preserved.".into();
}
}
Err(error) => {
self.canvas_document = Id::new_v4();
@@ -3243,7 +3249,9 @@ fn read_snapshot(path: PathBuf) -> Result<LoadedSnapshot, String> {
&& let Some(source_files::DiskExpectation::Bytes(bytes)) =
disk.expectations.get(&disk.bundle.entry)
&& let Ok(decoded) = persistence::decode_with_report_limited(bytes, LIMITS.model)
&& decoded.migration.is_some()
// Source1/2 require the historical single-document adapters.
// Source3+ must retain its authored bundle and token migration.
&& decoded.migration.as_ref().is_some_and(|report| report.from_schema <= 2)
{
return Ok(LoadedSnapshot::Legacy(
path,
@@ -3328,6 +3336,97 @@ mod source_project_tests {
Ok(())
}
#[test]
fn source3_native_open_preserves_report_comments_nesting_and_save_reopen() {
let original = include_str!("../../oa-core/tests/fixtures/v3-data-contract.arcadia");
for split in [false, true] {
let directory = Directory::new();
let path = directory.0.join("project.arcadia");
let mut authored = std::collections::BTreeMap::new();
if split {
let start = original.find("{\n").unwrap() + 2;
let end = original.rfind('}').unwrap();
authored.insert(
"project.arcadia",
format!(
"{} include \"dictionary.arcadia\";\n}}\n",
&original[..start]
),
);
authored.insert("dictionary.arcadia", original[start..end].to_owned());
} else {
authored.insert("project.arcadia", original.to_owned());
}
for (file, source) in &authored {
std::fs::write(directory.0.join(file), source).unwrap();
}
let mut app = App::with_project(Project::empty());
send(
&mut app,
Message::Loaded(Ok(Some(read_snapshot(path.clone()).unwrap()))),
);
assert_eq!(app.migration.as_ref().unwrap().from_schema, 3);
assert_eq!(app.page, Page::Validation);
assert_eq!(app.path, Some(path.clone()));
assert_eq!(app.document.bundle().files.len(), authored.len());
assert!(
app.dirty(),
"accepted source migration needs explicit saving"
);
for (file, source) in &authored {
assert_eq!(
std::fs::read_to_string(directory.0.join(file)).unwrap(),
*source
);
}
let text = app
.document
.bundle()
.files
.values()
.cloned()
.collect::<String>();
assert!(text.contains("// Reused record parameters retain their own identities."));
assert!(text.contains("// Frozen authored schema3 compatibility input."));
let packet = app
.project()
.elements
.values()
.find(|e| e.alias == "packet")
.unwrap()
.id;
let origin = app
.project()
.elements
.values()
.find(|e| e.alias == "origin")
.unwrap()
.id;
assert_eq!(
app.document.compiled().index.lexical_owners.get(&origin),
Some(&packet)
);
let before = app.document.snapshot();
save(&mut app, path.clone()).unwrap();
assert!(!app.dirty());
for (file, source) in &before.bundle.files {
assert_eq!(
std::fs::read_to_string(directory.0.join(file)).unwrap(),
*source
);
}
let mut reopened = App::with_project(Project::empty());
send(
&mut reopened,
Message::Loaded(Ok(Some(read_snapshot(path).unwrap()))),
);
assert!(reopened.migration.is_none());
assert_eq!(reopened.project(), app.project());
assert_eq!(reopened.document.bundle(), app.document.bundle());
assert!(!reopened.dirty());
}
}
fn pending_journal(directory: &Directory, before: Option<&str>) -> (PathBuf, PathBuf) {
let path = directory.0.join("project.arcadia");
let journal = directory.0.join(".arcadia-save-project.arcadia.journal");
+8
View File
@@ -149,3 +149,11 @@ Windows: cargo test --locked --workspace; cargo clippy --locked --workspace
--all-targets -- -D warnings; cargo build --locked -p oa-desktop -p oa-server.
WSL Ubuntu24.04 uses target/linux-cargo.toml and Mesa software Vulkan for native
WSLg. No remote push or usage reset authorized. No broad recursive target deletion.
Latest R6 checkpoint: native recursive scenario authoring passed two distinct
shared-leaf values, paired Create/Undo/Redo and save (55objects/5links). Runtime
found unreadable long-path picker names (fixed74989b6,262 desktop tests/Clippy/build)
and single-file source3 migration discarding comments on save (desktop shortcut
now corrected; actual disk include/single-file regression passes). Final build and
native retests remain. Old native exec37598 closed normally. See the updated R6
verification note; earlier ab661f2 suite evidence remains valid only for that freeze.
+29
View File
@@ -66,3 +66,32 @@ material findings before R6 acceptance. Independent semantic/correctness/spec
reviews already drove fixes; final native observations may require further review.
The broader release still needs semantic reconciliation, direct scenario/process
editing, lifecycle/hosted/help work and fresh cross-disciplinary end-state review.
## Native findings and follow-up fixes (2026-09-06)
At1100x700, the53-object recursive fixture exposed32/33 nested fields in two pages.
Native Call+Reply creation stored distinct Origin/Latitude and Destination/Latitude
expressions despite their shared terminal UUID. One Undo removed the pair; Redo
restored it. Save All wrote55objects/5links; source confirms both paths and reply
correlation. Three expected checks concern the absent SA System and two unallocated
functions. The saved evidence is ui-r6-scenario-windows/model/project.arcadia.
A third-hop popup exposed a material UI defect: repeated long path prefixes hid
all terminal field names. Fix74989b6 shows the terminal name first, sorts choices,
and retains the full address as wrapping detail text.262 desktop tests, strict
Clippy and release build passed; native retest is pending. Intermediate fixed hash
E592165A6FFFAEC64B67FF0A33FB4E78571527EE3C8F2CC457666DA6C277D5CB.
Native source3 import showed8semantic defaults,2generated allocations,1unresolved
value address and left the original hash305F19D1B79F99F8D4CF627BA2E9CA6836BB7959CC0070227815937A699EAFEA unchanged.
Its old desktop Save All path requested a new file and preserved the original, but
canonical regeneration discarded comments/nesting in the upgraded copy. This is a
material desktop/source parity defect, not a core bundle migration defect. The fix
keeps the historical single-document adapter only for source1/2; source3+ follows
bundle migration and propagates its report into Model checks. A regression passes
for actual disk single-file and included-file open, no write until explicit save,
comments, lexical ownership, report, exact saved source and clean reopened state.
Full desktop/Clippy/build and native retest are in progress; do not accept R6 yet.
The old Windows native window1835476 closed normally; exec37598 exited0 with no
runtime output beyond a newline. Re-inventory before opening the rebuilt binary.