Preserve qualified menu navigation and correct literal source trivia oracle

This commit is contained in:
2026-09-24 20:17:07 -07:00
parent fe637dcd27
commit f20497b29b
4 changed files with 71 additions and 29 deletions
+1
View File
@@ -17,6 +17,7 @@ harness/scenario-group-spacing-evidence-20260924/** -text whitespace=cr-at-eol
harness/scenario-reorder-interaction-evidence-20260924/** -text whitespace=cr-at-eol
harness/scenario-group-removal-evidence-20260925/** -text whitespace=cr-at-eol
harness/scenario-removal-followup-evidence-20260925/** -text whitespace=cr-at-eol
harness/fixtures/process-removal-removed-v2-20260925.arcadia -text whitespace=-blank-at-eol
# Exact source/recovery oracles and archived ledgers retain their measured bytes.
# Keep ordinary text diffs; only disable checkout/check-in newline conversion.
@@ -59,7 +59,9 @@ const BASELINE: &str = include_str!(concat!(
));
const REMOVED: &str = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../../harness/fixtures/process-removal-removed-20260925.arcadia"
// V1 assumed canonical whitespace. V2 independently retains removed-token
// trivia and existing reference spelling under language section 7's rules.
"/../../harness/fixtures/process-removal-removed-v2-20260925.arcadia"
));
fn native() -> App {
let document = Document::from_bundle(native_bundle(BASELINE), Default::default()).unwrap();
+33 -28
View File
@@ -436,6 +436,32 @@ pub fn popup(app: &App) -> Option<Menu<Message>> {
)),
true,
));
// Navigation belongs to the exact clicked preview, even when it
// is outside the current group. Keep it alongside aggregate removal
// without selecting that preview or exposing singleton mutations.
let qualified_definition = request.process.as_deref().copied().and_then(|context| {
let endpoint = match request.selection_target.as_deref() {
Some(Target::ProcessOccurrence(endpoint))
if !endpoint.references.is_empty() =>
{
Some(endpoint.clone())
}
Some(Target::ProcessPreviewLink { source, .. }) => Some(source.clone()),
_ => None,
}?;
Some((context, endpoint))
});
if let Some((context, endpoint)) = &qualified_definition {
entries.push(Entry::title("Reused contents · read-only in this process"));
entries.push(item(
"Open referenced definition",
Message::TopologyCanvas(crate::behavior::topology::CanvasEvent::OpenQualified(
*context,
endpoint.clone(),
)),
true,
));
}
if let Some(snapshot) = app.multiselect_snapshot().filter(|s| s.targets().len() > 1)
&& (selected || request.process.is_some())
{
@@ -494,34 +520,13 @@ pub fn popup(app: &App) -> Option<Menu<Message>> {
});
}
entries.push(Entry::separator());
if let Some(context) = request.process.as_deref().copied() {
let endpoint = match request.selection_target.as_deref() {
Some(Target::ProcessOccurrence(endpoint))
if !endpoint.references.is_empty() =>
{
Some(endpoint.clone())
}
Some(Target::ProcessPreviewLink { source, .. }) => Some(source.clone()),
_ => None,
};
if let Some(endpoint) = endpoint {
entries.push(Entry::title("Reused contents · read-only in this process"));
entries.push(item(
"Open referenced definition",
Message::TopologyCanvas(
crate::behavior::topology::CanvasEvent::OpenQualified(
context, endpoint,
),
),
true,
));
return Some(Menu {
token: opened.token,
anchor: request.anchor,
entries,
on_close: Message::Menu(Event::Close),
});
}
if qualified_definition.is_some() {
return Some(Menu {
token: opened.token,
anchor: request.anchor,
entries,
on_close: Message::Menu(Event::Close),
});
}
}
}
@@ -0,0 +1,34 @@
arcadia 7;
project process_removal_trial "Process removal trial" id "93600000-0000-4000-8000-000000000001" {
oa_activity intake "Intake" id "93600000-0000-4000-8000-000000000002" { }
oa_activity assess "Assess" id "93600000-0000-4000-8000-000000000003" { }
oa_activity report "Report" id "93600000-0000-4000-8000-000000000004" { }
interaction received "Received" id "93600000-0000-4000-8000-000000000005" { source @intake; target @assess; }
interaction reported "Reported" id "93600000-0000-4000-8000-000000000006" { source @assess; target @report; }
oa_process assessment "01 Assessment" id "93600000-0000-4000-8000-000000000010" { steps [@e1,@e2]; }
oa_occurrence e1 "Receive report" id "93600000-0000-4000-8000-000000000012" { parent @assessment; body { Exchange { exchange @received; sender none; receiver none; message_kind Asynchronous; }; }; }
oa_occurrence e2 "Forward report" id "93600000-0000-4000-8000-000000000014" { parent @assessment; body { Exchange { exchange @reported; sender none; receiver none; message_kind Asynchronous; }; }; }
oa_process caller "02 Response using Assessment" id "93600000-0000-4000-8000-000000000020" { steps [@r1,@r2]; }
oa_occurrence r1 "First assessment" id "93600000-0000-4000-8000-000000000021" { parent @caller; body { SequenceReference { sequence @assessment; }; }; }
oa_occurrence r2 "Second assessment" id "93600000-0000-4000-8000-000000000022" { parent @caller; body { SequenceReference { sequence @assessment; }; }; }
oa_process outer "03 Mission using Response" id "93600000-0000-4000-8000-000000000030" { steps [@r3]; }
oa_occurrence r3 "Response use" id "93600000-0000-4000-8000-000000000031" { parent @outer; body { SequenceReference { sequence @caller; }; }; }
sa_function sentinel "SA preserved function" id "93600000-0000-4000-8000-000000000040" { }
sa_functional_chain sentinel_chain "SA preserved chain" id "93600000-0000-4000-8000-000000000041" { steps [@sentinel_step]; }
sa_occurrence sentinel_step "SA preserved contribution" id "93600000-0000-4000-8000-000000000042" { parent @sentinel_chain; body { Action { action @sentinel; lifeline none; }; }; }
}