From dfb6102ba5aec9e26a48cc5472b51a4b349459fd Mon Sep 17 00:00:00 2001
From: "sorokin.oleg.edu"
Date: Sat, 12 Sep 2026 15:01:08 -0700
Subject: [PATCH] Add guarded Text alias rename with complete preview and
editor reuse
---
.gitattributes | 3 +
crates/oa-desktop/src/app.rs | 62 +-
crates/oa-desktop/src/app/source_rename.rs | 1172 ++++++++++++++
.../src/app/source_rename/alias_input.rs | 219 +++
.../app/source_rename/alias_input/tests.rs | 220 +++
.../src/app/source_rename/editor_patch.rs | 303 ++++
.../app/source_rename/preview_glyph_tests.rs | 445 ++++++
.../oa-desktop/src/app/source_rename/tests.rs | 1415 +++++++++++++++++
.../app/source_rename_layout_timing_tests.rs | 313 ++++
.../src/app/source_rename_timing_tests.rs | 347 ++++
crates/oa-desktop/src/app/source_symbols.rs | 5 +-
crates/oa-desktop/src/document.rs | 18 +-
.../oa-desktop/src/document_alias_rename.rs | 233 +++
.../src/document_alias_rename_tests.rs | 459 ++++++
crates/oa-desktop/src/guide.rs | 11 +-
crates/oa-desktop/src/main.rs | 1 +
.../oa-desktop/src/source_navigation/query.rs | 37 +-
.../src/source_navigation/query_tests.rs | 59 +
.../src/source_navigation/symbols.rs | 7 -
crates/oa-desktop/src/source_rename.rs | 3 +
crates/oa-desktop/src/source_rename/origin.rs | 278 ++++
.../oa-desktop/src/source_rename/preview.rs | 578 +++++++
crates/oa-desktop/src/views.rs | 40 +-
docs/language.html | 39 +
docs/language.rst | 44 +
.../archive-result.json | 19 +
.../build_archive.py | 145 ++
.../independent-review.md | 11 +
.../independent-verification.json | 133 ++
.../independent_verify.py | 140 ++
...rce-rename-completed-evidence-20260912.zip | Bin 0 -> 10755689 bytes
.../archive-result.json | 59 +
.../review.md | 20 +
...ource-rename-native-attempt-6-20260912.zip | Bin 0 -> 3221627 bytes
.../archive-result.json | 20 +
.../independent-review-receipt.json | 52 +
.../independent-review.md | 15 +
...ource-rename-refresh-evidence-20260912.zip | Bin 0 -> 6411947 bytes
...ase-source-alias-rename-design-20260911.md | 4 +-
...source-alias-rename-validation-20260912.md | 350 ++++
40 files changed, 7251 insertions(+), 28 deletions(-)
create mode 100644 crates/oa-desktop/src/app/source_rename.rs
create mode 100644 crates/oa-desktop/src/app/source_rename/alias_input.rs
create mode 100644 crates/oa-desktop/src/app/source_rename/alias_input/tests.rs
create mode 100644 crates/oa-desktop/src/app/source_rename/editor_patch.rs
create mode 100644 crates/oa-desktop/src/app/source_rename/preview_glyph_tests.rs
create mode 100644 crates/oa-desktop/src/app/source_rename/tests.rs
create mode 100644 crates/oa-desktop/src/app/source_rename_layout_timing_tests.rs
create mode 100644 crates/oa-desktop/src/app/source_rename_timing_tests.rs
create mode 100644 crates/oa-desktop/src/document_alias_rename.rs
create mode 100644 crates/oa-desktop/src/document_alias_rename_tests.rs
create mode 100644 crates/oa-desktop/src/source_rename.rs
create mode 100644 crates/oa-desktop/src/source_rename/origin.rs
create mode 100644 crates/oa-desktop/src/source_rename/preview.rs
create mode 100644 harness/experiments/source-alias-rename-completed-20260912/archive-result.json
create mode 100644 harness/experiments/source-alias-rename-completed-20260912/build_archive.py
create mode 100644 harness/experiments/source-alias-rename-completed-20260912/independent-review.md
create mode 100644 harness/experiments/source-alias-rename-completed-20260912/independent-verification.json
create mode 100644 harness/experiments/source-alias-rename-completed-20260912/independent_verify.py
create mode 100644 harness/experiments/source-alias-rename-completed-20260912/source-rename-completed-evidence-20260912.zip
create mode 100644 harness/experiments/source-alias-rename-native-20260912/archive-result.json
create mode 100644 harness/experiments/source-alias-rename-native-20260912/review.md
create mode 100644 harness/experiments/source-alias-rename-native-20260912/source-rename-native-attempt-6-20260912.zip
create mode 100644 harness/experiments/source-alias-rename-refresh-20260912/archive-result.json
create mode 100644 harness/experiments/source-alias-rename-refresh-20260912/independent-review-receipt.json
create mode 100644 harness/experiments/source-alias-rename-refresh-20260912/independent-review.md
create mode 100644 harness/experiments/source-alias-rename-refresh-20260912/source-rename-refresh-evidence-20260912.zip
create mode 100644 harness/release-source-alias-rename-validation-20260912.md
diff --git a/.gitattributes b/.gitattributes
index 3658687c..6d7e360b 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -71,3 +71,6 @@ harness/history/2026-09-11-state-before-gitea-migration/** -text whitespace=cr-a
harness/experiments/contextual-prerelease-20260911/native/**/*.arcadia whitespace=-blank-at-eol,-blank-at-eof,cr-at-eol
harness/experiments/contextual-prerelease-20260911/producer/package*.log whitespace=-blank-at-eof,cr-at-eol
harness/experiments/contextual-prerelease-20260911/producer/source-push.log -whitespace
+harness/experiments/source-alias-rename-native-20260912/** -text whitespace=cr-at-eol
+harness/experiments/source-alias-rename-completed-20260912/** -text whitespace=cr-at-eol
+harness/experiments/source-alias-rename-refresh-20260912/** -text whitespace=cr-at-eol
diff --git a/crates/oa-desktop/src/app.rs b/crates/oa-desktop/src/app.rs
index 11030066..b9d14f11 100644
--- a/crates/oa-desktop/src/app.rs
+++ b/crates/oa-desktop/src/app.rs
@@ -7,6 +7,7 @@ mod diagram_selection_tests;
mod hosted;
#[cfg(test)]
mod review_navigation_tests;
+pub(crate) mod source_rename;
mod source_symbols;
#[cfg(test)]
mod transition_context_tests;
@@ -422,6 +423,8 @@ pub enum Message {
crate::source_navigation::SymbolEvent,
),
SourceSymbolsReady(crate::source_navigation::Completion),
+ SourceRename(source_rename::Event),
+ SourceRenameReady(source_rename::Completion),
SourceForSelection,
SourceNavigation(crate::source_navigation::Event),
SourceFindClose(crate::source_navigation::SymbolContext, Id),
@@ -500,6 +503,7 @@ pub struct App {
pub source_navigation: crate::source_navigation::State,
source_find_instance: Id,
pub source_symbols: crate::source_navigation::SymbolState,
+ pub source_rename: source_rename::State,
pub model_issues: Vec,
pub migration: Option,
source_version: u64,
@@ -607,6 +611,7 @@ impl App {
source_navigation: crate::source_navigation::State::default(),
source_find_instance: Id::new_v4(),
source_symbols: crate::source_navigation::SymbolState::default(),
+ source_rename: source_rename::State::default(),
model_issues,
migration: None,
source_version: 0,
@@ -653,19 +658,37 @@ impl App {
|| self.behavior.has_pending()
}
fn sync_source(&mut self) {
+ self.sync_source_with_alias_editor(None);
+ }
+ fn sync_source_with_alias_editor(&mut self, hint: Option>) {
self.source_workspace.accept(self.document.bundle());
- self.show_source_file(false);
+ self.show_source_file_with_alias_editor(false, hint);
self.source_diagnostics = self.document.compiled().diagnostics.clone();
self.source_version += 1;
self.lint_requested = None;
}
fn show_source_file(&mut self, restore_cursor: bool) {
+ self.show_source_file_with_alias_editor(restore_cursor, None);
+ }
+ fn show_source_file_with_alias_editor(
+ &mut self,
+ restore_cursor: bool,
+ hint: Option>,
+ ) {
self.source_symbols.reveal = None;
self.source_tree.reveal(&self.source_workspace.active);
self.source_select_line = false;
let source = self.source_workspace.text().to_owned();
self.source_navigation.refresh(&source);
- self.source_editor = text_editor::Content::with_text(&source);
+ if !hint.is_some_and(|hint| {
+ hint.apply(
+ &mut self.source_editor,
+ &self.source_workspace.active,
+ &source,
+ )
+ }) {
+ self.source_editor = text_editor::Content::with_text(&source);
+ }
self.source_snapshot = Arc::from(source);
self.source_jump = restore_cursor
.then(|| {
@@ -710,6 +733,9 @@ impl App {
}
}
fn sync(&mut self) {
+ self.sync_with_alias_editor(None);
+ }
+ fn sync_with_alias_editor(&mut self, hint: Option>) {
self.explorer_index = crate::explorer::Index::new(self.project(), self.layer);
self.model_issues = validate(self.project());
self.normalize_creation();
@@ -739,7 +765,7 @@ impl App {
.map(|d| d.id);
}
self.refresh_draft();
- self.sync_source();
+ self.sync_source_with_alias_editor(hint);
}
fn normalize_creation(&mut self) {
if !self.create_kind.supports(self.layer) {
@@ -932,6 +958,7 @@ impl App {
let source_version = self.source_version + 1;
let lint_running = self.lint_running;
let navigation_in_flight = self.source_symbols.in_flight;
+ let rename_in_flight = self.source_rename.in_flight;
let guide = std::mem::take(&mut self.guide);
let mut hosted = std::mem::take(&mut self.hosted);
hosted.leave_document();
@@ -944,6 +971,7 @@ impl App {
self.source_version = source_version;
self.lint_running = lint_running;
self.source_symbols.in_flight = navigation_in_flight;
+ self.source_rename.in_flight = rename_in_flight;
self.guide = guide;
self.path = path;
self.status = "Project ready".into();
@@ -1061,7 +1089,9 @@ impl App {
self.behavior.creation.has_pending()
|| self.behavior.source_active()
|| (self.page == Page::Text
- && (self.source_symbols.open || self.source_navigation.open)
+ && (self.source_symbols.open
+ || self.source_navigation.open
+ || self.source_rename.open())
&& self.architecture.is_none()),
)
.map(|()| Message::Escape),
@@ -1109,6 +1139,11 @@ impl App {
])
}
pub fn update(&mut self, message: Message) -> Task {
+ if let Message::SourceRename(event) = &message
+ && !self.source_rename_envelope(event)
+ {
+ return Task::none();
+ }
let message = match message {
Message::SourceFindClose(context, instance) => {
if context != self.source_symbol_context()
@@ -1138,6 +1173,9 @@ impl App {
if let Message::SourceSymbolsReady(completion) = message {
return self.source_symbols_ready(completion);
}
+ if let Message::SourceRenameReady(completion) = message {
+ return self.source_rename_ready(completion);
+ }
if !matches!(
&message,
Message::CheckpointTick
@@ -1328,6 +1366,18 @@ impl App {
{
return Task::none();
}
+ if self.source_rename.open() {
+ if matches!(
+ message,
+ Message::Escape | Message::Request(Pending::Close(_))
+ ) {
+ self.close_source_rename();
+ return Task::none();
+ }
+ if !modal_event && !matches!(message, Message::SourceRename(_)) {
+ return Task::none();
+ }
+ }
if matches!(
message,
Message::Page(_) | Message::Layer(_) | Message::Diagram(_)
@@ -1372,6 +1422,7 @@ impl App {
self.last_workspace_page = self.page;
}
let mut task = self.handle(message);
+ self.refresh_source_rename_context();
self.route_state_diagram_workspace();
if self.page != Page::Home {
self.last_workspace_page = self.page;
@@ -2917,6 +2968,7 @@ impl App {
if self.pending_recovery.as_ref() != Some(&receipt.target) {
return Task::none();
}
+ self.invalidate_source_rename("Disk recovery changed this source context. Your replacement is retained; close and invoke Rename again.");
self.pending_recovery = None;
self.source_diagnostics
.retain(|issue| issue.diagnostic.code != "pending_save");
@@ -3004,6 +3056,8 @@ impl App {
Message::SourceViewport(ticket) => return self.source_viewport(ticket),
Message::SourceFindClose(..) => return Task::none(), // update checks and unwraps it
Message::SourceSymbols(_, event) => return self.source_symbol_event(event),
+ Message::SourceRename(event) => return self.source_rename_event(event),
+ Message::SourceRenameReady(completion) => return self.source_rename_ready(completion),
Message::SourceSymbolsReady(completion) => {
return self.source_symbols_ready(completion);
}
diff --git a/crates/oa-desktop/src/app/source_rename.rs b/crates/oa-desktop/src/app/source_rename.rs
new file mode 100644
index 00000000..50b742d3
--- /dev/null
+++ b/crates/oa-desktop/src/app/source_rename.rs
@@ -0,0 +1,1172 @@
+//! 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,
+}
+
+#[derive(Debug, Clone)]
+struct Job {
+ id: Id,
+ invocation: Id,
+ generation: Id,
+ context: Context,
+}
+
+#[derive(Debug)]
+struct Target {
+ id: Id,
+ alias: String,
+ caption: String,
+ origin: query::Origin,
+}
+
+#[derive(Debug)]
+struct Approval {
+ id: Id,
+ prepared: PreparedAliasRename,
+ preview: preview::Preview,
+ cursor: text_editor::Cursor,
+}
+
+#[derive(Debug, Clone)]
+enum Payload {
+ Target(Result, String>),
+ Preview(Result, String>),
+}
+
+#[derive(Debug, Clone)]
+pub struct Completion {
+ job: Job,
+ payload: Payload,
+}
+
+struct Form {
+ invocation: Id,
+ generation: Id,
+ context: Context,
+ target: Option>,
+ replacement: String,
+ notice: String,
+ stale: bool,
+ pending: Option,
+ approval: Option>,
+ search: String,
+ file: usize,
+ hunk: usize,
+ line: usize,
+ segment: usize,
+ details: bool,
+ detail_segment: usize,
+ detail_editor: text_editor::Content,
+}
+
+#[derive(Debug)]
+struct Undo {
+ id: Id,
+ context: Context,
+}
+
+#[derive(Default)]
+pub struct State {
+ form: Option
+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 9ea3a7f6..c1ca9106 100644
--- a/docs/language.rst
+++ b/docs/language.rst
@@ -2073,6 +2073,50 @@ Navigation MUST preserve the accepted model and every source draft, and select
locations in the original UTF-8 bytes. Displayed locations use one-based lines
and UTF-8 byte columns.
+**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/source-alias-rename-completed-20260912/archive-result.json b/harness/experiments/source-alias-rename-completed-20260912/archive-result.json
new file mode 100644
index 00000000..27d03ac1
--- /dev/null
+++ b/harness/experiments/source-alias-rename-completed-20260912/archive-result.json
@@ -0,0 +1,19 @@
+{
+ "archive": "source-rename-completed-evidence-20260912.zip",
+ "sha256": "2282e4e755bb03ab3ecb079391909f3978297ad307e76306ef7eb5a87a9437cf",
+ "bytes": 10755689,
+ "members": 77,
+ "payloadBytes": 12361849,
+ "completedRuns": [
+ "attempt-6",
+ "clipping-negative-1",
+ "clipping-positive-diagnostic-1",
+ "nested-sync-diagnostic-1",
+ "editor-patch-check-1"
+ ],
+ "commandReceipts": 8,
+ "inputArchivesVerified": 5,
+ "sourceReadbacks": 73,
+ "allMemberBytesAndCrcVerified": true,
+ "scope": "Completed source gates and bounded experiments only; not candidate acceptance or native paint."
+}
\ No newline at end of file
diff --git a/harness/experiments/source-alias-rename-completed-20260912/build_archive.py b/harness/experiments/source-alias-rename-completed-20260912/build_archive.py
new file mode 100644
index 00000000..08e3f45d
--- /dev/null
+++ b/harness/experiments/source-alias-rename-completed-20260912/build_archive.py
@@ -0,0 +1,145 @@
+"""Archive only explicitly selected completed receipts; execute no project code."""
+import hashlib
+import io
+import json
+from pathlib import Path
+import zipfile
+
+ROOT = Path(__file__).resolve().parents[2]
+OUT = Path(__file__).resolve().parent
+PREFIX = "source-rename-completed-evidence/"
+RUNS = ["attempt-6", "clipping-negative-1", "clipping-positive-diagnostic-1",
+ "nested-sync-diagnostic-1", "editor-patch-check-1"]
+payload = {}
+originals = {}
+checks = []
+
+def sha(data):
+ return hashlib.sha256(data).hexdigest()
+
+def encoded(value):
+ return (json.dumps(value, ensure_ascii=True, indent=2) + "\n").encode()
+
+def add(source, target):
+ path = ROOT / source
+ data = path.read_bytes()
+ assert target not in payload
+ assert path.suffix.lower() not in {".exe", ".dll", ".pyc"}
+ payload[target] = data
+ originals[str(path)] = data
+
+for run in RUNS:
+ directory = ROOT / ".local/source-rename-integration-20260912" / run
+ names = ["inputs.zip", "inputs.json", "environment.json"]
+ phases = ["clippy", "tests", "timing", "gui"] if run == "attempt-6" else [""]
+ if run == "attempt-6":
+ names.append("complete.json")
+ complete = json.loads((directory / "complete.json").read_bytes())
+ assert complete["inputsUnchanged"] and complete["gates"] == phases
+ for phase in phases:
+ receipt_name = phase + "-result.json" if phase else "result.json"
+ receipt = json.loads((directory / receipt_name).read_bytes())
+ assert receipt["finished"] and receipt["inputsUnchanged"]
+ assert receipt["exitCode"] == (101 if run == "clipping-negative-1" else 0)
+ names.append(receipt_name)
+ for stream in ["stdout", "stderr"]:
+ log = (phase + "-" if phase else "") + stream + ".log"
+ assert sha((directory / log).read_bytes()) == receipt[stream + "Sha256"]
+ names.append(log)
+ checks.append({"run": run, "phase": phase or "command", "exitCode": receipt["exitCode"],
+ "finished": receipt["finished"], "command": receipt["command"]})
+ manifest = json.loads((directory / "inputs.json").read_bytes())
+ raw = (directory / "inputs.zip").read_bytes()
+ assert sha(raw) == manifest["archiveSha256"]
+ with zipfile.ZipFile(io.BytesIO(raw)) as inner:
+ expected = {entry["path"]: entry for entry in manifest["files"]}
+ assert len(inner.namelist()) == len(set(inner.namelist())) == len(expected)
+ assert set(inner.namelist()) == set(expected) and inner.testzip() is None
+ for name, entry in expected.items():
+ assert not Path(name).is_absolute() and ".." not in Path(name).parts
+ assert Path(name).suffix.lower() not in {".exe", ".dll", ".pyc"}
+ data = inner.read(name)
+ assert len(data) == entry["bytes"] and sha(data) == entry["sha256"]
+ checks.append({"run": run, "inputArchiveSha256": sha(raw), "inputMembers": len(expected),
+ "allInputBytesAndCrcVerified": True})
+ for name in names:
+ add(directory.relative_to(ROOT) / name, "runs/" + run + "/" + name)
+
+diagnosis = ".local/source-rename-latency-diagnosis-20260912/"
+notes = ["notes.md", "read-bindings.json", "nested-summary.json", "summarize.py",
+ "editor-initialization-candidates.md", "editor-initialization-bindings.json",
+ "same-line-patch-assessment.md", "editor-patch-independent-review.md",
+ "editor-patch-review-bindings.json", "prepare-instrumentation.ps1",
+ "candidate/editor_patch.rs", "candidate/README.md"]
+for name in notes:
+ add(diagnosis + name, "diagnosis/" + name)
+for path in sorted((ROOT / diagnosis / "instrumentation").rglob("*")):
+ if path.is_file():
+ add(path.relative_to(ROOT), "diagnosis/instrumentation/" + path.relative_to(ROOT / diagnosis / "instrumentation").as_posix())
+for name in ["README.md", "source_rename.rs", "controller-tests.rs", "preview_glyph_tests.rs", "base-hashes.json", "staged-hashes.json"]:
+ add(".local/source-rename-preview-clipping-20260912/" + name, "clipping-stage/" + name)
+for name in ["native-preview-clipping-review.md", "native-preview-clipping-bindings.json", "staged-clipping-review.md", "staged-clipping-review-bindings.json"]:
+ add(".local/source-rename-controller-independent-review-20260912/" + name, "reviews/" + name)
+for name in ["gate.py", "focused.py"]:
+ add(".local/source-rename-integration-20260912/" + name, "helpers-current-readback/" + name)
+assert sha(payload["diagnosis/candidate/editor_patch.rs"]) == "f301b8a043916b69dccb176da527a50ee85124b7e8b1da18921e4a0374a5153b"
+
+# Bind the corrected helper from the completed check snapshot, never moving live source.
+with zipfile.ZipFile(io.BytesIO(payload["runs/editor-patch-check-1/inputs.zip"])) as inner:
+ corrected = inner.read("crates/oa-desktop/src/app/source_rename/editor_patch.rs")
+assert sha(corrected) == "049c9774c1ca28cda01f9a8e024604bef282366aa52c53c17c1918dbd09c3441"
+negative = payload["runs/clipping-negative-1/stderr.log"].decode()
+assert "source glyph under scrollbar" in negative and "cluster=92..93" in negative
+
+native_path = "harness/experiments/source-alias-rename-native-20260912/source-rename-native-attempt-6-20260912.zip"
+native = (ROOT / native_path).read_bytes()
+assert sha(native) == "77adda5a33eb1def6dab23352ca0ab172300ea65fc21d2c215d545d7fcce0d08"
+gui = json.loads(payload["runs/attempt-6/gui-result.json"])["binary"]
+summary = {"scope": "Completed source gates and bounded experiments only; not candidate acceptance or native paint.",
+ "checks": checks, "externalBindings": [{"path": native_path, "sha256": sha(native), "bytes": len(native), "included": False},
+ {"path": ".local/source-rename-integration-20260912/attempt-6/arcadia-studio.exe", "sha256": gui["sha256"], "bytes": gui["bytes"], "included": False}],
+ "correctedHelperFromCheckInputSha256": sha(corrected),
+ "excluded": ["editor-patch-tests-1", "next-layout evaluator", "executable/DLL bytes", "private profiles", "caches", "duplicate native trial archive"]}
+payload["SUMMARY.json"] = encoded(summary)
+payload["INDEX.md"] = b"""# Completed alias source gates and bounded experiments
+
+This private archive preserves five completed runs only. It is not a release or acceptance of an editor-reuse candidate. Native trial evidence is separately versioned and SHA-bound in SUMMARY.json, without duplicate payload.
+
+| Run | Meaning |
+| --- | --- |
+| attempt-6 | Four successful Windows source gates: Clippy, tests, existing full Confirm timing, GUI executable build. The GUI JSON records the external binary; building it is not native acceptance. |
+| clipping-negative-1 | Expected test failure (101): original layout allows actual shaped declaration glyph cluster92..93 beneath the scrollbar. |
+| clipping-positive-diagnostic-1 | Successful focused rename tests with corrected preview layout and temporary timing instrumentation in source. This is an experimental capture, not clean production acceptance. |
+| nested-sync-diagnostic-1 | Successful ignored real-Confirm timing experiment with nested instrumentation. Inclusive phase levels must not be added together; no GPU, first-paint or native responsiveness claim. |
+| editor-patch-check-1 | Successful cargo check of corrected reuse helper integration only. It does not execute helper behavior, later layout timing or native rendering. |
+
+Every run has its exact inputs.zip, complete membership/hash manifest, environment, commands/receipts and raw logs. All eight command receipt log hashes and all five nested ZIP memberships/member bytes/CRCs were independently checked during construction. Inputs manifests bind historical uncommitted snapshots; baseCommit alone is not their source identity.
+
+diagnosis/instrumentation preserves removed diagnostic baseline/modified files, exact patch, bindings and generator. Historical notes retain their original time-scoped claims; later receipts qualify earlier hypotheses. diagnosis/candidate/editor_patch.rs is frozen f301b8a0 and has the known after-only LFCR counterexample documented in editor-patch-independent-review.md. Its original README's broad fallback claim is superseded by that review. Corrected helper049c9774 is preserved inside editor-patch-check-1/inputs.zip. The review is static, not proof of executed correctness.
+
+clipping-stage and reviews preserve the earlier proposed repair/evaluator and source review; the exact executed evaluator is in each run's inputs.zip. helpers-current-readback are archive-time helper source snapshots, not independently proven historical executed versions. Historical absolute paths are evidence, not portable execution instructions. Reproduce with the recorded Windows compiler/dependencies and exact source snapshot; do not run relocated helpers blindly.
+
+No current editor-patch-tests-1 or subsequent layout evaluation is included. No executables, DLLs, caches or private profiles are included, and no native trial payload is duplicated. PAYLOAD-MANIFEST.json covers all members except itself; external archive-result.json binds the entire archive.
+"""
+add(Path(__file__).relative_to(ROOT), "archive-tools/build_archive.py")
+payload["READBACK-SOURCES.json"] = encoded([{"path": str(Path(path).relative_to(ROOT)), "sha256": sha(data), "bytes": len(data)} for path, data in originals.items()])
+payload["PAYLOAD-MANIFEST.json"] = encoded({"selfExcluded": "PAYLOAD-MANIFEST.json", "members": [{"path": name, "bytes": len(data), "sha256": sha(data)} for name, data in sorted(payload.items())]})
+archive = OUT / "source-rename-completed-evidence-20260912.zip"
+with zipfile.ZipFile(archive, "x", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as zipped:
+ for name, data in sorted(payload.items()):
+ info = zipfile.ZipInfo(PREFIX + name, date_time=(2026, 9, 12, 0, 0, 0))
+ info.compress_type = zipfile.ZIP_DEFLATED
+ zipped.writestr(info, data)
+with zipfile.ZipFile(archive) as zipped:
+ assert zipped.testzip() is None and set(zipped.namelist()) == {PREFIX + n for n in payload}
+ for name, data in payload.items():
+ assert zipped.read(PREFIX + name) == data
+for path, data in originals.items():
+ assert Path(path).read_bytes() == data, "Source changed during archive: " + path
+receipt = {"archive": archive.name, "sha256": sha(archive.read_bytes()), "bytes": archive.stat().st_size,
+ "members": len(payload), "payloadBytes": sum(map(len, payload.values())), "completedRuns": RUNS,
+ "commandReceipts": 8, "inputArchivesVerified": 5, "sourceReadbacks": len(originals),
+ "allMemberBytesAndCrcVerified": True, "scope": summary["scope"]}
+with (OUT / "archive-result.json").open("x", encoding="utf-8") as stream:
+ json.dump(receipt, stream, indent=2)
+print(json.dumps(receipt))
diff --git a/harness/experiments/source-alias-rename-completed-20260912/independent-review.md b/harness/experiments/source-alias-rename-completed-20260912/independent-review.md
new file mode 100644
index 00000000..0b3d4bd0
--- /dev/null
+++ b/harness/experiments/source-alias-rename-completed-20260912/independent-review.md
@@ -0,0 +1,11 @@
+# Independent archive verification — PASS
+
+2026-09-12, `/root/publication_review`. No discrepancies found. Read-only verification of archive/original bytes; no archived helper, project code, Cargo or native application was executed. See `independent-verification.json` and the separate `independent_verify.py` evaluator.
+
+- Whole ZIP matches `archive-result.json`: SHA256 `2282e4e755bb03ab3ecb079391909f3978297ad307e76306ef7eb5a87a9437cf`, 10,755,689 bytes, 77 members, 12,361,849 uncompressed payload bytes.
+- Complete outer manifest membership, every payload hash/length and all CRCs pass. All five nested input ZIPs pass exact membership, every input hash/length and CRC: 513/514/514/514/515 members respectively. No duplicate or unsafe paths, executable/DLL/cache/profile payloads, or nested native archive duplicates were found.
+- All eight completed command receipts agree with their raw log hashes and summary entries. All 73 original-source readbacks are byte-identical, including the archive builder. External native ZIP `77adda5a…` and preserved executable `d1ec6305…` match their complete SHA256 and byte bindings.
+- Raw outcomes match the stated historical scope: attempt6 has 796 tests passed, zero failed, two ignored, plus successful strict Clippy, separate ignored timing and executable build. The clipping negative control fails with the recorded glyph cluster92..93 beneath the scrollbar. The corrected-layout diagnostic run passes 33 focused tests; nested timing passes its one experiment. Editor-patch-check-1 is a successful **check**, not executed behavior.
+- The original candidate `f301b8a0…`, its documented LFCR finding, and corrected helper `049c9774…` inside the completed check snapshot are correctly distinguished. Staged clipping hashes and nested timing summary-to-log binding pass.
+
+Limitations are accurately stated in INDEX.md: this is historical evidence, not acceptance of the current reuse candidate, subsequent evaluator runs, corrected native layout, or release. Native trial payload remains separately bound. Helper sources labeled archive-time readbacks are not asserted to be the exact historical executed versions. Historical uncommitted input snapshots, rather than baseCommit alone, identify each tested source. No new native painting or latency claim follows from this verification.
diff --git a/harness/experiments/source-alias-rename-completed-20260912/independent-verification.json b/harness/experiments/source-alias-rename-completed-20260912/independent-verification.json
new file mode 100644
index 00000000..4ec1ff3b
--- /dev/null
+++ b/harness/experiments/source-alias-rename-completed-20260912/independent-verification.json
@@ -0,0 +1,133 @@
+{
+ "status": "PASS",
+ "checks": 2945,
+ "archiveSha256": "2282e4e755bb03ab3ecb079391909f3978297ad307e76306ef7eb5a87a9437cf",
+ "bytes": 10755689,
+ "members": 77,
+ "payloadBytes": 12361849,
+ "nestedInputs": {
+ "attempt-6": {
+ "members": 513,
+ "sha256": "03b5a9e3f4e9e220421320c09f1ecf46f811edf2e3c6c45dcd9522c6d78b8255",
+ "topLevelCounts": {
+ "Cargo.lock": 1,
+ "Cargo.toml": 1,
+ "build": 3,
+ "crates": 275,
+ "docs": 18,
+ "examples": 51,
+ "harness": 164
+ }
+ },
+ "clipping-negative-1": {
+ "members": 514,
+ "sha256": "1a59b58373d615a534244881a931f4423f590f04e0e632c986bf2a93af7d287d",
+ "topLevelCounts": {
+ "Cargo.lock": 1,
+ "Cargo.toml": 1,
+ "build": 3,
+ "crates": 276,
+ "docs": 18,
+ "examples": 51,
+ "harness": 164
+ }
+ },
+ "clipping-positive-diagnostic-1": {
+ "members": 514,
+ "sha256": "fc899e533e04317d0ba27dfa9f1bdfbfca77d3dede8478c45480f0edb19931a0",
+ "topLevelCounts": {
+ "Cargo.lock": 1,
+ "Cargo.toml": 1,
+ "build": 3,
+ "crates": 276,
+ "docs": 18,
+ "examples": 51,
+ "harness": 164
+ }
+ },
+ "nested-sync-diagnostic-1": {
+ "members": 514,
+ "sha256": "5bbd5145f6eea69fabe5cbfa3da14f059cf4446de49072f8714a5dc709d35cfa",
+ "topLevelCounts": {
+ "Cargo.lock": 1,
+ "Cargo.toml": 1,
+ "build": 3,
+ "crates": 276,
+ "docs": 18,
+ "examples": 51,
+ "harness": 164
+ }
+ },
+ "editor-patch-check-1": {
+ "members": 515,
+ "sha256": "1b18763ba3f74cbff0e842ff51b58879a6d7f82daac4ce65086b8c579ae0b272",
+ "topLevelCounts": {
+ "Cargo.lock": 1,
+ "Cargo.toml": 1,
+ "build": 3,
+ "crates": 277,
+ "docs": 18,
+ "examples": 51,
+ "harness": 164
+ }
+ }
+ },
+ "commandReceipts": [
+ {
+ "run": "attempt-6",
+ "phase": "clippy",
+ "exitCode": 0
+ },
+ {
+ "run": "attempt-6",
+ "phase": "tests",
+ "exitCode": 0
+ },
+ {
+ "run": "attempt-6",
+ "phase": "timing",
+ "exitCode": 0
+ },
+ {
+ "run": "attempt-6",
+ "phase": "gui",
+ "exitCode": 0
+ },
+ {
+ "run": "clipping-negative-1",
+ "phase": "command",
+ "exitCode": 101
+ },
+ {
+ "run": "clipping-positive-diagnostic-1",
+ "phase": "command",
+ "exitCode": 0
+ },
+ {
+ "run": "nested-sync-diagnostic-1",
+ "phase": "command",
+ "exitCode": 0
+ },
+ {
+ "run": "editor-patch-check-1",
+ "phase": "command",
+ "exitCode": 0
+ }
+ ],
+ "originalReadbacks": 73,
+ "originalDeltas": [],
+ "externalBindings": [
+ {
+ "path": "harness/experiments/source-alias-rename-native-20260912/source-rename-native-attempt-6-20260912.zip",
+ "sha256": "77adda5a33eb1def6dab23352ca0ab172300ea65fc21d2c215d545d7fcce0d08",
+ "bytes": 3221627
+ },
+ {
+ "path": ".local/source-rename-integration-20260912/attempt-6/arcadia-studio.exe",
+ "sha256": "d1ec63050e95513064155e9d04f443d95667b1e468dcdbb3b810dad379504814",
+ "bytes": 113854464
+ }
+ ],
+ "failures": [],
+ "scope": "Independent byte/CRC/membership and receipt verification only; no archived or production code executed."
+}
\ No newline at end of file
diff --git a/harness/experiments/source-alias-rename-completed-20260912/independent_verify.py b/harness/experiments/source-alias-rename-completed-20260912/independent_verify.py
new file mode 100644
index 00000000..157a6283
--- /dev/null
+++ b/harness/experiments/source-alias-rename-completed-20260912/independent_verify.py
@@ -0,0 +1,140 @@
+"""Read archive/original bytes only; never import or execute archived helpers."""
+from pathlib import Path, PurePosixPath, PureWindowsPath
+from collections import Counter
+import hashlib
+import io
+import json
+import zipfile
+
+root = Path(__file__).resolve().parents[2]
+folder = Path(__file__).resolve().parent
+receipt = json.loads((folder / 'archive-result.json').read_bytes())
+raw = (folder / receipt['archive']).read_bytes()
+sha = lambda b: hashlib.sha256(b).hexdigest()
+failures = []
+checks = 0
+def check(ok, message):
+ global checks
+ checks += 1
+ if not ok:
+ failures.append(message)
+def safe(name):
+ pos = PurePosixPath(name)
+ win = PureWindowsPath(name)
+ return not pos.is_absolute() and not win.is_absolute() and not win.drive and '..' not in pos.parts and '\\' not in name
+def verify_zip(z, label):
+ names = z.namelist()
+ check(len(names) == len(set(names)), label + ': duplicate member')
+ check(z.testzip() is None, label + ': CRC')
+ check(all(safe(n) for n in names), label + ': unsafe member path')
+ check(all(not n.endswith('/') for n in names), label + ': unexpected directory member')
+ check(all(PurePosixPath(n).suffix.lower() not in {'.exe', '.dll', '.pyc'} for n in names), label + ': executable/cache member')
+ check(all(not ({'node_modules', 'target', '.git', '__pycache__', 'profile', 'profiles', 'cache', 'caches'} & set(PurePosixPath(n).parts)) for n in names), label + ': out-of-scope directory')
+ return names
+
+check(sha(raw) == receipt['sha256'], 'whole archive SHA')
+check(len(raw) == receipt['bytes'], 'whole archive bytes')
+prefix = 'source-rename-completed-evidence/'
+z = zipfile.ZipFile(io.BytesIO(raw))
+names = verify_zip(z, 'outer')
+check(len(names) == receipt['members'] == 77, 'outer member count')
+check(all(n.startswith(prefix) for n in names), 'outer prefix')
+payload = {n[len(prefix):]: z.read(n) for n in names}
+check(sum(map(len, payload.values())) == receipt['payloadBytes'], 'outer payload bytes')
+manifest = json.loads(payload['PAYLOAD-MANIFEST.json'])
+entries = manifest['members']
+check(manifest['selfExcluded'] == 'PAYLOAD-MANIFEST.json', 'manifest self exclusion')
+check(len(entries) == len({e['path'] for e in entries}), 'manifest duplicate entry')
+check(set(e['path'] for e in entries) == set(payload) - {'PAYLOAD-MANIFEST.json'}, 'manifest complete membership')
+for entry in entries:
+ data = payload[entry['path']]
+ check(len(data) == entry['bytes'] and sha(data) == entry['sha256'], 'manifest member: ' + entry['path'])
+
+source_maps = [
+ ('.local/source-rename-latency-diagnosis-20260912/', 'diagnosis/'),
+ ('.local/source-rename-preview-clipping-20260912/', 'clipping-stage/'),
+ ('.local/source-rename-controller-independent-review-20260912/', 'reviews/'),
+]
+source_entries = json.loads(payload['READBACK-SOURCES.json'])
+check(len(source_entries) == receipt['sourceReadbacks'] == 73, 'readback count')
+original_deltas = []
+for entry in source_entries:
+ source = entry['path'].replace('\\', '/')
+ check(safe(source), 'unsafe original path: ' + source)
+ if source.endswith('/build_archive.py'):
+ member = 'archive-tools/build_archive.py'
+ elif source in {'.local/source-rename-integration-20260912/gate.py', '.local/source-rename-integration-20260912/focused.py'}:
+ member = 'helpers-current-readback/' + source.rsplit('/', 1)[1]
+ elif source.startswith('.local/source-rename-integration-20260912/'):
+ member = 'runs/' + source.removeprefix('.local/source-rename-integration-20260912/')
+ else:
+ mapped = [target + source.removeprefix(base) for base, target in source_maps if source.startswith(base)]
+ check(len(mapped) == 1, 'original target mapping: ' + source)
+ if not mapped:
+ continue
+ member = mapped[0]
+ archived = payload[member]
+ check(len(archived) == entry['bytes'] and sha(archived) == entry['sha256'], 'readback archive binding: ' + member)
+ actual = (root / source).read_bytes()
+ if actual != archived:
+ original_deltas.append({'path': source, 'currentSha256': sha(actual), 'archiveSha256': sha(archived)})
+check(not original_deltas, 'original source byte differences')
+
+summary = json.loads(payload['SUMMARY.json'])
+runs = receipt['completedRuns']
+check(runs == ['attempt-6', 'clipping-negative-1', 'clipping-positive-diagnostic-1', 'nested-sync-diagnostic-1', 'editor-patch-check-1'], 'completed run scope')
+check({PurePosixPath(n).parts[1] for n in payload if n.startswith('runs/')} == set(runs), 'actual run membership')
+nested = {}
+commands = []
+for run in runs:
+ start = f'runs/{run}/'
+ manifest = json.loads(payload[start + 'inputs.json'])
+ data = payload[start + 'inputs.zip']
+ check(sha(data) == manifest['archiveSha256'], run + ': input ZIP binding')
+ inner = zipfile.ZipFile(io.BytesIO(data))
+ inner_names = verify_zip(inner, run)
+ expected = manifest['files']
+ check(len(expected) == len({e['path'] for e in expected}), run + ': duplicate input manifest entry')
+ check(set(inner_names) == {e['path'] for e in expected}, run + ': input membership')
+ for entry in expected:
+ item = inner.read(entry['path'])
+ check(len(item) == entry['bytes'] and sha(item) == entry['sha256'], run + ': ' + entry['path'])
+ nested[run] = {'members': len(inner_names), 'sha256': sha(data), 'topLevelCounts': dict(Counter(PurePosixPath(n).parts[0] for n in inner_names))}
+ recorded = [r for r in summary['checks'] if r['run'] == run and 'inputArchiveSha256' in r]
+ check(len(recorded) == 1 and recorded[0]['inputArchiveSha256'] == sha(data) and recorded[0]['inputMembers'] == len(inner_names), run + ': summary input binding')
+ phases = ['clippy', 'tests', 'timing', 'gui'] if run == 'attempt-6' else ['']
+ for phase in phases:
+ stem = phase + '-' if phase else ''
+ result = json.loads(payload[start + stem + 'result.json'])
+ check(bool(result['finished']) and result['inputsUnchanged'] and result['started'] < result['finished'], run + ': completion ' + phase)
+ check(result['exitCode'] == (101 if run == 'clipping-negative-1' else 0), run + ': exit ' + phase)
+ for stream in ['stdout', 'stderr']:
+ check(sha(payload[start + stem + stream + '.log']) == result[stream + 'Sha256'], run + ': log ' + phase + stream)
+ recorded = [r for r in summary['checks'] if r['run'] == run and r.get('phase') == (phase or 'command')]
+ check(len(recorded) == 1 and all(recorded[0][key] == result[key] for key in ['command', 'finished', 'exitCode']), run + ': command summary ' + phase)
+ commands.append({'run': run, 'phase': phase or 'command', 'exitCode': result['exitCode']})
+ if run == 'editor-patch-check-1':
+ corrected = inner.read('crates/oa-desktop/src/app/source_rename/editor_patch.rs')
+ check(sha(corrected) == summary['correctedHelperFromCheckInputSha256'] == '049c9774c1ca28cda01f9a8e024604bef282366aa52c53c17c1918dbd09c3441', 'corrected helper binding')
+check(len(commands) == receipt['commandReceipts'] == 8, 'command count')
+check(len(nested) == receipt['inputArchivesVerified'] == 5, 'input archive count')
+complete = json.loads(payload['runs/attempt-6/complete.json'])
+check(complete['inputsUnchanged'] and complete['gates'] == ['clippy', 'tests', 'timing', 'gui'], 'gate6 closure')
+check(sha(payload['diagnosis/candidate/editor_patch.rs']) == 'f301b8a043916b69dccb176da527a50ee85124b7e8b1da18921e4a0374a5153b', 'original candidate binding')
+check('source glyph under scrollbar' in payload['runs/clipping-negative-1/stderr.log'].decode() and 'cluster=92..93' in payload['runs/clipping-negative-1/stderr.log'].decode(), 'negative glyph failure receipt')
+check(json.loads(payload['diagnosis/nested-summary.json'])['logSha256'] == sha(payload['runs/nested-sync-diagnostic-1/stdout.log']), 'nested timing summary log binding')
+for entry in json.loads(payload['clipping-stage/staged-hashes.json']):
+ member = 'clipping-stage/' + PureWindowsPath(entry['Path']).name
+ check(sha(payload[member]) == entry['Hash'].lower(), 'staged layout source binding: ' + member)
+external = []
+for entry in summary['externalBindings']:
+ data = (root / entry['path']).read_bytes()
+ check(not entry['included'], 'external mistakenly marked included')
+ check(len(data) == entry['bytes'] and sha(data) == entry['sha256'], 'external binding: ' + entry['path'])
+ external.append({'path': entry['path'], 'sha256': sha(data), 'bytes': len(data)})
+binary = json.loads(payload['runs/attempt-6/gui-result.json'])['binary']
+check(external[1]['sha256'] == binary['sha256'] and external[1]['bytes'] == binary['bytes'], 'external binary gate receipt')
+
+result = {'status': 'PASS' if not failures else 'FAIL', 'checks': checks, 'archiveSha256': sha(raw), 'bytes': len(raw), 'members': len(names), 'payloadBytes': sum(map(len, payload.values())), 'nestedInputs': nested, 'commandReceipts': commands, 'originalReadbacks': len(source_entries), 'originalDeltas': original_deltas, 'externalBindings': external, 'failures': failures, 'scope': 'Independent byte/CRC/membership and receipt verification only; no archived or production code executed.'}
+(folder / 'independent-verification.json').write_text(json.dumps(result, indent=2), encoding='utf-8')
+print(json.dumps(result, indent=2))
diff --git a/harness/experiments/source-alias-rename-completed-20260912/source-rename-completed-evidence-20260912.zip b/harness/experiments/source-alias-rename-completed-20260912/source-rename-completed-evidence-20260912.zip
new file mode 100644
index 0000000000000000000000000000000000000000..7ce2c7d5851723156a4a56802d549ee98351b70c
GIT binary patch
literal 10755689
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