From 208268c8aa7f6bc3c2bab6a3c0657358f3f7dc23 Mon Sep 17 00:00:00 2001
From: Codex-ytr83r
Rename alias (F2 while the source editor has focus) changes the alias +under the caret or its exact selection. It requires a unique authored identity +in the complete accepted source bundle, with no pending source, property or +behavior drafts and no extra loaded detached files. Accepted but unsaved source +is eligible. The operation MUST NOT implicitly apply a draft or allocate an ID. +The engineering name and UUID remain unchanged.
+The Source alias field does not trim or normalize the entered alias. Pasting +line breaks, tabs or other control characters is explicitly rejected as a whole: +the field and its selection remain unchanged, and any previous preview approval +is invalidated. Preview +prepares a typed alias change and displays every changed file and source line; +comments, strings, engineering data, file membership and declaration ownership +remain unchanged. Enter in the field requests Preview, never confirmation. +The preview is for this operation against accepted source, so a later Save may +also contain earlier accepted edits. A changing rename requires enough model +history capacity to retain its immediate Undo. An invalid, identical, stale or +oversized candidate cannot enable confirmation.
+The preview MUST provide access to all admitted files, hunks, lines and long-line +segments. Refuse a candidate whose complete preview exceeds the editor's bounds: +256 changed files, 50,000 changed lines or 8 MiB of displayed source bytes +(both versions of changed/context lines and file paths). Index metadata is +separately bounded to seven retained line records per changed line. These +limits do not restrict the language itself. A changed-line count is not a count +of semantic references. Cancel, Preview and Rename alias remain reachable +outside the independently scrolling source preview.
+Explicit Rename alias confirms the current preview once, as one accepted +model/source transaction. A source, document, recovery or replacement change +invalidates its approval even if later bytes match the old preview. Closing the +form cancels approval; a late worker result MUST NOT reopen it. Rejected, +canceled and unchanged operations preserve accepted bytes, drafts, save state, +revisions, selection and both histories. Successful rename selects the new alias +at the original occurrence rather than the first matching spelling in the file. +Editing the replacement permits a new Preview in the same form. After a source +context change, close the form and invoke Rename again on the current alias.
+Undo rename is guarded against intervening edits and uses model history; +the persistent Undo model and Redo model controls restore the complete +accepted snapshots. Text Ctrl+Z remains Undo text. Save is separate and +uses the ordinary guarded source-save contract. An unconfirmed preview and Undo +history are not persisted on reopening.
Changing a graphical UUID must atomically update map keys and every reference.
Alias changes preserve UUID identity. Deletion must account for owned elements,
incident relationships, ordered occurrences, and diagram placements without
diff --git a/docs/language.rst b/docs/language.rst
index 02452f17..0116a562 100644
--- a/docs/language.rst
+++ b/docs/language.rst
@@ -2109,6 +2109,50 @@ target. Camera movement preserves a valid marker; changing the selected record,
document, accepted revision or represented context retires it. Navigation does
not alter allocation ownership or the meaning of Delete.
+**Rename alias** (``F2`` while the source editor has focus) changes the alias
+under the caret or its exact selection. It requires a unique authored identity
+in the complete accepted source bundle, with no pending source, property or
+behavior drafts and no extra loaded detached files. Accepted but unsaved source
+is eligible. The operation MUST NOT implicitly apply a draft or allocate an ID.
+The engineering name and UUID remain unchanged.
+
+The **Source alias** field does not trim or normalize the entered alias. Pasting
+line breaks, tabs or other control characters is explicitly rejected as a whole:
+the field and its selection remain unchanged, and any previous preview approval
+is invalidated. **Preview**
+prepares a typed alias change and displays every changed file and source line;
+comments, strings, engineering data, file membership and declaration ownership
+remain unchanged. Enter in the field requests Preview, never confirmation.
+The preview is for this operation against accepted source, so a later Save may
+also contain earlier accepted edits. A changing rename requires enough model
+history capacity to retain its immediate Undo. An invalid, identical, stale or
+oversized candidate cannot enable confirmation.
+
+The preview MUST provide access to all admitted files, hunks, lines and long-line
+segments. Refuse a candidate whose complete preview exceeds the editor's bounds:
+256 changed files, 50,000 changed lines or 8 MiB of displayed source bytes
+(both versions of changed/context lines and file paths). Index metadata is
+separately bounded to seven retained line records per changed line. These
+limits do not restrict the language itself. A changed-line count is not a count
+of semantic references. Cancel, Preview and Rename alias remain reachable
+outside the independently scrolling source preview.
+
+Explicit **Rename alias** confirms the current preview once, as one accepted
+model/source transaction. A source, document, recovery or replacement change
+invalidates its approval even if later bytes match the old preview. Closing the
+form cancels approval; a late worker result MUST NOT reopen it. Rejected,
+canceled and unchanged operations preserve accepted bytes, drafts, save state,
+revisions, selection and both histories. Successful rename selects the new alias
+at the original occurrence rather than the first matching spelling in the file.
+Editing the replacement permits a new Preview in the same form. After a source
+context change, close the form and invoke Rename again on the current alias.
+
+**Undo rename** is guarded against intervening edits and uses model history;
+the persistent **Undo model** and **Redo model** controls restore the complete
+accepted snapshots. Text ``Ctrl+Z`` remains **Undo text**. Save is separate and
+uses the ordinary guarded source-save contract. An unconfirmed preview and Undo
+history are not persisted on reopening.
+
Changing a graphical UUID must atomically update map keys and every reference.
Alias changes preserve UUID identity. Deletion must account for owned elements,
incident relationships, ordered occurrences, and diagram placements without
diff --git a/harness/experiments/navigation-rename-union-20260912/.gitattributes b/harness/experiments/navigation-rename-union-20260912/.gitattributes
new file mode 100644
index 00000000..37d85e34
--- /dev/null
+++ b/harness/experiments/navigation-rename-union-20260912/.gitattributes
@@ -0,0 +1,11 @@
+# Exact archived source/provenance/receipt bytes; do not normalize line endings.
+/before-details-fix/crates/oa-desktop/src/app/source_rename.rs -text whitespace=cr-at-eol
+/before-details-fix/crates/oa-desktop/src/app/source_rename/preview_scroll_tests.rs -text whitespace=cr-at-eol
+/before-details-fix/manifest.json -text whitespace=cr-at-eol
+/details-fix-hashes.json -text whitespace=cr-at-eol
+/final-source-hashes.json -text whitespace=cr-at-eol
+/formatting.json -text whitespace=cr-at-eol
+/import-provenance.json -text whitespace=cr-at-eol
+/initial-source-hashes.json -text whitespace=cr-at-eol
+/pre-format-source-hashes.json -text whitespace=cr-at-eol
+/artifacts.json -text whitespace=cr-at-eol
diff --git a/harness/experiments/navigation-rename-union-20260912/README.md b/harness/experiments/navigation-rename-union-20260912/README.md
new file mode 100644
index 00000000..ad23462a
--- /dev/null
+++ b/harness/experiments/navigation-rename-union-20260912/README.md
@@ -0,0 +1,75 @@
+# Selective navigation and Text alias rename union
+
+This is prepared source and static review evidence. **The combined union has not been compiled, tested or exercised natively.** Formatting and source-hash checks do not establish those results. The integration owner retains publication and runtime acceptance; peer-owned compact Text layout work is outside this change.
+
+## Pinned inputs and dependency boundary
+
+- Our base is [4db1ef543ced916179194272bf0e65dce73cb107](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/commit/4db1ef543ced916179194272bf0e65dce73cb107), preserving the evidence bytes for navigation production [46b4f3c0d0f04050ad6d705051ee0199138e47a2](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/commit/46b4f3c0d0f04050ad6d705051ee0199138e47a2).
+- Peer rename source is [cbc49a7802fb1bba0dd284fd904c700a0703ae70](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/commit/cbc49a7802fb1bba0dd284fd904c700a0703ae70). Its production delta is [dfb6102ba5aec9e26a48cc5472b51a4b349459fd](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/commit/dfb6102ba5aec9e26a48cc5472b51a4b349459fd) plus the mandatory `cbc49a7` scroll correction, against [be7a8cd8d7d63aa18e0196bbd36f9e646764c761](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/commit/be7a8cd8d7d63aa18e0196bbd36f9e646764c761). Intervening `4686d05` contains evidence, not production dependencies.
+- [Import provenance](import-provenance.json) records all 24 peer files and 10 corresponding baseline files. All 34 raw downloads were checked against published Gitea Git blob hashes; SHA-256 and sizes are retained.
+
+The union changes 27 source/documentation paths: 25 Rust files and two language documents. Document/query prerequisites were identical to the peer baseline; 14 new files were added and shared App/view/documentation hunks were merged selectively. The entire core tree and the existing `examples/release1` timing fixture match the peer. No core/schema, dependency manifests, lockfile, allocation/Delete semantics, user specification or historical evidence was replaced. Existing camera, lifecycle, repair, exact navigation focus and grapheme behavior remains in the integration base.
+
+## Source review findings and corrections
+
+These findings concern the combination of pinned branches. They do not retroactively assert defects in either branch's isolated acceptance evidence. The initial boundaries were published in [issue 17 comment 717](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/17#issuecomment-717).
+
+| Finding | Correction and evaluator |
+| --- | --- |
+| Diagram usage dispatch precedes generic modal handling, so merely adding a Rename modal gate permits queued diagram Open over Rename. | Both admissions now exclude the other chooser; source navigation and Rename retain reference chooser exclusions. Real App tests cover Rename with an existing approval and both loading/ready diagram choosers. |
+| A Rename completion arriving after Close and diagram navigation can cancel the newer deferred camera/focus during outer reconciliation. Worker slots also survive document replacement. | Completion is passive in reveal reconciliation and releases only its exact slot before modal gates. Tests cover target/preview, forged/duplicate completion, first measurement, and all three real outstanding workers across reset. |
+| Rejected old Close/Confirm must be inert before outer source/camera reconciliation. Captured Begin and Undo Rename have an additional queued-intent boundary. | Envelope checks run before reconciliation. Begin still requires Text; Undo Rename still requires its existing live-context predicate. Tests retain a real old approval and exercise stale Begin/Close/Confirm and queued Undo Rename after diagram navigation. Ordinary model Undo/Redo preserves the exact accepted snapshot stack. |
+| Independent review found a P2 Details/Preview visit gap: a held File-navigation snap could target the same preview identity after returning from Details and erase later manual scrolling. | An actual Details visibility change rotates the visit UUID without changing file/hunk/line/segment or scheduling a scroll reset. Repeated same-value visibility is inert. The retained-widget test exercises held reset → Details → Preview → manual scroll → held reset, including both mounted and between-frame Details transitions. |
+
+The integration owner reported an independent static review approving the final Details correction, with both corrected pre-format hashes matching [details-fix-hashes.json](details-fix-hashes.json), and no further finding. This was source review, not test/native evidence. Formatting subsequently changes presentation only; the final manifest identifies the resulting inputs for future gates.
+
+The existing `preview_destination` UUID remains paired in the mounted widget and every page/approval scroll operation. The Details correction does not force a return to the top. If Details is actually mounted, the returning preview follows Iced's ordinary widget-state lifecycle; if both switches happen between frames, the retained scroll state remains subject to the existing contract. In either case, an older operation cannot address the new visit.
+
+## Exact source and artifact records
+
+- [Initial frozen union hashes](initial-source-hashes.json): the initial 27-path handoff before the Details correction.
+- [Reviewed Details fix hashes](details-fix-hashes.json): the two changed files before formatting.
+- [Pre-format hashes](pre-format-source-hashes.json): all 27 inputs after the accepted Details correction.
+- [Final source hashes](final-source-hashes.json): all 27 inputs after bounded formatting; use these to identify the next compiler inputs.
+- [Formatting receipt](formatting.json): formatter version, exact relative argument list, changed paths, check exit and checks against tracked inputs outside the owned set.
+- [Raw artifact hashes](artifacts.json) and [scoped attributes](.gitattributes): exact archived bytes and text-conversion policy.
+
+The two independently archived pre-fix Rust files are [source_rename.rs](before-details-fix/crates/oa-desktop/src/app/source_rename.rs) and [preview_scroll_tests.rs](before-details-fix/crates/oa-desktop/src/app/source_rename/preview_scroll_tests.rs). Their [original manifest](before-details-fix/manifest.json) is copied unchanged. These copies intentionally retain the reviewed old behavior and must not be compiled as current sources or reformatted. Exact `-text` entries preserve their raw bytes and the checksum-bound receipts. The current implementation is in [the App rename controller](../../../crates/oa-desktop/src/app/source_rename.rs).
+
+Formatting used the local `rustfmt` binary with edition 2024 and `skip_children=true` over only the 25 named Rust files. The preceding leaf-only `--check` found expected formatting differences; the subsequent all-owned-file format/check receipt records completion. No Cargo command, compiler, test, native UI or staging/publication operation was performed during this preparation.
+
+## Evaluators to run
+
+The six combined App tests use a parsed four-file Unicode/CRLF fixture with an explicitly identified distant placement. They dispatch actual App events, produce worker completions independently without polling the returned workers, and check whole model/source, accepted snapshot identity, history, semantic/visual selection and actual deferred viewport measurements.
+
+The four retained-widget tests execute real scroll operations on the production dialog widget tree with a CPU font/layout renderer. They do not establish native GPU paint or package behavior.
+
+These group filters must select **six** and **four** tests respectively; do not substitute filename filters:
+
+```text
+cargo test --locked --offline -p oa-desktop app::source_rename::tests::navigation_union_tests:: -- --test-threads=1
+cargo test --locked --offline -p oa-desktop app::source_rename::tests::preview_scroll_tests:: -- --test-threads=1
+```
+
+Exact individual filters:
+
+```text
+app::source_rename::tests::navigation_union_tests::rename_modal_rejects_queued_diagram_and_source_navigation_without_losing_approval
+app::source_rename::tests::navigation_union_tests::loading_and_ready_diagram_choosers_reject_a_previously_captured_rename_begin
+app::source_rename::tests::navigation_union_tests::late_target_and_preview_results_release_only_their_slot_and_preserve_first_camera_measurement
+app::source_rename::tests::navigation_union_tests::stale_begin_close_and_actual_confirm_leave_new_diagram_focus_and_pending_measurement_unchanged
+app::source_rename::tests::navigation_union_tests::document_reset_retains_all_three_worker_slots_until_their_exact_results_arrive
+app::source_rename::tests::navigation_union_tests::rename_then_exact_caret_diagram_navigation_preserves_complete_model_undo_redo_history
+app::source_rename::tests::preview_scroll_tests::explicit_navigation_resets_retained_scroll_but_id_change_alone_does_not
+app::source_rename::tests::preview_scroll_tests::delayed_page_and_approval_operations_cannot_reset_a_new_destination
+app::source_rename::tests::preview_scroll_tests::repeated_page_visits_filters_and_fast_preview_completion_have_distinct_destinations
+app::source_rename::tests::preview_scroll_tests::details_round_trip_retires_held_reset_without_changing_page_or_repeated_visibility_scroll
+```
+
+Additional relevant groups are `source_rename`, `document::alias_rename::tests::`, `app::diagram_usages::tests::`, and `app::diagram_reveal::tests::`. The existing isolated timing filters are `accepted_release1_prepare_commit_sync_and_confirm_timing` and `accepted_release1_constructor_vs_reuse_through_next_highlight`, each run alone with `--ignored --nocapture --test-threads=1` when the integration owner schedules those trials.
+
+Compilation, focused/full regression gates, strict lint, matching build and native navigation/rename/Save/Undo/Redo/package acceptance remain open. The peer's published source/native/package evidence remains tied to its own identified source and executable, not this union. The existing permanent Text layout is retained; compact command/layout work remains with the peer's separate scope.
+
+The [prepared native acceptance workflows](native-acceptance.md) cover preview visibility/scroll, mutual modal input ownership, immediate keyboard editing, diagram navigation and complete source/disk/history restoration. They have not been executed on this union.
+
+Parent staging also checks added files. Its initial cached whitespace check identified original CRLF bytes in three checksum-bound JSON artifacts; exact raw-artifact attributes now allow CR at line endings while retaining ordinary whitespace checks. No archived bytes or source were changed by this correction. The earlier working-tree diff check did not cover those then-untracked artifacts.
diff --git a/harness/experiments/navigation-rename-union-20260912/artifacts.json b/harness/experiments/navigation-rename-union-20260912/artifacts.json
new file mode 100644
index 00000000..1dace165
--- /dev/null
+++ b/harness/experiments/navigation-rename-union-20260912/artifacts.json
@@ -0,0 +1,59 @@
+{
+ "files": [
+ {
+ "path": "before-details-fix/crates/oa-desktop/src/app/source_rename.rs",
+ "bytes": 45315,
+ "sha256": "7b13c39d4c1509d13aef2de4580b9e418cf7ac1ae87d42bd21dcd34ecc70f863",
+ "git_blob": "eee376e2461477a4ac123c849fb165d9e2867b2b"
+ },
+ {
+ "path": "before-details-fix/crates/oa-desktop/src/app/source_rename/preview_scroll_tests.rs",
+ "bytes": 10937,
+ "sha256": "06c8dc66b696f70427a190cd174be373a8114bd2f49b6e8f1152173d59e9ec29",
+ "git_blob": "4641cf7f8db309b12c7bd668dd4ea771cb456fa6"
+ },
+ {
+ "path": "before-details-fix/manifest.json",
+ "bytes": 595,
+ "sha256": "4ac41b15970e9525b5def9af9eb0d57eaa9d3919dd2dd6fe9c4929a60cb17aa6",
+ "git_blob": "4507b73945f1660a9c1e9a0ea3064d1d40b7b764"
+ },
+ {
+ "path": "details-fix-hashes.json",
+ "bytes": 494,
+ "sha256": "275a692bda781a561c0a50c9af1900c21db42327366daed5ec54a6ade2c1b810",
+ "git_blob": "da4aa80d6ab9cb752fc398337f2e12a63a10d07c"
+ },
+ {
+ "path": "final-source-hashes.json",
+ "bytes": 6679,
+ "sha256": "a1c007d3d44da805b840423ea6950811c1b43dc780c753164320105fb1296f0b",
+ "git_blob": "616cc048be1c7bee62bd12e73a493c2a7b57ff20"
+ },
+ {
+ "path": "formatting.json",
+ "bytes": 1986,
+ "sha256": "14b0812cb176296f07fa7712dfc9fc5e5a9cc94ec10a4038961e469ab0650647",
+ "git_blob": "d0ca466fbaa24abf1270c56e3cfe3842458458c4"
+ },
+ {
+ "path": "import-provenance.json",
+ "bytes": 10539,
+ "sha256": "9761b644ca7c5a3cbcc543834848170c3baa27c6f80093c68a8f64d0c3677b30",
+ "git_blob": "1fe1da89a3ddf54af931ac9f3c9e3d537fd422fd"
+ },
+ {
+ "path": "initial-source-hashes.json",
+ "bytes": 7723,
+ "sha256": "fbc1109e039150265dbdc1d3c7ffda2279b7323468488732c776f67515b78e66",
+ "git_blob": "291589c30276eb7f7000daa8ee01f3feb613b531"
+ },
+ {
+ "path": "pre-format-source-hashes.json",
+ "bytes": 6679,
+ "sha256": "d49583b87bb12655fd96c17c1629b832b6389aeddf98cc986ad97c7c19282f13",
+ "git_blob": "e746e7a36318fce9ddf607122006f2088343d89b"
+ }
+ ],
+ "note": "Raw archived inputs and receipts. This manifest and .gitattributes intentionally do not hash themselves."
+}
diff --git a/harness/experiments/navigation-rename-union-20260912/before-details-fix/crates/oa-desktop/src/app/source_rename.rs b/harness/experiments/navigation-rename-union-20260912/before-details-fix/crates/oa-desktop/src/app/source_rename.rs
new file mode 100644
index 00000000..eee376e2
--- /dev/null
+++ b/harness/experiments/navigation-rename-union-20260912/before-details-fix/crates/oa-desktop/src/app/source_rename.rs
@@ -0,0 +1,1223 @@
+//! Editor-local, explicitly approved alias transactions. Workers own immutable
+//! snapshots; only the live form can approve adoption into the current document.
+use super::*;
+use crate::{
+ document::PreparedAliasRename,
+ source_navigation::{self as nav, query},
+ source_rename::{origin, preview},
+};
+mod alias_input;
+mod editor_patch;
+const LINES_PER_PAGE: usize = 8;
+
+// A transient display hint from the same approved candidate. Document authority,
+// model synchronization and source ownership remain with their existing paths.
+pub(super) struct EditorRefresh<'a> {
+ path: &'a str,
+ before: &'a str,
+ after: &'a str,
+}
+
+impl EditorRefresh<'_> {
+ pub(super) fn apply(self, editor: &mut text_editor::Content, path: &str, source: &str) -> bool {
+ self.path == path
+ && self.after == source
+ && editor_patch::replace(editor, self.before, self.after)
+ }
+}
+
+#[derive(Debug, Clone, PartialEq)]
+pub struct Begin {
+ pub document: Id,
+ pub revision: u64,
+ pub source: query::SnapshotKey,
+ pub path: String,
+ pub cursor: text_editor::Cursor,
+}
+
+#[derive(Debug, Clone)]
+pub enum Event {
+ Begin(Begin),
+ Input(Id, String),
+ PasteRejected(Id),
+ Preview(Id, Id),
+ Confirm(Id, Id, Id),
+ Close(Id),
+ Search(Id, String),
+ File(Id, Id, bool),
+ Hunk(Id, Id, bool),
+ Line(Id, Id, bool),
+ Segment(Id, Id, bool),
+ Details(Id, bool),
+ DetailSegment(Id, bool),
+ ReadOnly(Id, text_editor::Action),
+ Undo(Id),
+}
+
+#[derive(Debug, Clone)]
+struct Context {
+ begin: Begin,
+ accepted: Arc