From 0edadeebdbe159af2c16611df5fe885cd964080b Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Sun, 6 Sep 2026 04:29:29 +0300 Subject: [PATCH 1/4] Record R6 cross-platform tests and native data workflows --- harness/STATE.md | 66 ++++++++--------- harness/release-data-verification.md | 104 ++++++++++++++++----------- 2 files changed, 95 insertions(+), 75 deletions(-) diff --git a/harness/STATE.md b/harness/STATE.md index 8654f789..0bd2b388 100644 --- a/harness/STATE.md +++ b/harness/STATE.md @@ -76,23 +76,17 @@ Dedicated target D:/CodexBuilds/Capella2-data-target. Contract freeze is schema/ with full data payload and dictionary slices together; existing typed ports remain. See release-data-implementation.md and release-data-contract.md in that checkout. -Core is committed0b58107; source/migration1230ab8. Root API/docs are integrated -on the same working tree; desktop remains in flight and R6 is not accepted. -Core15 R6 +28workflow tests passed again after final allocation-arrow suppression. -Linux0b58107 full core307 tests passed (one explicit probe ignored by default), -with strict all-target core Clippy. Earlier13ports/14scenarios and115 source/lib -tests also passed. Desktop final257 tests and strict all-target Clippy pass; -optimized Windows desktop build b403039 passed. Its SHA256 is recorded in the R6 verification note; native acceptance remains pending. +R6 core/source/desktop are frozen at ab661f2. Full Windows607 tests and Linux610 +tests pass (one explicit benchmark ignored on each platform); strict workspace +all-target Clippy passes on both. Optimized desktop/server Linux build also passed. +Windows desktop261 tests include the bounded scenario value editor. Exact logs, +binaries and runtime evidence: release-data-verification.md. -Root41 server tests passed; a fourth R6 HTTP workflow now also passes, alongside all4 data HTTP tests and strict server Clippy. The original3 actual HTTP workflows for the published -data example, protocol/artifact identity, atomic rejected defaults, query/export, -reidentify/delete/restart, source3 bundle migration reports and old coupled3 -envelope upgrade without write/revision. Tests exposed dropped bundle reports and -rejected legitimate old source/model pairs; both root fixes passed retest. -Strict reST HTML generation and81 OpenAPI schema definitions passed. Actual frozen -server32033FFE imported the published example; its complete Project/StoredProject -responses passed served/current JSON Schema validation and obsolete shapes rejected. -Evidence: api-r6-contract and r6-server-tests-after.log under the release directory. +All4 R6 actual HTTP workflows pass, covering data protocols/artifact identity, +rejected defaults, qualified Call/Reply paths, validation locations, source edits, +reidentification, source3 migration and restart persistence. The published example's +actual server responses passed served/local OpenAPI validation; obsolete shapes +reject. Strict reST rendering and81 OpenAPI schemas passed. Independent core review found association transition closure pulling unrelated types and missing empty-enum warning; both corrected and focused tests passed. @@ -106,14 +100,24 @@ pages replaces unbounded inherited rows; recursive paths support explicit drill- and imported finite paths; same-phase styles/same-exchange reselection preserve valid drafts. Read-only follow-up found no new path/style defect. Paging resets only on actual layer/document changes; its regression failed before and passes now. -Root found another unresolved scale issue: scenario creation still enumerates every -carried field into both a dropdown and individual input rows. A bounded focused value editor is now implemented and under automated/independent review; actual native operation remains required before R6 acceptance. +The bounded scenario editor replaces whole-recursion enumeration and per-field +inputs with24-row browsing and a single focused value draft. The reply call picker +no longer filters alternative calls using values belonging to the old exchange. +Automated and independent checks pass; native scenario checks are next. -Current ownership: drawing_correctness owns desktop except root-owned guide.rs and -the dedicated Windows Cargo target. state_architecture_review independently reviews -R6 spec/API consistency; its data_view.rs ownership has ended. data_core runs an -isolated R3 typed-baseline experiment; Linux R6 core checkout is idle and verified. -Root owns API/OpenAPI/reST, docs, integration and native input. No concurrent writers. +Root exclusively operates native R6. The Windows13-object data model has saved +native bounds/default repair, a typed physical flow/field, allocation protocol +edit, allocation removal/Undo, and inherited-owner navigation. Association endpoint +labels/selectability were exercised. The1100x700 data layout has been inspected. +A separate53-object recursive-operation fixture was prepared with core APIs and +round-tripped for upcoming native scenario trials; fixture construction is not +claimed as native authoring. See the verification note for remaining gates. + +Parallel isolated work: drawing_correctness implements direct scenario gestures in +Capella2-scenario-direct. data_core owns typed semantic review core and +state_architecture_review owns source5/migration in Capella2-semantic-review. +The typed facet C design won the bounded experiment/criticism round; its production +plan and decision are recorded in that checkout. No overlapping writers or targets. 1. State evidence is committed and main fast-forwarded to a8f451e; DATA received the same evidence in c5276b1. Finish native data-authoring acceptance and bounded @@ -121,8 +125,8 @@ Root owns API/OpenAPI/reST, docs, integration and native input. No concurrent wr 2. Finish R6 core/source/desktop, integrate actual REST/schema/reST, independent semantic/correctness/UX review, Windows/Linux checks and real data authoring. 3. Implement R3 typed semantic drift/reconciliation after R6 freezes. Current - baselines/reconciliation only cover prose. Prefer historical typed-body snapshots - and finite proposals; avoid a duplicate recursive semantic schema without evidence. + baselines/reconciliation only cover prose. Use the experimentally selected typed facet review design C; the semantic + integration checkout records the full scope and source5 migration plan. 4. Complete direct scenario/process gestures, persistent coverage/filters, Home/recent/recovery, hosted desktop ETag workflows and offline guidance. 5. Fresh final requirements/domain/correctness/native UX/architecture review; full @@ -130,13 +134,11 @@ Root owns API/OpenAPI/reST, docs, integration and native input. No concurrent wr ## Environment and native ownership -Native input is paused after physical Escape; no R6 native trial has run. -Root exclusively owns native input. Latest saved Windows trial is window1706782, -ui-state-navigation-windows,49objects/28links/1 expected missing-owner warning. -Linux navigation trial3148598 closed normally, exec46107 exit0; baseline Linux -trial721472 also closed normally, exec72680 exit0. Independent Windows3672536 is -saved at1100x700. Older root drawing windows are saved. Re-inventory before input. -Protected user7210312/6228978 were absent; do not reset/save/close if they return. +The user explicitly reauthorized native testing after Escape. Root's current R6 +window1835476 uses the frozen ab661f2 binary and ui-r6-windows/model/project.arcadia; +13objects/4links/1 expected missing-SA-System warning, saved. Currently1100x700. +Original Capella is present. Older protected user7210312/6228978 were absent; +do not reset/save/close them if they return. Re-inventory before switching apps. Evidence: D:/CodexBuilds/Capella2-release1-01a06e2e. State source checkout/target: D:/CodexBuilds/Capella2-state-integration and -target. Linux source/target: diff --git a/harness/release-data-verification.md b/harness/release-data-verification.md index beb28433..103dd2c9 100644 --- a/harness/release-data-verification.md +++ b/harness/release-data-verification.md @@ -1,50 +1,68 @@ -# R6 data contracts — verification in progress +# R6 data contracts — native verification in progress -R6 is not accepted. Main remains at state-editing acceptance a8f451e. The updated -objective10134df9-bea2-4c02-a820-67b53d6b86f7 was read fully on2026-09-06; product -scope is unchanged and reasoning effort must match the delegated task. The full -first release remains incomplete. Native input is paused after physical Escape. +R6 is not accepted. Main remains at a8f451e. The full first-release goal remains +active and incomplete. User explicitly reauthorized native testing after Escape. -## Current evidence +## Frozen production and automated evidence -- Core0b58107: Linux307 tests pass, one explicitly ignored benchmark; strict - all-target core Clippy passes. Windows15 R6+28 workflows pass after final - allocation-edge filtering. Source migration/compatibility evidence is retained. -- Desktopb403039: Windows257 tests, strict all-target desktop Clippy and release - build pass. Binary D:/CodexBuilds/Capella2-data-target/release/arcadia-studio.exe, - SHA256 d4aa6ae7d36f429c0cb639cdf57e33cb8b99d158a9629c95a1510d24e406fab5. - The later bounded scenario editor is not covered by this binary. -- Optimized empty inheritance chains250/500/1000: Windows21.070/89.088/391.590ms; - Linux22.381/111.662/408.129ms. These are single-run validation measurements. -- Server41 prior tests passed. The new qualified Call/Reply workflow and all4 R6 - HTTP tests now pass with strict all-target server Clippy. Actual HTTP proves - distinct reused/inherited/recursive field paths, preserved expression whitespace, - phase/path422 with unchanged ETag/model/source/disk, source edits, enclosing-hop - and terminal/base reidentification, correlation and exact restart persistence. - Initial new-test failures were fixture misuse of untyped Port construction and - incorrect assumption that transaction errors carry structured issues. Tests now - use make_port and the documented command_rejected/detail plus validation endpoint. -- Published data example was imported into actual frozen server32033FFE. Complete - Project/StoredProject responses passed served/local OpenAPI validation; obsolete - shapes rejected. reST strict rendering and81 OpenAPI schemas passed. -- Independent spec review found one stale identity-only port-compatibility paragraph; - fixed to directional explicit ancestry and strict HTML rendering passed. No other - material R6 spec/API contradiction found in that review. +Data integration ab661f2: Windows607 and Linux610 workspace tests pass, one explicit +benchmark ignored each; strict workspace all-target Clippy passes on both. +Windows261 desktop tests include the focused bounded scenario editor; Linux release +desktop/server build passed. Logs under D:/CodexBuilds/Capella2-release1-01a06e2e: +r6-workspace-windows-ab661f2.log and r6-workspace-windows-clippy-ab661f2.log. +Linux logs in Capella2-data-linux-review/target/linux-verification: +workspace-ab661f2.log, workspace-clippy-ab661f2.log, release-ab661f2.log. -Logs are under D:/CodexBuilds/Capella2-release1-01a06e2e: -r6-http-paths-final.log, r6-http-all-data.log, r6-http-paths-clippy.log, -r6-server-tests-after.log and api-r6-contract. Linux core evidence is under -D:/CodexBuilds/Capella2-data-linux-review/target/linux-verification/report.md. +Windows frozen executable ui-r6-windows/arcadia-studio.exe SHA256 +C3ABD9E550E1AD6824DFE273EB27A3ABB35C5C0DA97C819DCB0AB2586AF5450C. +Current native window1835476, process session37598. No output observed; runtime.log +has not been created by Tee-Object (do not claim an empty log file). -## Active checks and remaining gates +All4 actual R6 HTTP tests pass with strict server Clippy: published data example, +protocol/artifact identity, rejected defaults, qualified reused/inherited/recursive +Call/Reply paths, phase/path422 with unchanged ETag/model/source/disk, source edits, +hop/terminal/base reidentification, correlation and restart persistence. Source3 +coupled/source bundle migrations report correctly and opening alone does not write. +Logs: r6-http-paths-final.log, r6-http-all-data.log, r6-http-paths-clippy.log. +Initial fixture errors (untyped Port and transaction-error envelope assumption) +were corrected before passing. Published example responses from server32033FFE +passed served/local OpenAPI validation; obsolete shapes rejected. Strict reST HTML +and81 OpenAPI schemas passed. One stale port compatibility paragraph was corrected. -The isolated Linux checkout was fast-forwarded to b403039; full workspace tests are -running in exec98587 with its dedicated data-linux-target. Initial filesystem wait -was verified as a live Cargo process in p9_client_rpc; it subsequently compiled. -Do not restart from an observation timeout. Bounded scenario editor production and -regressions are being tested by the desktop worker. Independent review found stale -values hiding an alternative reply call; its fix is included in that worker pass. +Optimized empty inheritance chains250/500/1000: Windows21.070/89.088/391.590ms; +Linux22.381/111.662/408.129ms. Single-run core validation timings, not UI latency. -Before acceptance: integrated Windows/Linux checks, native data/association/scenario -value workflows at normal/minimum sizes, source3 migration diagnostics, Save/reopen, -and closure of material review findings. No R6 visual or real-app acceptance claim. +## Personally observed Windows native workflows + +Loaded the isolated Engineering data source fixture. Its architecture view shows +nested fields, association role/multiplicity labels, self-reference navigation and +selectable endpoint labels. No selection-induced dirty state observed. + +Voltage maximum48→12 with default24 rejects when navigating; entered12 survives, +accepted summary remains0..48/default24, and a located default error is shown. +Repair default→12 applies together; Undo restores both old values, Redo restores +both new values. Created Cooling water with Material/Flow and contained Mass flow +rate Real1..1, unit kg/s, explicit default0.0. Save All wrote an included sa/types.arcadia +file with matching typed values, leaving13objects/4links/1 expected missing-System +warning. Navigation allocation changed Synchronous→Asynchronous; Monitoring's +separate Asynchronous/Read allocation is preserved. Removing Monitoring allocation +keeps Navigate; Undo restores the allocation and original checks. Followed inherited +Latitude from Located asset to Coordinate. Saved all edits. Data layout inspected +at1440x900 and1100x700; no overlapping controls observed. + +Separate ui-r6-scenario-windows/model/project.arcadia was constructed with the core +API from the saved native data, adding functional ports/exchange, correlated +Call/Reply, reused/inherited/recursive records and30 extra fields.53objects/5links +validate and source round-trip exactly. fixture-generator.rs retained as evidence; +temporary project example removed. Initial generator compile/load errors were +fixture-only and fixed using the bundle-aware loader; final build has no warnings. +This preparation is not native scenario authoring evidence. + +## Remaining acceptance gates + +Native scenario focused/path/phase/draft behavior and paging; actual saved reopen; +source3 migration diagnostics; Linux native data/scenario workflows. Closure of +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. From 74989b6f254e54ac77b5daed13fb59987c284533 Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Sun, 6 Sep 2026 04:40:08 +0300 Subject: [PATCH 2/4] Keep nested data field names visible in compact pickers --- crates/oa-desktop/src/data_values.rs | 150 ++++++++++++++------- crates/oa-desktop/src/forms/data_fields.rs | 7 + 2 files changed, 112 insertions(+), 45 deletions(-) diff --git a/crates/oa-desktop/src/data_values.rs b/crates/oa-desktop/src/data_values.rs index 12736cad..64241d40 100644 --- a/crates/oa-desktop/src/data_values.rs +++ b/crates/oa-desktop/src/data_values.rs @@ -11,10 +11,11 @@ pub struct FieldPathKey { pub struct FieldPathChoice { pub key: FieldPathKey, pub label: String, + pub picker_label: String, } impl std::fmt::Display for FieldPathChoice { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&self.label) + f.write_str(&self.picker_label) } } @@ -49,8 +50,7 @@ fn named_choice(project: &Project, entry: data::CarriedFieldPath) -> FieldPathCh .map(|e| format!("{} (@{})", e.name, e.alias)) .unwrap_or_else(|| id.to_string()) }) - .collect::>() - .join(" → "); + .collect::>(); let direction = if data::item_mechanism(project, entry.item) == Some(ExchangeMechanism::Operation) { match entry.direction { @@ -63,54 +63,83 @@ fn named_choice(project: &Project, entry: data::CarriedFieldPath) -> FieldPathCh } else { "" }; + let terminal = qualified + .last() + .expect("A field path always has a terminal"); + let owner_path = qualified[..qualified.len() - 1].join(" → "); + let picker_label = format!( + "{terminal}{direction} — {}{}", + project.named(entry.item), + if owner_path.is_empty() { + String::new() + } else { + format!(" / {owner_path}") + }, + ); FieldPathChoice { key: FieldPathKey { path: entry.path, field: entry.field, }, - label: format!("{} / {qualified}{direction}", project.named(entry.item)), + label: format!( + "{} / {}{direction}", + project.named(entry.item), + qualified.join(" → ") + ), + picker_label, } } +// A bounded picker must expose its distinguishing field before a long path. +// Keep the full address separately for the wrapping detail text. +fn sorted_choices(mut choices: Vec) -> Vec { + choices.sort_by_cached_key(|choice| choice.picker_label.to_lowercase()); + choices +} + pub fn choices( project: &Project, exchange: &Relation, phase: &MessageKind, ) -> Result, String> { - Ok(data::try_carried_field_paths(project, exchange)? - .into_iter() - .filter(|entry| phase_allows(project, entry, phase)) - .map(|entry| named_choice(project, entry)) - .collect()) + Ok(sorted_choices( + data::try_carried_field_paths(project, exchange)? + .into_iter() + .filter(|entry| phase_allows(project, entry, phase)) + .map(|entry| named_choice(project, entry)) + .collect(), + )) } /// Direct carried fields only: an unrelated deep branch must not prevent /// browsing a root field. Preserve the core resolver's first carried owner. pub fn roots(project: &Project, exchange: &Relation, phase: &MessageKind) -> Vec { let mut seen = std::collections::BTreeSet::new(); - exchange - .body - .items() - .iter() - .flat_map(|item| { - data::effective_fields(project, *item) - .into_iter() - .filter_map(|field| { - let SharedBody::DataField { direction, .. } = field.shared()? else { - return None; - }; - Some(data::CarriedFieldPath { - item: *item, - path: vec![], - field: field.id, - direction: *direction, + sorted_choices( + exchange + .body + .items() + .iter() + .flat_map(|item| { + data::effective_fields(project, *item) + .into_iter() + .filter_map(|field| { + let SharedBody::DataField { direction, .. } = field.shared()? else { + return None; + }; + Some(data::CarriedFieldPath { + item: *item, + path: vec![], + field: field.id, + direction: *direction, + }) }) - }) - }) - .filter(|entry| seen.insert(entry.field)) - .filter(|entry| phase_allows(project, entry, phase)) - .map(|entry| named_choice(project, entry)) - .collect() + }) + .filter(|entry| seen.insert(entry.field)) + .filter(|entry| phase_allows(project, entry, phase)) + .map(|entry| named_choice(project, entry)) + .collect(), + ) } /// Resolve authored finite paths as well as the finite representative picker list. @@ -166,20 +195,22 @@ pub fn children( } let mut path = key.path.clone(); path.push(key.field); - Ok(data::effective_fields(project, *record) - .into_iter() - .map(|field| { - named_choice( - project, - data::CarriedFieldPath { - item: entry.item, - path: path.clone(), - field: field.id, - direction: entry.direction, - }, - ) - }) - .collect()) + Ok(sorted_choices( + data::effective_fields(project, *record) + .into_iter() + .map(|field| { + named_choice( + project, + data::CarriedFieldPath { + item: entry.item, + path: path.clone(), + field: field.id, + direction: entry.direction, + }, + ) + }) + .collect(), + )) } #[cfg(test)] @@ -482,4 +513,33 @@ pub(crate) mod tests { .contains("128") ); } + #[test] + fn recursive_picker_starts_with_distinct_leaf_names_and_sorts_them() { + let (f, next) = recursive_payload(); + let exchange = &f.project.relations[&f.exchange]; + let context = FieldPathKey { + path: vec![f.origin, next, next], + field: next, + }; + let visible = children(&f.project, exchange, &MessageKind::Call, &context).unwrap(); + let leaf = visible + .iter() + .find(|choice| choice.key.field == f.leaf) + .unwrap(); + assert!(leaf.to_string().starts_with("latitude (@latitude)")); + assert!(leaf.label.contains("origin (@origin) → next (@next)")); + assert!( + visible.windows(2).all( + |pair| pair[0].to_string().to_lowercase() <= pair[1].to_string().to_lowercase() + ) + ); + assert_ne!( + visible[0].to_string().chars().take(24).collect::(), + visible[1].to_string().chars().take(24).collect::() + ); + assert_eq!( + resolve(&f.project, exchange, &MessageKind::Call, &leaf.key), + Some(leaf.clone()) + ); + } } diff --git a/crates/oa-desktop/src/forms/data_fields.rs b/crates/oa-desktop/src/forms/data_fields.rs index 97b8afbe..05f9f1e8 100644 --- a/crates/oa-desktop/src/forms/data_fields.rs +++ b/crates/oa-desktop/src/forms/data_fields.rs @@ -363,6 +363,10 @@ fn message_value<'a>( { out = out.push(text("Current address needs review. Choose an explicit path to resolve a legacy, ambiguous or incompatible value.").size(11).color(style::MUTED)); let retained = crate::data_values::FieldPathChoice { + picker_label: format!( + "{} · current address needs review", + project.named(key.field) + ), label: format!( "Current address · {} / {}", key.path @@ -377,6 +381,9 @@ fn message_value<'a>( selected = Some(retained.clone()); choices.push(retained); } + if let Some(choice) = &selected { + out = out.push(text(choice.label.clone()).size(11).color(style::MUTED)); + } let owned = path.to_owned(); out = out.push( pick_list(choices, selected, move |choice| { From f5467e50c5d510acbd0af178b9428d2ced940a87 Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Sun, 6 Sep 2026 04:43:41 +0300 Subject: [PATCH 3/4] Preserve authored source and reports through desktop migration --- crates/oa-desktop/src/app.rs | 105 ++++++++++++++++++++++++++- harness/STATE.md | 8 ++ harness/release-data-verification.md | 29 ++++++++ 3 files changed, 139 insertions(+), 3 deletions(-) diff --git a/crates/oa-desktop/src/app.rs b/crates/oa-desktop/src/app.rs index 8d395af1..ee3d5a69 100644 --- a/crates/oa-desktop/src/app.rs +++ b/crates/oa-desktop/src/app.rs @@ -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 { && 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::(); + 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"); diff --git a/harness/STATE.md b/harness/STATE.md index 0bd2b388..feae4ca5 100644 --- a/harness/STATE.md +++ b/harness/STATE.md @@ -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. diff --git a/harness/release-data-verification.md b/harness/release-data-verification.md index 103dd2c9..32f75489 100644 --- a/harness/release-data-verification.md +++ b/harness/release-data-verification.md @@ -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. From b35dede75fc8778ea695b9b2c023cfa2a1e49e09 Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Sun, 6 Sep 2026 04:56:41 +0300 Subject: [PATCH 4/4] Browse message value properties by record with bounded pages --- crates/oa-desktop/src/app.rs | 13 + crates/oa-desktop/src/data_values.rs | 14 + crates/oa-desktop/src/forms.rs | 23 +- crates/oa-desktop/src/forms/data_fields.rs | 299 +++++++++++++++------ harness/DECISIONS.md | 6 + harness/STATE.md | 24 +- harness/TASK_LEDGER.md | 20 +- harness/release-data-verification.md | 22 ++ 8 files changed, 310 insertions(+), 111 deletions(-) diff --git a/crates/oa-desktop/src/app.rs b/crates/oa-desktop/src/app.rs index ee3d5a69..07a7a591 100644 --- a/crates/oa-desktop/src/app.rs +++ b/crates/oa-desktop/src/app.rs @@ -130,6 +130,7 @@ pub enum Message { FieldShape(String, Value), FieldAppend(String, Value), FieldValuePath(String, crate::data_values::FieldPathKey), + FieldValueBrowse(String, Option, usize), FieldVariant(String, Value), FieldArray(String, Option, i32), Apply, @@ -1139,6 +1140,18 @@ impl App { self.status = error; } } + Message::FieldValueBrowse(path, scope, page) => { + if let Some(draft) = &mut self.draft + && draft + .value + .pointer(&path) + .is_some_and(|row| row.get("expression").is_some()) + { + draft + .value_browsers + .insert(path, crate::forms::ValueBrowser { scope, page }); + } + } Message::FieldValuePath(path, key) => { if let Some(draft) = &mut self.draft && let Err(error) = draft.value_path(&path, key) diff --git a/crates/oa-desktop/src/data_values.rs b/crates/oa-desktop/src/data_values.rs index 64241d40..14e10f4f 100644 --- a/crates/oa-desktop/src/data_values.rs +++ b/crates/oa-desktop/src/data_values.rs @@ -97,6 +97,7 @@ fn sorted_choices(mut choices: Vec) -> Vec { choices } +#[cfg(test)] pub fn choices( project: &Project, exchange: &Relation, @@ -142,6 +143,19 @@ pub fn roots(project: &Project, exchange: &Relation, phase: &MessageKind) -> Vec ) } +/// Browse one record at a time, including explicitly chosen recursive hops. +pub fn at_scope( + project: &Project, + exchange: &Relation, + phase: &MessageKind, + scope: Option<&FieldPathKey>, +) -> Result, String> { + match scope { + Some(key) => children(project, exchange, phase, key), + None => Ok(roots(project, exchange, phase)), + } +} + /// Resolve authored finite paths as well as the finite representative picker list. /// In particular, optional recursive Value records may be traversed repeatedly. pub fn resolve( diff --git a/crates/oa-desktop/src/forms.rs b/crates/oa-desktop/src/forms.rs index a7f30ba1..36563e68 100644 --- a/crates/oa-desktop/src/forms.rs +++ b/crates/oa-desktop/src/forms.rs @@ -32,6 +32,12 @@ pub struct Input { pub raw: String, pub editor: text_editor::Content, } +#[derive(Clone, Default)] +pub struct ValueBrowser { + pub scope: Option, + pub page: usize, +} + pub struct Draft { pub kind: RecordKind, pub original: Id, @@ -40,6 +46,7 @@ pub struct Draft { pub inputs: BTreeMap, pub exact_strings: bool, port_contract_drafts: BTreeMap, + pub value_browsers: BTreeMap, } impl Draft { @@ -77,11 +84,14 @@ impl Draft { inputs: BTreeMap::new(), exact_strings: false, port_contract_drafts: BTreeMap::new(), + value_browsers: BTreeMap::new(), }; draft.rebuild(); Some(draft) } fn rebuild(&mut self) { + // Array/variant edits can change the meaning of a row path. + self.value_browsers.clear(); self.inputs.clear(); fn visit(value: &Value, path: &str, out: &mut BTreeMap) { match value { @@ -710,10 +720,15 @@ fn reference_ids(draft: &Draft, project: &Project, path: &str) -> Vec { .. }, .. - } => project - .relations - .get(id) - .and_then(|r| crate::data_values::choices(project, r, message_kind).ok()), + } => project.relations.get(id).and_then(|r| { + let scope = address_path.split_last().map(|(&field, path)| { + crate::data_values::FieldPathKey { + path: path.to_vec(), + field, + } + }); + crate::data_values::at_scope(project, r, message_kind, scope.as_ref()).ok() + }), _ => None, }) .unwrap_or_default() diff --git a/crates/oa-desktop/src/forms/data_fields.rs b/crates/oa-desktop/src/forms/data_fields.rs index 05f9f1e8..2f87a22d 100644 --- a/crates/oa-desktop/src/forms/data_fields.rs +++ b/crates/oa-desktop/src/forms/data_fields.rs @@ -330,104 +330,152 @@ fn message_value<'a>( } => project.relations.get(id).map(|r| (r, message_kind)), _ => None, }); - let choices = context - .map(|(r, phase)| crate::data_values::choices(project, r, phase)) - .unwrap_or_else(|| Ok(vec![])); - let mut out = column![text("Qualified carried field").size(11).color(style::MUTED)].spacing(6); - match choices { - Err(error) => out = out.push(text(error).size(11).color(style::MUTED)), - Ok(mut choices) => { - let current_key = current.as_ref().map(|v| crate::data_values::FieldPathKey { - path: v.path.clone(), - field: v.field, - }); - let mut selected = current_key + let current_key = current + .as_ref() + .map(|value| crate::data_values::FieldPathKey { + path: value.path.clone(), + field: value.field, + }); + let selected = context.and_then(|(exchange, phase)| { + current_key + .as_ref() + .and_then(|key| crate::data_values::resolve(project, exchange, phase, key)) + }); + let browser = draft + .value_browsers + .get(path) + .cloned() + .unwrap_or_else(|| ValueBrowser { + scope: selected .as_ref() - .and_then(|key| choices.iter().find(|c| &c.key == key)) - .cloned() - .or_else(|| { - context.and_then(|(r, phase)| { - current_key - .as_ref() - .and_then(|key| crate::data_values::resolve(project, r, phase, key)) - }) - }); - if let Some(choice) = &selected - && !choices.iter().any(|c| c.key == choice.key) - { - choices.push(choice.clone()); - } - if selected.is_none() - && let Some(key) = current_key.clone() - && !key.field.is_nil() - { - out = out.push(text("Current address needs review. Choose an explicit path to resolve a legacy, ambiguous or incompatible value.").size(11).color(style::MUTED)); - let retained = crate::data_values::FieldPathChoice { - picker_label: format!( - "{} · current address needs review", - project.named(key.field) - ), - label: format!( - "Current address · {} / {}", - key.path - .iter() - .map(|id| project.named(*id)) - .collect::>() - .join(" → "), - project.named(key.field) - ), - key, - }; - selected = Some(retained.clone()); - choices.push(retained); - } - if let Some(choice) = &selected { - out = out.push(text(choice.label.clone()).size(11).color(style::MUTED)); - } - let owned = path.to_owned(); - out = out.push( - pick_list(choices, selected, move |choice| { - Message::FieldValuePath(owned.clone(), choice.key) - }) - .placeholder("Choose a carried field path…") - .text_size(12) - .padding(8) - .width(Fill), - ); - } + .and_then(|choice| crate::data_values::parent(&choice.key)), + page: 0, + }); + let mut out = column![text("Qualified carried field").size(11).color(style::MUTED)].spacing(6); + if let Some(choice) = &selected { + out = out.push(text(choice.label.clone()).size(11)); + } else if let Some(key) = ¤t_key + && !key.field.is_nil() + { + out = out.push( + text(format!( + "Current address needs review: {} / {}. Choose an explicit field.", + key.path + .iter() + .map(|id| project.named(*id)) + .collect::>() + .join(" → "), + project.named(key.field) + )) + .size(11) + .color(style::MUTED), + ); } - if let (Some((exchange, phase)), Some(current)) = (context, current) { - let key = crate::data_values::FieldPathKey { - path: current.path, - field: current.field, - }; - if crate::data_values::resolve(project, exchange, phase, &key).is_some() { - if let Some(parent) = crate::data_values::parent(&key) { - out = out.push( - button(text("Up to enclosing field").size(11)) + if let Some((exchange, phase)) = context { + let location = browser + .scope + .as_ref() + .and_then(|key| crate::data_values::resolve(project, exchange, phase, key)) + .map(|choice| choice.label) + .unwrap_or_else(|| "Root carried fields".into()); + out = out.push( + text(format!("Browse: {location}")) + .size(11) + .color(style::MUTED), + ); + if let Some(scope) = &browser.scope { + let mut navigation = row![button(text("↑ Up").size(11)).style(style::nav).on_press( + Message::FieldValueBrowse(path.into(), crate::data_values::parent(scope), 0) + )] + .spacing(4); + if !scope.path.is_empty() { + navigation = navigation.push( + button(text("Root fields").size(11)) .style(style::nav) - .on_press(Message::FieldValuePath(path.into(), parent)), + .on_press(Message::FieldValueBrowse(path.into(), None, 0)), ); } - match crate::data_values::children(project, exchange, phase, &key) { - Ok(children) if !children.is_empty() => { - let path = path.to_owned(); + out = out.push(navigation); + } + match crate::data_values::at_scope(project, exchange, phase, browser.scope.as_ref()) { + Ok(choices) => { + let count = choices.len(); + let (visible, page, pages) = field_page(choices, browser.page); + // Selection detail stays visible independently of browser location/page. + let visible_selection = selected + .clone() + .filter(|choice| visible.iter().any(|c| c.key == choice.key)); + let owned = path.to_owned(); + out = out.push( + pick_list(visible, visible_selection, move |choice| { + Message::FieldValuePath(owned.clone(), choice.key) + }) + .placeholder("Choose a field here…") + .text_size(12) + .padding(8) + .width(Fill), + ); + if pages > 1 { out = out.push( - pick_list( - children, - None::, - move |choice| Message::FieldValuePath(path.clone(), choice.key), - ) - .placeholder("Choose a field inside this record…") - .text_size(12) - .padding(8) - .width(Fill), + row![ + button(text("Previous").size(11)) + .style(style::nav) + .on_press_maybe((page > 0).then(|| Message::FieldValueBrowse( + path.into(), + browser.scope.clone(), + page - 1 + ))), + text(format!("{} / {pages} · {count} fields", page + 1)).size(11), + button(text("Next").size(11)) + .style(style::nav) + .on_press_maybe((page + 1 < pages).then(|| { + Message::FieldValueBrowse( + path.into(), + browser.scope.clone(), + page + 1, + ) + })) + ] + .spacing(4) + .align_y(iced::Alignment::Center), + ); + } else if count == 0 { + out = out.push( + text("No compatible fields at this location.") + .size(11) + .color(style::MUTED), ); } - Err(error) => out = out.push(text(error).size(11).color(style::MUTED)), - _ => {} } + Err(error) => out = out.push(text(error).size(11).color(style::MUTED)), } + if let Some(choice) = &selected + && browser.scope.as_ref() != Some(&choice.key) + && crate::data_values::children(project, exchange, phase, &choice.key) + .is_ok_and(|children| !children.is_empty()) + { + out = out.push( + button( + text(format!( + "Browse fields in {} →", + project.named(choice.key.field) + )) + .size(11), + ) + .style(style::nav) + .on_press(Message::FieldValueBrowse( + path.into(), + Some(choice.key.clone()), + 0, + )), + ); + } + } else { + out = out.push( + text("Choose a message exchange to browse its carried fields.") + .size(11) + .color(style::MUTED), + ); } if let Some(expression) = value.get("expression") { out = out.push(super::property( @@ -442,6 +490,25 @@ fn message_value<'a>( out.into() } +const FIELDS_PER_PAGE: usize = 24; + +fn field_page( + choices: Vec, + requested: usize, +) -> (Vec, usize, usize) { + let pages = choices.len().div_ceil(FIELDS_PER_PAGE).max(1); + let page = requested.min(pages - 1); + ( + choices + .into_iter() + .skip(page * FIELDS_PER_PAGE) + .take(FIELDS_PER_PAGE) + .collect(), + page, + pages, + ) +} + #[cfg(test)] mod tests { use super::*; @@ -497,6 +564,25 @@ mod tests { format!("{path}/expression"), "newly typed".into(), )); + let before_browse = app.draft.as_ref().unwrap().materialize().unwrap(); + for (scope, page) in [ + (None, 0), + ( + Some(crate::data_values::FieldPathKey { + path: vec![f.origin], + field: next, + }), + 999, + ), + ] { + let _ = app.update(Message::FieldValueBrowse(path.into(), scope, page)); + let _ = super::super::view(app.draft.as_ref().unwrap(), app.project()); + assert_eq!( + app.draft.as_ref().unwrap().materialize().unwrap(), + before_browse + ); + assert_eq!(app.project(), &f.project); + } let _ = app.update(Message::FieldValuePath( path.into(), crate::data_values::FieldPathKey { @@ -560,6 +646,43 @@ mod tests { let _ = super::super::view(app.draft.as_ref().unwrap(), app.project()); } + #[test] + fn field_browser_pages_every_direct_field_without_flattening_other_records() { + let f = crate::data_values::tests::wide_payload(); + let exchange = &f.project.relations[&f.exchange]; + let roots = + crate::data_values::at_scope(&f.project, exchange, &MessageKind::Call, None).unwrap(); + assert!(roots.len() > FIELDS_PER_PAGE); + assert!(roots.iter().all(|choice| choice.key.path.is_empty())); + let scope = crate::data_values::FieldPathKey { + path: vec![], + field: f.origin, + }; + let children = + crate::data_values::at_scope(&f.project, exchange, &MessageKind::Call, Some(&scope)) + .unwrap(); + assert!(children.len() > FIELDS_PER_PAGE); + assert!( + children + .iter() + .all(|choice| choice.key.path == vec![f.origin]) + ); + for choices in [roots, children] { + let (_, _, pages) = field_page(choices.clone(), 0); + let visited: Vec<_> = (0..pages) + .flat_map(|page| { + let (visible, actual, _) = field_page(choices.clone(), page); + assert_eq!(actual, page); + assert!(visible.len() <= FIELDS_PER_PAGE); + visible + }) + .collect(); + assert_eq!(visited, choices); + assert_eq!(field_page(choices, usize::MAX).1, pages - 1); + } + assert_eq!(field_page(vec![], usize::MAX), (vec![], 0, 1)); + } + #[test] fn numeric_bound_drafts_keep_partial_and_full_precision_values_out_of_accepted_state() { let mut p = Project::empty(); diff --git a/harness/DECISIONS.md b/harness/DECISIONS.md index 579d2765..a10397eb 100644 --- a/harness/DECISIONS.md +++ b/harness/DECISIONS.md @@ -63,3 +63,9 @@ State camera/tool lifetime follows effective machine and diagram identity, even when selection changes through Catalog or Layer outside Behavior. Reset only on actual context change; preserve same-view return. Independent review reproduced the leak and native Windows/Linux tests verified the correction in316dc55. + +- Carried-value property browsing follows one exact record scope at a time, with + bounded pages and a separate read-only browser location. Flattened representative + paths were proven ambiguous in native recursive/reused data. Browsing does not + change the selected field or expression; choosing a field remains an explicit + draft edit through the ordinary validated command. No persistent browser schema. diff --git a/harness/STATE.md b/harness/STATE.md index feae4ca5..cca2e587 100644 --- a/harness/STATE.md +++ b/harness/STATE.md @@ -134,10 +134,10 @@ plan and decision are recorded in that checkout. No overlapping writers or targe ## Environment and native ownership -The user explicitly reauthorized native testing after Escape. Root's current R6 -window1835476 uses the frozen ab661f2 binary and ui-r6-windows/model/project.arcadia; -13objects/4links/1 expected missing-SA-System warning, saved. Currently1100x700. -Original Capella is present. Older protected user7210312/6228978 were absent; +The user explicitly reauthorized native testing after Escape. Root's f5467e5 R6 +window3476204 and exec93768 closed normally after verified source migration and +55-object recursive scenario reopen; no runtime output. The property-browser +replacement build is running. Original Capella is present. Older protected user7210312/6228978 were absent; do not reset/save/close them if they return. Re-inventory before switching apps. Evidence: D:/CodexBuilds/Capella2-release1-01a06e2e. State source checkout/target: @@ -150,10 +150,12 @@ Windows: cargo test --locked --workspace; cargo clippy --locked --workspace 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. +Latest R6 checkpoint: Windows264 desktop tests and strict Clippy pass for the +one-record property browser; optimized build/native retest pending. Paging and +location changes retain accepted model and typed expressions. f5467e5 Windows +and Linux263 desktop tests, strict Clippy and optimized release passed. Native +Windows source3 migration preserved comments/nesting through explicit Save All +and clean source4 reopen. Native recursive55-object scenario values and paired +Call/Reply history were verified; flat property paths prompted the latest fix. +Linux native R6 workflows and final independent browser review remain. See +release-data-verification.md. Main remains a8f451e; R6 is not yet accepted. diff --git a/harness/TASK_LEDGER.md b/harness/TASK_LEDGER.md index d7a6147e..67aa3ef3 100644 --- a/harness/TASK_LEDGER.md +++ b/harness/TASK_LEDGER.md @@ -39,9 +39,13 @@ requires native workflows, semantic evaluators and fresh independent review. whole-model equality or flat reformatting. Independent counterexamples were fixed. - R3 existing-target reconciliation remains name/description only. R6 data shape expansion is active implementation, not accepted functionality. -- R6 core/source and actual HTTP semantics pass focused Windows and full Linux - core checks; desktop257 tests pass after independent draft/path/paging fixes. - Native R6 acceptance and bounded scenario-value authoring remain outstanding. +- R6 ab661f2 full suites passed Windows607/Linux610; f5467e5 desktop263 and + strict Clippy/release passed on both platforms. Native Windows data editing, + typed defaults, allocations, recursive qualified Call/Reply values, history and + saved reopening passed. Source3 migration now preserves comments and nesting. + Native found flat property browsing still ambiguous; one-record browsing with + bounded pages now passes264 desktop tests/Clippy, pending rebuilt native checks. + Linux native R6 acceptance remains outstanding. ## Assumptions and open questions @@ -51,11 +55,11 @@ requires native workflows, semantic evaluators and fresh independent review. gestures still need their own occurrence/order semantics and task verification. - Routing offers a usable initial path plus manual pins; arbitrary dense diagrams are not guaranteed crossing-free. Measured dense full solve119ms remains a limit. -- R3 typed historical bodies plus finite proposals appear simpler than a separate - recursive semantic-value schema. An isolated probe supports scalar partial review - and deleted historical references, but ordered membership/order acknowledgements - need separate typed order checkpoints. Historical source reference parsing is - still unimplemented; this remains a candidate awaiting independent review. +- R3 selected design C uses finite self-tagged typed facets, separate membership + and order acknowledgements, and transient constructor groups. Source5 historical + references are implemented in the isolated semantic checkout. Independent review + found narrow-acknowledgement/canonical-agreement/rollup defects; the worker has + added regressions and fixes. Full catalog, GUI/API/spec and acceptance remain. ## Decisions and current strategy diff --git a/harness/release-data-verification.md b/harness/release-data-verification.md index 32f75489..3a631ac1 100644 --- a/harness/release-data-verification.md +++ b/harness/release-data-verification.md @@ -95,3 +95,25 @@ Full desktop/Clippy/build and native retest are in progress; do not accept R6 ye The old Windows native window1835476 closed normally; exec37598 exited0 with no runtime output beyond a newline. Re-inventory before opening the rebuilt binary. + +## Migration retest and bounded property browsing + +f5467e5 passed263 desktop tests, strict all-target desktop Clippy and optimized +release on Windows/Linux. Frozen Windows SHA256 +33D1B2B6709BBC734E265568C7F93CB86A506497DEF3F4531669E5ABF8B2F039. +Native fresh legacy.arcadia import preserved original bytes until Save All, +displayed8defaults/2allocations/1unresolved address, and retained comments and +nested fields in its text editor. Save All kept the same file and source4 wording; +reopen was clean15objects/3links/4checks without a migration report. Saved SHA256 +A8C0A689FEA6CC352007ACB127DE4A45E05290830DE815385CFFBAB777255543. +Evidence: ui-r6-final-windows/migration/legacy.arcadia. + +The55-object recursive scenario reopened with both qualified expressions intact. +Leaf-first labels fixed the hidden terminal names, but existing-value properties +still flattened every representative path, causing repeated indistinguishable +leaf names. The follow-up browses one record at a time, with24-choice pages and +wrapping current address/location text. Up/root/page actions change only browser +state; draft field and expression are preserved.264 desktop tests and strict +Clippy passed, including wide-record page coverage and draft preservation across +recursive browsing. Optimized build and native retest remain pending. Frozen +f5467e5 window3476204 closed normally; exec93768 had no runtime output.