Compare commits

..
Author SHA1 Message Date
Codex-ytr83r 4fcb65c0d3 Record boundary ordering comparison and native review 2026-09-24 22:19:18 -07:00
Codex-ytr83r 3e21c1bca2 Bound complete member displacement across large origins 2026-09-24 21:52:38 -07:00
Codex-ytr83r 42f595a5d6 Probe dependency-aware ordering across container boundaries 2026-09-24 21:50:15 -07:00
Codex-ytr83r c02a03c553 Declare dependency-aware boundary ordering comparison 2026-09-24 21:48:07 -07:00
Codex-ytr83r f4fa0c11f2 Record SCC placement evidence and bounded transfer correction 2026-09-24 21:37:03 -07:00
Codex-ytr83r 2426d28648 Preserve requested container minima after placement transfer 2026-09-24 21:24:57 -07:00
Codex-ytr83r 4dd764fa6c Use mutable reachability rows in isolated SCC probe 2026-09-24 21:17:11 -07:00
Codex-ytr83r ea18adc061 fix(experiment): score occupied perimeter cells including one-column cycles 2026-09-24 21:11:19 -07:00
Codex-ytr83r 5300a8c803 experiment(layout): keep cyclic quotient groups compact in condensation order 2026-09-24 21:09:04 -07:00
Codex-ytr83r ae9dad54b7 Record bounded placement clearance result and preserved quality regressions 2026-09-24 20:57:17 -07:00
Codex-ytr83r 074051261a test(layout): use valid record types for non-port lead fixtures 2026-09-24 20:40:41 -07:00
Codex-ytr83r 2be8c7f292 experiment(layout): diagnose mandatory leads and test bounded flat separation 2026-09-24 20:38:33 -07:00
Codex-ytr83r 2850b915d6 Record placement reference failures and port-clearance requirements 2026-09-24 20:26:23 -07:00
Codex-ytr83r fc5c22c903 Preserve authored sizes during identity placement transfer 2026-09-24 20:18:39 -07:00
Codex-ytr83r 8a2010d8a6 Add bounded external placement comparison and preservation adapter 2026-09-24 20:12:01 -07:00
Codex-ytr83r ac5d7ef34a Describe recorded evidence without implying blocked publication 2026-09-24 19:16:59 -07:00
Codex-ytr83r ae86111f22 Record independent routing corpus decision and preserved evidence 2026-09-24 19:12:27 -07:00
Codex-ytr83r 4fb3cdc721 Observe released router 715036e1 in frozen common harness 2026-09-24 18:53:15 -07:00
Codex-ytr83r 3ea0e23b70 Observe j router 08656b18 in frozen common harness 2026-09-24 18:46:28 -07:00
Codex-ytr83r 095ab3b358 Split geometry serialization to stay within macro recursion depth 2026-09-24 18:44:56 -07:00
Codex-ytr83r f674e36c8b Freeze byte-identical independent routing inputs and review 2026-09-24 18:37:26 -07:00
Codex-ytr83r f0eae74912 Make secondary corpus placement aliases deterministic 2026-09-24 18:36:18 -07:00
Codex-ytr83r a879341cfc Define frozen routing corpus and isolated timing protocol 2026-09-24 18:33:37 -07:00
Codex-ytr83r f72aa2ca5c Record lane tradeoffs, verification and runtime concern 2026-09-24 18:20:21 -07:00
Codex-ytr83r e8ec6dbb31 Isolate parallel lanes with the original overlap coefficient 2026-09-24 18:13:07 -07:00
Codex-ytr83r d0be9ff067 Probe bounded parallel lanes after capped penalty comparison 2026-09-24 18:09:48 -07:00
Codex-ytr83r 3d7adff923 Experiment with fixed capped overlap penalty at unchanged geometry 2026-09-24 18:03:48 -07:00
97 changed files with 27302 additions and 211 deletions
+709 -5
View File
@@ -5,6 +5,12 @@ use oa_core::{
};
use serde_json::{Value, json};
use std::collections::{BTreeMap, BTreeSet};
#[path = "auto_layout_probe/boundary_fixtures.rs"]
mod boundary_fixtures;
#[path = "auto_layout_probe/clearance.rs"]
mod clearance;
#[path = "auto_layout_probe/condensed.rs"]
mod condensed;
#[path = "auto_layout_probe/layered.rs"]
mod layered;
@@ -364,6 +370,24 @@ fn metrics(project: &Project, diagram: Id) -> Value {
.map(move |w| json!({"edge":e.id,"warning":format!("{w:?}")}))
})
.collect();
let constraints: Vec<_> = edges.iter().map(|e|json!({"id":e.id,"effective_pins":e.pins,
"pin_fractions":e.pin_fractions,"custom_suspended":e.custom_suspended,
"actual_endpoint_owners":projection::edge_endpoint_placements(project,&project.diagrams[&diagram],e.id)})).collect();
let route_endpoints: Vec<_> = edges
.iter()
.map(|e| {
json!({"id":e.id,
"source_owner":definitions[&e.id].source,"target_owner":definitions[&e.id].target,
"source":e.points.first(),"target":e.points.last()})
})
.collect();
let routed_edges: Vec<_> = edges
.iter()
.map(|e| {
json!({"id":e.id,"points":e.points,"label":{
"text":e.label.text,"position":e.label.bounds.position,"size":e.label.bounds.size}})
})
.collect();
json!({
"nodes":view.nodes.len(),"edges":edges.len(),"ports":view.ports.len(),
"proper_crossings":crossings.len(),"crossing_details":crossings,
@@ -384,14 +408,12 @@ fn metrics(project: &Project, diagram: Id) -> Value {
"drawing_area":routed.bounds.size.width as f64*routed.bounds.size.height as f64,
"route_bends":bends,"route_length":total_length,
"projected_nodes":view.nodes,"projected_ports":view.ports,
"route_endpoints":edges.iter().map(|e|json!({"id":e.id,
"source_owner":definitions[&e.id].source,"target_owner":definitions[&e.id].target,
"source":e.points.first(),"target":e.points.last()})).collect::<Vec<_>>(),
"routed_edges":edges.iter().map(|e|json!({"id":e.id,"points":e.points,"label":{
"text":e.label.text,"position":e.label.bounds.position,"size":e.label.bounds.size}})).collect::<Vec<_>>()
"projected_edges":view.edges,
"routing_constraints":constraints,"route_endpoints":route_endpoints,"routed_edges":routed_edges
})
}
#[derive(Clone)]
struct Builder {
project: Project,
diagram: Id,
@@ -735,6 +757,631 @@ fn observe(name: &str, f: Builder) -> Value {
"second_layout_exact":second.as_ref().is_ok_and(|s|s.project==after),"second_layout_error":second.err().map(|e|e.to_string()),
"before_roundtrip":roundtrip(&before),"after_roundtrip":roundtrip(&after)}})
}
fn route_corpus(path: &std::path::Path) {
let text = std::fs::read_to_string(path).expect("Read frozen routing corpus manifest");
let manifest: Value = serde_json::from_str(&text).expect("Parse corpus manifest");
assert_eq!(manifest["schema"], 1);
let directory = path.parent().expect("Corpus manifest directory");
let mut names = BTreeSet::new();
let mut prepared = Vec::new();
for case in manifest["cases"].as_array().expect("Corpus cases") {
let name = case["name"].as_str().expect("Case name");
assert!(names.insert(name.to_owned()), "Duplicate case name");
let file = std::path::Path::new(case["project_file"].as_str().expect("Project file"));
assert!(
file.components()
.all(|part| matches!(part, std::path::Component::Normal(_))),
"Corpus project files must use relative normal components"
);
let project: Project = serde_json::from_str(
&std::fs::read_to_string(directory.join(file)).expect("Read frozen Project"),
)
.expect("Decode frozen Project");
validate_candidate(&project).expect("Validate frozen Project");
let diagram: Id = serde_json::from_value(case["diagram"].clone()).expect("Diagram UUID");
assert!(
project.diagrams.contains_key(&diagram),
"Missing corpus diagram"
);
prepared.push((name.to_owned(), project, diagram));
}
assert!(!prepared.is_empty(), "Empty corpus");
println!(
"{}",
json!({"probe":"routing_corpus_geometry_v1","metric_selfchecks":"passed",
"mode":"Route-only observation of frozen authored Projects; no Layout, reset or timing.",
"manifest":manifest,"quality_thresholds":null,
"limitations":"Existing raw geometry metrics; estimated main-label rectangles, no glyph or port-label acceptance. Folded promotion is observed, not passed to the unsupported layered prototype. Automatic non-port attachment coordinates may legally change across router variants."})
);
for (name, project, diagram) in prepared {
println!(
"{}",
json!({"fixture":name,"diagram":diagram,"before_project":project,
"before":metrics(&project,diagram),"roundtrip":roundtrip(&project)})
);
}
}
// External placement is an experimental geometry transfer, not a production command.
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct PlacementPlan {
schema: u32,
nodes: Vec<PlacementNode>,
}
#[derive(serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct PlacementNode {
id: Id,
position: Position,
size: Size,
}
fn import_placement(
original: &Project,
diagram: Id,
plan: PlacementPlan,
) -> Result<Project, ModelError> {
let fail = |message: &str| ModelError(message.to_owned());
validate_candidate(original)?;
let d = original
.diagrams
.get(&diagram)
.ok_or_else(|| fail("Missing diagram"))?;
if d.projection.scenario().is_some() {
return Err(fail("Scenario placement import is unsupported"));
}
if plan.schema != 1 || d.nodes.len() > 256 || plan.nodes.len() > 256 {
return Err(fail("Placement schema or 256-node bound exceeded"));
}
let view = projection::project_view(original, diagram);
if view.edges.len() > 1024 {
return Err(fail("Placement 1024-visible-edge bound exceeded"));
}
let visible: BTreeSet<_> = view.nodes.iter().map(|node| node.id).collect();
let mut supplied = BTreeSet::new();
for node in &plan.nodes {
if !supplied.insert(node.id)
|| !visible.contains(&node.id)
|| !node.position.x.is_finite()
|| !node.position.y.is_finite()
|| !node.size.width.is_finite()
|| !node.size.height.is_finite()
|| node.size.width <= 0.0
|| node.size.height <= 0.0
{
return Err(fail("Invalid, duplicate or out-of-scope placement"));
}
}
if supplied != visible {
return Err(fail(
"Plan must contain every projected visible node exactly once",
));
}
let eligible: BTreeSet<_> = view
.edges
.iter()
.filter_map(|edge| {
let owners = projection::edge_endpoint_placements(original, d, edge.id)?;
(owners == (edge.source, edge.target)
&& visible.contains(&edge.source)
&& visible.contains(&edge.target))
.then_some(edge.id)
})
.collect();
// Recover core visual ancestry, including Allocation grouping, without
// reimplementing private parents(). This temporary clone is never returned.
let mut unfolded = original.clone();
for node in unfolded
.diagrams
.get_mut(&diagram)
.unwrap()
.nodes
.values_mut()
{
node.collapsed = false;
}
let full = projection::project_view(&unfolded, diagram);
let parents: BTreeMap<_, _> = full.nodes.iter().map(|n| (n.id, n.visual_parent)).collect();
let mut hidden_owner = BTreeMap::new();
for id in parents.keys() {
let mut seen = BTreeSet::from([*id]);
let mut parent = parents[id];
let mut nearest = None;
while let Some(ancestor) = parent {
if seen.len() > 256 || !seen.insert(ancestor) {
return Err(fail("Invalid cyclic or excessive visual ancestry"));
}
if nearest.is_none() && visible.contains(&ancestor) && d.nodes[&ancestor].collapsed {
nearest = Some(ancestor);
}
parent = *parents
.get(&ancestor)
.ok_or_else(|| fail("Missing visual ancestor"))?;
}
if !visible.contains(id)
&& let Some(owner) = nearest
{
hidden_owner.insert(*id, owner);
}
}
let mut after = original.clone();
let ad = after.diagrams.get_mut(&diagram).unwrap();
let intended: BTreeMap<_, _> = plan
.nodes
.iter()
.map(|node| (node.id, (node.position, node.size)))
.collect();
for node in plan.nodes {
let placed = ad
.nodes
.get_mut(&node.id)
.ok_or_else(|| fail("Projected node is not stored"))?;
let projected_size = view.nodes.iter().find(|n| n.id == node.id).unwrap().size;
if placed.collapsed {
if node.size != projected_size {
return Err(fail(
"Collapsed placement plan must retain exact projected compact size; stored expanded size is preserved",
));
}
} else if node.size != projected_size {
// Unchanged effective size must not bake derived projection minima
// into authored geometry during an identity transfer.
placed.size = node.size;
}
placed.position = node.position;
}
for (id, owner) in hidden_owner {
let delta = Position {
x: ad.nodes[&owner].position.x - d.nodes[&owner].position.x,
y: ad.nodes[&owner].position.y - d.nodes[&owner].position.y,
};
let hidden = ad.nodes.get_mut(&id).unwrap();
hidden.position.x = d.nodes[&id].position.x + delta.x;
hidden.position.y = d.nodes[&id].position.y + delta.y;
}
let deltas: BTreeMap<_, _> = ad
.nodes
.iter()
.map(|(id, n)| {
(
*id,
Position {
x: n.position.x - d.nodes[id].position.x,
y: n.position.y - d.nodes[id].position.y,
},
)
})
.collect();
let translated: BTreeMap<_, _> = projection::translated_routes(original, d, &deltas)
.into_iter()
.map(|route| (route.edge, route))
.collect();
for route in &mut ad.routes {
if eligible.contains(&route.edge) {
route.waypoints.clear();
route.label = None;
} else if let Some(moved) = translated.get(&route.edge) {
*route = moved.clone();
}
}
for node in ad.nodes.values() {
if !node.position.x.is_finite() || !node.position.y.is_finite() {
return Err(fail("Placement translation overflow"));
}
}
validate_candidate(&after)?;
let mut final_view = projection::project_view(&after, diagram);
// Moving children inward can remove a formerly derived container minimum.
// Preserve authored size for true identity transfers, but materialize a
// requested unchanged effective size when reprojection would shrink it.
// This is one simultaneous restoration, never an iterative layout repair.
let mut restore_minima = Vec::new();
let original_sizes: BTreeMap<_, _> = view.nodes.iter().map(|n| (n.id, n.size)).collect();
let projected_ids: BTreeSet<_> = final_view.nodes.iter().map(|n| n.id).collect();
if projected_ids != visible || final_view.nodes.len() != visible.len() {
return Err(fail(
"Final Rust projection differs from intended node identities",
));
}
for node in &final_view.nodes {
let (position, size) = intended[&node.id];
if node.position == position && node.size == size {
continue;
}
if node.position != position
|| d.nodes[&node.id].collapsed
|| original_sizes[&node.id] != size
|| node.size.width > size.width
|| node.size.height > size.height
{
return Err(fail(
"Final Rust projection differs from intended node geometry",
));
}
restore_minima.push((node.id, size));
}
if !restore_minima.is_empty() {
for (id, size) in restore_minima {
after
.diagrams
.get_mut(&diagram)
.unwrap()
.nodes
.get_mut(&id)
.unwrap()
.size = size;
}
validate_candidate(&after)?;
final_view = projection::project_view(&after, diagram);
}
if final_view.nodes.len() != intended.len()
|| final_view
.nodes
.iter()
.any(|node| intended.get(&node.id) != Some(&(node.position, node.size)))
{
return Err(fail(
"Final Rust projection differs from intended node geometry",
));
}
Ok(after)
}
#[cfg(test)]
mod placement_import_tests {
use super::*;
fn nested() -> Builder {
fixtures()
.into_iter()
.find(|(name, _)| *name == "two_containers_reversed_children")
.unwrap()
.1
}
fn identity(project: &Project, diagram: Id) -> PlacementPlan {
PlacementPlan {
schema: 1,
nodes: projection::project_view(project, diagram)
.nodes
.into_iter()
.map(|n| PlacementNode {
id: n.id,
position: n.position,
size: n.size,
})
.collect(),
}
}
#[test]
fn unchanged_effective_container_size_survives_inward_child_movement() {
let f = nested();
let before = projection::project_view(&f.project, f.diagram);
let mut plan = identity(&f.project, f.diagram);
let mut expected = f.project.clone();
for node in &mut plan.nodes {
let projected = before.nodes.iter().find(|n| n.id == node.id).unwrap();
if projected.visual_parent.is_some() && node.position.y == 330.0 {
node.position.y -= 20.0;
expected
.diagrams
.get_mut(&f.diagram)
.unwrap()
.nodes
.get_mut(&node.id)
.unwrap()
.position = node.position;
}
if projected.visual_parent.is_none() {
expected
.diagrams
.get_mut(&f.diagram)
.unwrap()
.nodes
.get_mut(&node.id)
.unwrap()
.size = node.size;
}
}
let after = import_placement(&f.project, f.diagram, plan).unwrap();
assert_eq!(after, expected);
let final_view = projection::project_view(&after, f.diagram);
for node in &final_view.nodes {
assert_eq!(
node.size,
before.nodes.iter().find(|n| n.id == node.id).unwrap().size
);
}
}
#[test]
fn identity_keeps_authored_expanded_and_folded_sizes() {
let mut f = nested();
assert_eq!(
import_placement(&f.project, f.diagram, identity(&f.project, f.diagram)).unwrap(),
f.project
);
let parent = projection::project_view(&f.project, f.diagram)
.nodes
.into_iter()
.find(|n| n.visual_parent.is_none())
.unwrap()
.id;
f.project
.diagrams
.get_mut(&f.diagram)
.unwrap()
.nodes
.get_mut(&parent)
.unwrap()
.collapsed = true;
assert_eq!(
import_placement(&f.project, f.diagram, identity(&f.project, f.diagram)).unwrap(),
f.project
);
}
#[test]
fn inconsistent_smaller_container_plan_still_rejects() {
let f = nested();
let child = projection::project_view(&f.project, f.diagram)
.nodes
.into_iter()
.find(|n| n.visual_parent.is_some())
.unwrap()
.id;
let mut plan = identity(&f.project, f.diagram);
plan.nodes
.iter_mut()
.find(|n| n.id == child)
.unwrap()
.position
.x += 1000.0;
assert!(import_placement(&f.project, f.diagram, plan).is_err());
}
}
fn import_placement_cli(
project_file: &std::path::Path,
diagram_text: &std::ffi::OsStr,
plan_file: &std::path::Path,
) {
let before: Project =
serde_json::from_slice(&std::fs::read(project_file).expect("Read Project"))
.expect("Decode Project");
let diagram: Id = diagram_text
.to_str()
.expect("UTF-8 UUID")
.parse()
.expect("Diagram UUID");
let plan: PlacementPlan =
serde_json::from_slice(&std::fs::read(plan_file).expect("Read placement plan"))
.expect("Decode placement plan");
let after = import_placement(&before, diagram, plan).expect("Validate placement transfer");
println!(
"{}",
json!({"probe":"external_placement_v1", "diagram":diagram,
"scope":"Visible positions and expanded-node sizes imported; collapsed planned size must equal original projected compact size, stored expanded size preserved. Hidden descendants translated with nearest visible collapsed ancestor; unrelated omitted placements exact. Existing eligible routes reset, retained routes use original-to-final translation. No ELK paths, labels or ports imported; no Layout executed.",
"before_project":before,"after_project":after,"before":metrics(&before,diagram),"after":metrics(&after,diagram),
"conservation":conservation(&before,&after,diagram),"roundtrip":roundtrip(&after),
"final_projected_ports":projection::project_view(&after,diagram).ports})
);
}
fn lead_diagnostics(project: &Project, diagram: Id) -> Value {
let view = projection::project_view(project, diagram);
let endpoint = |e: &routing::LeadEndpoint| {
json!({"owner":e.owner,"tip":e.tip,"stub":e.stub,
"blockers":e.blockers.iter().map(|b|json!({"id":b.id,"bounds":{"position":b.bounds.position,"size":b.bounds.size}})).collect::<Vec<_>>(),
"stub_containers":e.stub_containers.iter().map(|b|json!({"id":b.id,"bounds":{"position":b.bounds.position,"size":b.bounds.size}})).collect::<Vec<_>>()})
};
json!(
routing::lead_incompatibilities(project, &project.diagrams[&diagram], &view)
.iter()
.map(
|r| json!({"edge":r.edge,"allowed_pair_count":r.allowed_pair_count,
"lead_clear_pair_count":r.lead_clear_pair_count,
"source":r.source.iter().map(&endpoint).collect::<Vec<_>>(),
"target":r.target.iter().map(&endpoint).collect::<Vec<_>>()})
)
.collect::<Vec<_>>()
)
}
fn repaired_candidate(before: &Project, diagram: Id) -> Result<Project, ModelError> {
let geometry = clearance::repair(before, diagram)?;
let view = projection::project_view(&geometry, diagram);
// Reconstruct metadata once from original to final geometry with the same
// audited reset/translation policy used by the placement reference.
import_placement(
before,
diagram,
PlacementPlan {
schema: 1,
nodes: view
.nodes
.iter()
.map(|n| PlacementNode {
id: n.id,
position: n.position,
size: n.size,
})
.collect(),
},
)
}
fn repair_placement_cli(project_file: &std::path::Path, diagram_text: &std::ffi::OsStr) {
let before: Project =
serde_json::from_slice(&std::fs::read(project_file).expect("Read Project"))
.expect("Decode Project");
let diagram: Id = diagram_text
.to_str()
.expect("UTF-8 UUID")
.parse()
.expect("Diagram UUID");
validate_candidate(&before).expect("Validate input");
assert!(before.diagrams.contains_key(&diagram), "Missing diagram");
let candidate = match repaired_candidate(&before, diagram) {
Err(error) => json!({"supported":false,"error":error.to_string()}),
Ok(after) => {
let duplicate = repaired_candidate(&before, diagram);
let mut previous = after.clone();
let mut stability = Vec::new();
for pass in 2..=10 {
match repaired_candidate(&previous, diagram) {
Ok(next) => {
stability.push(json!({"pass":pass,"equal_previous":next==previous,"equal_first":next==after}));
previous = next;
}
Err(error) => {
stability.push(json!({"pass":pass,"error":error.to_string()}));
break;
}
}
}
json!({"supported":true,"project":after,"metrics":metrics(&after,diagram),
"lead_incompatibilities":lead_diagnostics(&after,diagram),
"conservation":conservation(&before,&after,diagram),"roundtrip":roundtrip(&after),
"same_input_exact":duplicate.as_ref().is_ok_and(|p|*p==after),
"ten_repair_calls":stability})
}
};
println!(
"{}",
json!({"probe":"placement_clearance_v1","diagram":diagram,
"scope":"Experimental flat monotone separation only; lead clearance is necessary, not sufficient routing or readability acceptance. Unsupported topology and unresolved constraints remain explicit. Existing router and command behavior unchanged.",
"before_project":before,"before":metrics(&before,diagram),
"before_lead_incompatibilities":lead_diagnostics(&before,diagram),"candidate":candidate})
);
}
fn scc_observe(name: &str, f: Builder) -> Value {
placement_observe(name, f, false)
}
fn placement_observe(name: &str, f: Builder, boundary_order: bool) -> Value {
let before = f.project;
let diagram = f.diagram;
validate_candidate(&before).expect("Validate SCC input");
let with_diagnostics = |p: &Project| {
if boundary_order {
condensed::boundary_candidate_with_diagnostics(p, diagram)
} else {
condensed::candidate_with_diagnostics(p, diagram)
}
};
let propose = |p: &Project| {
if boundary_order {
condensed::boundary_candidate_with_diagnostics(p, diagram).map(|(p, _)| p)
} else {
condensed::candidate(p, diagram)
}
};
let candidate = match with_diagnostics(&before) {
Err(error) => json!({"supported":false,"error":error.to_string()}),
Ok((after, plan)) => {
let same = propose(&before);
let mut repeated = after.clone();
let mut stability = Vec::new();
for pass in 2..=10 {
match propose(&repeated) {
Ok(next) => {
stability.push(json!({"pass":pass,"equal_previous":next==repeated,"equal_first":next==after}));
repeated = next;
}
Err(error) => {
stability.push(json!({"pass":pass,"error":error.to_string()}));
break;
}
}
}
json!({"supported":true,"project":after,"plan":plan,"metrics":metrics(&after,diagram),
"lead_incompatibilities":lead_diagnostics(&after,diagram),
"conservation":conservation(&before,&after,diagram),"roundtrip":roundtrip(&after),
"same_input_exact":same.as_ref().is_ok_and(|p|*p==after),"ten_candidate_calls":stability})
}
};
json!({"fixture":name,"diagram":diagram,"before_project":before,
"before":metrics(&before,diagram),"candidate":candidate})
}
fn scc_placement_cli(
project_file: &std::path::Path,
diagram_text: &std::ffi::OsStr,
boundary_order: bool,
) {
let project: Project =
serde_json::from_slice(&std::fs::read(project_file).expect("Read Project"))
.expect("Decode Project");
let diagram: Id = diagram_text
.to_str()
.expect("UTF-8 UUID")
.parse()
.expect("Diagram UUID");
println!(
"{}",
placement_observe(
"external_case",
Builder {
project,
diagram,
next: 0,
witness: None
},
boundary_order,
)
);
}
fn arrange_corpus(path: &std::path::Path) {
let manifest: Value = serde_json::from_slice(&std::fs::read(path).expect("Read manifest"))
.expect("Decode manifest");
assert_eq!(manifest["schema"], 1);
let mut names = BTreeSet::new();
let cases = manifest["cases"].as_array().expect("Cases");
assert!(!cases.is_empty(), "Empty corpus");
println!(
"{}",
json!({"probe":"arrange_corpus_v1","manifest":manifest,"quality_thresholds":null})
);
for case in cases {
let name = case["name"].as_str().expect("Case name");
assert!(names.insert(name), "Duplicate case name");
let file = std::path::Path::new(case["project_file"].as_str().expect("Project file"));
assert!(
file.components()
.all(|c| matches!(c, std::path::Component::Normal(_))),
"Relative normal project path required"
);
let project: Project = serde_json::from_slice(
&std::fs::read(path.parent().unwrap().join(file)).expect("Read Project"),
)
.expect("Decode Project");
let diagram: Id = serde_json::from_value(case["diagram"].clone()).expect("Diagram UUID");
validate_candidate(&project).expect("Validate corpus Project");
assert!(project.diagrams.contains_key(&diagram), "Missing diagram");
assert!(
project.diagrams[&diagram].nodes.len() <= 256,
"256-node bound"
);
assert!(
projection::project_view(&project, diagram).edges.len() <= 1024,
"1024-edge bound"
);
println!(
"{}",
observe(
name,
Builder {
project,
diagram,
next: 0,
witness: None
}
)
);
}
}
fn main() {
// Analytic checks validate the observer, not any layout's quality.
let horizontal = [(0., 0.), (10., 0.)];
@@ -773,6 +1420,63 @@ fn main() {
assert_eq!(overlap((0., 0., 10., 10.), (10., 0., 20., 10.)), 0.);
assert!((inside_length((0., 5.), (10., 5.), (2., 2., 8., 8.)) - 6.).abs() < 3. * EPS);
assert_eq!(inside_length((0., 2.), (10., 2.), (2., 2., 8., 8.)), 0.);
let args: Vec<_> = std::env::args_os().collect();
if args.len() == 3 && args[1] == "--route-corpus" {
route_corpus(std::path::Path::new(&args[2]));
return;
}
if args.len() == 3 && args[1] == "--arrange-corpus" {
arrange_corpus(std::path::Path::new(&args[2]));
return;
}
if args.len() == 5 && args[1] == "--import-placement" {
import_placement_cli(
std::path::Path::new(&args[2]),
&args[3],
std::path::Path::new(&args[4]),
);
return;
}
if args.len() == 4 && args[1] == "--repair-placement" {
repair_placement_cli(std::path::Path::new(&args[2]), &args[3]);
return;
}
if args.len() == 4 && args[1] == "--scc-placement" {
scc_placement_cli(std::path::Path::new(&args[2]), &args[3], false);
return;
}
if args.len() == 4 && args[1] == "--boundary-placement" {
scc_placement_cli(std::path::Path::new(&args[2]), &args[3], true);
return;
}
if args.len() == 2 && args[1] == "--scc-fixtures" {
for (name, f) in fixtures() {
println!("{}", scc_observe(name, f));
}
return;
}
if args.len() == 2 && args[1] == "--boundary-fixtures" {
for (name, f) in fixtures() {
println!("{}", placement_observe(name, f, true));
}
return;
}
if args.len() == 2 && args[1] == "--boundary-extra-fixtures" {
for (name, f) in boundary_fixtures::fixtures() {
println!(
"{}",
json!({"fixture":name,
"baseline":scc_observe(name, f.clone()),
"boundary":placement_observe(name, f, true)})
);
}
return;
}
assert_eq!(
args.len(),
1,
"Usage: auto_layout_probe [--route-corpus MANIFEST | --arrange-corpus MANIFEST | --import-placement PROJECT UUID PLAN | --repair-placement PROJECT UUID | --scc-placement PROJECT UUID | --scc-fixtures | --boundary-placement PROJECT UUID | --boundary-fixtures | --boundary-extra-fixtures]"
);
println!(
"{}",
json!({"probe":"auto_layout_probe_v2","reference_source":"715036e132677dd2bc2fb37ed316d93dc9987aec","metric_selfchecks":"passed", "quality_thresholds":null,
@@ -0,0 +1,131 @@
//! Independent structural falsifiers for incoming boundary ordering.
use super::*;
fn pair(f: &mut Builder, name: &str, x: f32) -> (Id, Id, Id) {
let parent = f.function(name, None, x, 40.0);
let a = f.function(&format!("{name} A"), Some(parent), x + 60.0, 130.0);
let b = f.function(&format!("{name} B"), Some(parent), x + 60.0, 330.0);
(parent, a, b)
}
pub(super) fn fixtures() -> Vec<(&'static str, Builder)> {
let mut all = Vec::new();
let mut f = Builder::new("boundary_opposing_parents");
let (_, la, lb) = pair(&mut f, "Left", 40.0);
let (_, ra, rb) = pair(&mut f, "Right", 820.0);
for (name, a, b) in [
("Reverse upper", la, rb),
("Reverse lower", lb, ra),
("Return upper", ra, la),
("Return lower", rb, lb),
] {
f.exchange(name, a, b);
}
all.push(("boundary_opposing_parents", f));
let mut f = Builder::new("boundary_three_parent_chain");
let (_, la, lb) = pair(&mut f, "Left", 40.0);
let (middle, ma, mb) = pair(&mut f, "Middle", 820.0);
let (_, ra, rb) = pair(&mut f, "Right", 1600.0);
for (name, a, b) in [
("Left upper", la, mb),
("Left lower", lb, ma),
("Middle upper", mb, ra),
("Middle lower", ma, rb),
] {
f.exchange(name, a, b);
}
let mut translated = f.clone();
for element in [middle, ma, mb] {
let node = translated.node(element);
let position = &mut translated
.project
.diagrams
.get_mut(&translated.diagram)
.unwrap()
.nodes
.get_mut(&node)
.unwrap()
.position;
position.x += 300.0;
position.y += 500.0;
}
let mut permuted = f.clone();
let ids: Vec<_> = permuted.project.relations.keys().copied().collect();
for (i, id) in ids.iter().enumerate() {
reidentify(
&mut permuted.project,
*id,
Id::from_u128(1_000_000 + i as u128),
)
.unwrap();
}
for (i, id) in ids.iter().rev().enumerate() {
reidentify(
&mut permuted.project,
Id::from_u128(1_000_000 + i as u128),
*id,
)
.unwrap();
}
all.push(("boundary_three_parent_chain", f));
all.push(("boundary_three_parent_translated", translated));
all.push(("boundary_three_parent_edge_ids_reversed", permuted));
let mut f = Builder::new("boundary_two_local_sccs");
let (_, sa, sb) = pair(&mut f, "Source", 40.0);
let target = f.function("Target", None, 820.0, 40.0);
let x1 = f.function("X1", Some(target), 880.0, 130.0);
let x2 = f.function("X2", Some(target), 1200.0, 130.0);
let y1 = f.function("Y1", Some(target), 880.0, 330.0);
let y2 = f.function("Y2", Some(target), 1200.0, 330.0);
let z = f.function("Z", Some(target), 1520.0, 230.0);
for (name, a, b) in [
("X forward", x1, x2),
("X back", x2, x1),
("Y forward", y1, y2),
("Y back", y2, y1),
("X result", x2, z),
("Y result", y2, z),
("Upper boundary", sa, y1),
("Lower boundary", sb, x1),
] {
f.exchange(name, a, b);
}
all.push(("boundary_two_local_sccs", f));
let mut f = super::fixtures()
.into_iter()
.find(|(name, _)| *name == "two_containers_reversed_children")
.unwrap()
.1;
let relations: Vec<_> = f.project.relations.values().cloned().collect();
for relation in relations {
if let RelationBody::FunctionalExchange {
source_port,
target_port,
..
} = relation.body
{
for (port, side, offset) in [
(source_port, PortAnchorSide::Right, 0.3),
(target_port, PortAnchorSide::Left, 0.7),
] {
let owner = f.project.elements[&port].parent.unwrap();
let node = f.node(owner);
f.project = prepare_command(
&f.project,
&Command::SetPortAnchor {
diagram: f.diagram,
node,
anchor: PortAnchor { port, side, offset },
},
)
.unwrap()
.project;
}
}
}
all.push(("boundary_two_containers_anchored", f));
all
}
@@ -0,0 +1,279 @@
//! Bounded flat-placement experiment. Empty lead diagnostics are necessary only,
//! never a claim that routes, labels, or drawing quality are acceptable.
use oa_core::{Id, ModelError, Project, projection, routing};
use std::collections::BTreeMap;
const ROUNDS: usize = 4;
const WORK_LIMIT: usize = 10_000_000;
const MAX_SPAN: f32 = 100_000.0;
const MARGIN: f32 = 1.0;
fn fail(message: &str) -> ModelError {
ModelError(format!("Clearance probe: {message}"))
}
fn spend(work: &mut usize, amount: usize) -> Result<(), ModelError> {
*work = work.saturating_add(amount);
if *work > WORK_LIMIT {
return Err(fail("work limit exceeded"));
}
Ok(())
}
// A boundary constraint means start[to] >= start[from] + extent[from] + gap.
// Adjacent total-order constraints below separately preserve start ordering.
type Constraints = BTreeMap<(usize, usize), f32>;
fn solve(
baseline: &[f32],
extents: &[f32],
order: &[usize],
constraints: &Constraints,
work: &mut usize,
) -> Result<Vec<f32>, ModelError> {
let mut result = baseline.to_vec();
let mut previous = None;
for &to in order {
if let Some(from) = previous {
result[to] = result[to].max(result[from]);
}
for (&(from, target), &gap) in constraints {
spend(work, 1)?;
if target == to {
result[to] = result[to].max(result[from] + extents[from] + gap);
}
}
previous = Some(to);
}
let minimum = baseline.iter().copied().fold(f32::INFINITY, f32::min);
for (i, &value) in result.iter().enumerate() {
if !value.is_finite() || value + extents[i] - minimum > MAX_SPAN {
return Err(fail("coordinate/span bound exceeded"));
}
}
Ok(result)
}
/// Input is an already admitted placement candidate. Never modifies its routes,
/// authored anchors, sizes or semantics. Error drops the private clone.
pub fn repair(project: &Project, diagram: Id) -> Result<Project, ModelError> {
let original = project
.diagrams
.get(&diagram)
.ok_or_else(|| fail("missing diagram"))?;
if original.projection.scenario().is_some() {
return Err(fail("Scenario unsupported"));
}
let baseline = projection::project_diagram(project, original);
if baseline.nodes.len() > 256 || baseline.edges.len() > 1024 {
return Err(fail("graph bound exceeded"));
}
if baseline.nodes.len() != original.nodes.len()
|| baseline
.nodes
.iter()
.any(|n| n.collapsed || n.visual_parent.is_some())
{
return Err(fail("nested, folded or omitted placements unsupported"));
}
let mut nodes = baseline.nodes.clone();
nodes.sort_by_key(|n| n.id);
if nodes.iter().any(|n| {
!n.position.x.is_finite()
|| !n.position.y.is_finite()
|| !n.size.width.is_finite()
|| !n.size.height.is_finite()
|| n.size.width <= 0.0
|| n.size.height <= 0.0
}) {
return Err(fail("invalid initial geometry"));
}
let indices: BTreeMap<_, _> = nodes.iter().enumerate().map(|(i, n)| (n.id, i)).collect();
let coordinates = [
nodes.iter().map(|n| n.position.x).collect::<Vec<_>>(),
nodes.iter().map(|n| n.position.y).collect::<Vec<_>>(),
];
let extents = [
nodes.iter().map(|n| n.size.width).collect::<Vec<_>>(),
nodes.iter().map(|n| n.size.height).collect::<Vec<_>>(),
];
for axis in 0..2 {
let minimum = coordinates[axis]
.iter()
.copied()
.fold(f32::INFINITY, f32::min);
if coordinates[axis]
.iter()
.zip(&extents[axis])
.any(|(&start, &extent)| {
!(start + extent).is_finite() || start + extent - minimum > MAX_SPAN
})
{
return Err(fail("initial coordinate/span bound exceeded"));
}
}
let mut orders = [Vec::new(), Vec::new()];
let mut ranks = [vec![0; nodes.len()], vec![0; nodes.len()]];
for axis in 0..2 {
orders[axis] = (0..nodes.len()).collect();
orders[axis].sort_by(|&a, &b| {
coordinates[axis][a]
.total_cmp(&coordinates[axis][b])
.then(nodes[a].id.cmp(&nodes[b].id))
});
for (rank, &i) in orders[axis].iter().enumerate() {
ranks[axis][i] = rank;
}
}
let mut constraints = [Constraints::new(), Constraints::new()];
let mut work = 0;
// Preserve one existing disjoint axis per pair, X before Y. No initially
// overlapping pair is silently treated as successfully repaired.
for a in 0..nodes.len() {
for b in a + 1..nodes.len() {
spend(&mut work, 1)?;
let mut chosen = None;
for axis in 0..2 {
for (from, to) in [(a, b), (b, a)] {
let gap = coordinates[axis][to] - coordinates[axis][from] - extents[axis][from];
if gap >= 0.0 {
chosen = Some((axis, from, to, gap));
break;
}
}
if chosen.is_some() {
break;
}
}
let (axis, from, to, gap) =
chosen.ok_or_else(|| fail("initial node overlap unsupported"))?;
constraints[axis].insert((from, to), gap);
}
}
let mut result = project.clone();
for round in 0..=ROUNDS {
let current = &result.diagrams[&diagram];
let view = projection::project_diagram(&result, current);
if view.nodes.len() != nodes.len()
|| view.nodes.iter().any(|n| {
indices.get(&n.id).is_none_or(|&i| {
n.size != nodes[i].size || n.collapsed || n.visual_parent.is_some()
})
})
{
return Err(fail("reprojection changed node identity/size/topology"));
}
// Charge work units proportional to node count and at most sixteen
// endpoint pairs. This is not an exact operation count or a bound on
// all projection work; graph, round and span limits apply separately.
spend(
&mut work,
view.edges
.len()
.saturating_mul(nodes.len().saturating_add(1))
.saturating_mul(16),
)?;
let failures = routing::lead_incompatibilities(&result, current, &view);
if failures.is_empty() {
return Ok(result);
}
if round == ROUNDS {
return Err(fail("unresolved mandatory leads after four adjustments"));
}
let mut strengthened = false;
for failure in failures {
if failure.allowed_pair_count != 1
|| failure.source.len() != 1
|| failure.target.len() != 1
{
return Err(fail("ambiguous endpoint choices unsupported"));
}
for endpoint in failure.source.iter().chain(&failure.target) {
let owner = *indices
.get(&endpoint.owner)
.ok_or_else(|| fail("unknown endpoint owner"))?;
let dx = endpoint.stub.x - endpoint.tip.x;
let dy = endpoint.stub.y - endpoint.tip.y;
if endpoint.blockers.is_empty() {
continue;
}
let (axis, forward) = match (dx, dy) {
(x, 0.0) if x != 0.0 => (0, x > 0.0),
(0.0, y) if y != 0.0 => (1, y > 0.0),
_ => return Err(fail("noncardinal/degenerate blocked lead")),
};
for blocker in &endpoint.blockers {
spend(&mut work, 1)?;
let other = *indices
.get(&blocker.id)
.ok_or_else(|| fail("unknown blocker"))?;
let (from, to) = if forward {
(owner, other)
} else {
(other, owner)
};
if ranks[axis][from] >= ranks[axis][to] {
return Err(fail("lead constraint opposes frozen spatial order"));
}
let required = routing::PORT_STUB + routing::CLEARANCE + MARGIN;
let old = constraints[axis].entry((from, to)).or_insert(0.0);
if *old < required {
*old = required;
strengthened = true;
}
}
}
}
if !strengthened {
return Err(fail(
"unresolved lead without a stronger monotone constraint",
));
}
let x = solve(
&coordinates[0],
&extents[0],
&orders[0],
&constraints[0],
&mut work,
)?;
let y = solve(
&coordinates[1],
&extents[1],
&orders[1],
&constraints[1],
&mut work,
)?;
let target = result.diagrams.get_mut(&diagram).unwrap();
for (i, node) in nodes.iter().enumerate() {
let placed = target.nodes.get_mut(&node.id).unwrap();
placed.position.x = x[i];
placed.position.y = y[i];
}
}
unreachable!("bounded loop returns on final round")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn separation_propagates_to_neighbor_without_moving_predecessor() {
let constraints = BTreeMap::from([((0, 1), 31.0), ((1, 2), 10.0)]);
let actual = solve(
&[-20.0, 100.0, 210.0],
&[100.0; 3],
&[0, 1, 2],
&constraints,
&mut 0,
)
.unwrap();
assert_eq!(actual, vec![-20.0, 111.0, 221.0]);
}
#[test]
fn extent_bound_rejects_constraint_expansion() {
let constraints = BTreeMap::from([((0, 1), MAX_SPAN)]);
assert!(solve(&[0.0, 20.0], &[10.0; 2], &[0, 1], &constraints, &mut 0).is_err());
}
}
@@ -0,0 +1,654 @@
//! Isolated SCC-block placement experiment; no production-layout acceptance.
use super::{PlacementNode, PlacementPlan, import_placement};
use oa_core::{Id, ModelError, Position, Project, Size, projection, routing};
use std::collections::{BTreeMap, BTreeSet};
const LIMIT: usize = 20_000_000;
const PAD: f32 = 32.0;
const SPAN: f32 = 100_000.0;
#[path = "condensed/boundary.rs"]
mod boundary;
fn error(text: &str) -> ModelError {
ModelError(format!("SCC placement: {text}"))
}
fn charge(work: &mut usize, count: usize) -> Result<(), ModelError> {
*work = work.saturating_add(count);
if *work > LIMIT {
Err(error("work limit exceeded"))
} else {
Ok(())
}
}
fn components(arcs: &[BTreeSet<usize>], work: &mut usize) -> Result<Vec<Vec<usize>>, ModelError> {
let n = arcs.len();
let mut reach = vec![vec![false; n]; n];
for (start, reachable) in reach.iter_mut().enumerate() {
let mut todo = vec![start];
reachable[start] = true;
while let Some(at) = todo.pop() {
for &next in &arcs[at] {
charge(work, 1)?;
if !reachable[next] {
reachable[next] = true;
todo.push(next);
}
}
}
}
let mut used = vec![false; n];
let mut result = Vec::new();
for i in 0..n {
if used[i] {
continue;
}
let mut group = Vec::new();
for j in i..n {
charge(work, 1)?;
if !used[j] && reach[i][j] && reach[j][i] {
used[j] = true;
group.push(j);
}
}
result.push(group);
}
Ok(result)
}
fn perimeter_slots(n: usize, rows: usize, cols: usize) -> Vec<(usize, usize)> {
let mut slots = Vec::new();
if rows == 1 {
slots.extend((0..cols).map(|col| (col, 0)));
} else if cols == 1 {
slots.extend((0..rows).map(|row| (0, row)));
} else {
slots.extend((0..cols).map(|col| (col, 0)));
slots.extend((1..rows).map(|row| (cols - 1, row)));
slots.extend((0..cols - 1).rev().map(|col| (col, rows - 1)));
slots.extend((1..rows - 1).rev().map(|row| (0, row)));
}
slots.truncate(n);
slots
}
// Score occupied maximum-member cells, excluding unused perimeter slots.
// Heterogeneous members may occupy less than this nominal cell envelope.
fn perimeter(
n: usize,
cell: Size,
gap: Size,
work: &mut usize,
) -> Result<(Vec<Position>, usize, usize), ModelError> {
type GridScore = (bool, f32, f32, usize, usize);
let mut best: Option<(GridScore, usize, usize)> = None;
for rows in 1..=n {
for cols in 1..=n {
charge(work, 1)?;
let capacity = if rows == 1 || cols == 1 {
rows * cols
} else {
2 * rows + 2 * cols - 4
};
if capacity < n {
continue;
}
charge(work, capacity)?;
let slots = perimeter_slots(n, rows, cols);
let max_x = slots.iter().map(|p| p.0).max().unwrap();
let max_y = slots.iter().map(|p| p.1).max().unwrap();
let width = (max_x + 1) as f32 * cell.width + max_x as f32 * gap.width;
let height = (max_y + 1) as f32 * cell.height + max_y as f32 * gap.height;
let aspect = (width / height).max(height / width);
let key = (
aspect > 2.0,
if aspect <= 2.0 {
width * height
} else {
aspect
},
width * height,
rows,
cols,
);
if best.as_ref().is_none_or(|(old, _, _)| key < *old) {
best = Some((key, rows, cols));
}
}
}
let (_, rows, cols) = best.ok_or_else(|| error("no perimeter grid"))?;
let slots = perimeter_slots(n, rows, cols);
Ok((
slots
.into_iter()
.take(n)
.map(|(x, y)| Position {
x: x as f32 * (cell.width + gap.width),
y: y as f32 * (cell.height + gap.height),
})
.collect(),
rows,
cols,
))
}
fn lift(
id: Id,
parent: Option<Id>,
parents: &BTreeMap<Id, Option<Id>>,
work: &mut usize,
) -> Result<Option<Id>, ModelError> {
let mut at = id;
for _ in 0..=parents.len() {
charge(work, 1)?;
let Some(&up) = parents.get(&at) else {
return Err(error("missing visual ancestor"));
};
if up == parent {
return Ok(Some(at));
}
let Some(next) = up else {
return Ok(None);
};
at = next;
}
Err(error("cyclic visual ancestry"))
}
/// Frozen projected geometry is the minimum; folded nodes remain opaque.
pub fn candidate(project: &Project, diagram: Id) -> Result<Project, ModelError> {
candidate_with_diagnostics(project, diagram).map(|(result, _)| result)
}
pub fn candidate_with_diagnostics(
project: &Project,
diagram: Id,
) -> Result<(Project, serde_json::Value), ModelError> {
candidate_policy(project, diagram, false)
}
pub fn boundary_candidate_with_diagnostics(
project: &Project,
diagram: Id,
) -> Result<(Project, serde_json::Value), ModelError> {
candidate_policy(project, diagram, true)
}
fn candidate_policy(
project: &Project,
diagram: Id,
order_boundaries: bool,
) -> Result<(Project, serde_json::Value), ModelError> {
let d = project
.diagrams
.get(&diagram)
.ok_or_else(|| error("missing diagram"))?;
if d.projection.scenario().is_some() {
return Err(error("Scenario unsupported"));
}
if d.nodes.len() > 256 {
return Err(error("stored-node bound exceeded"));
}
let view = projection::project_diagram(project, d);
if view.edges.len() > 1024 {
return Err(error("visible-edge bound exceeded"));
}
if view.nodes.iter().any(|n| {
!n.size.width.is_finite()
|| !n.size.height.is_finite()
|| n.size.width <= 0.0
|| n.size.height <= 0.0
}) {
return Err(error("invalid projected minima"));
}
let parents: BTreeMap<_, _> = view.nodes.iter().map(|n| (n.id, n.visual_parent)).collect();
let names: BTreeMap<_, _> = view
.nodes
.iter()
.map(|n| (n.id, (project.elements[&n.element].alias.clone(), n.id)))
.collect();
let mut children: BTreeMap<Option<Id>, Vec<Id>> = BTreeMap::new();
for n in &view.nodes {
children.entry(n.visual_parent).or_default().push(n.id);
}
for ids in children.values_mut() {
ids.sort_by_key(|id| names[id].clone());
}
let mut work = 0;
let mut depth = BTreeMap::new();
for n in &view.nodes {
let mut at = n.id;
let mut count = 0;
let mut seen = BTreeSet::new();
while let Some(up) = *parents.get(&at).ok_or_else(|| error("missing parent"))? {
charge(&mut work, 1)?;
if !seen.insert(at) {
return Err(error("cyclic hierarchy"));
}
count += 1;
at = up;
}
depth.insert(n.id, count);
}
let routed = routing::route_diagram(project, d, &view);
let mut sizes: BTreeMap<_, _> = view.nodes.iter().map(|n| (n.id, n.size)).collect();
let mut offsets = BTreeMap::new();
let mut diagnostics = Vec::new();
let mut boundary_groups = Vec::new();
let mut groups: Vec<_> = children.keys().copied().collect();
groups.sort_by_key(|p| std::cmp::Reverse(p.map_or(0, |id| depth[&id] + 1)));
for parent in groups {
let ids = &children[&parent];
let index: BTreeMap<_, _> = ids.iter().enumerate().map(|(i, id)| (*id, i)).collect();
let mut arcs = vec![BTreeSet::new(); ids.len()];
let mut links = Vec::new();
let mut undirected = BTreeSet::new();
for edge in &view.edges {
charge(&mut work, 1)?;
let (Some(a), Some(b)) = (
lift(edge.source, parent, &parents, &mut work)?,
lift(edge.target, parent, &parents, &mut work)?,
) else {
continue;
};
if a == b {
continue;
}
let (a, b) = (index[&a], index[&b]);
if edge.oriented {
arcs[a].insert(b);
} else {
undirected.insert((ids[a].min(ids[b]), ids[a].max(ids[b])));
}
let routed_edge = routed
.edges
.get(&edge.id)
.ok_or_else(|| error("missing estimated edge label"))?;
let mut label = routed_edge.label.bounds.size;
if let Some(relation) = project.relations.get(&edge.id) {
for end in routing::association_end_geometry(relation, routed_edge) {
label.width = label.width.max(end.label.bounds.size.width);
label.height = label.height.max(end.label.bounds.size.height);
}
}
if !label.width.is_finite() || !label.height.is_finite() {
return Err(error("invalid estimated label"));
}
links.push((a, b, label));
}
let comps = components(&arcs, &mut work)?;
let mut owner = vec![0; ids.len()];
for (c, members) in comps.iter().enumerate() {
for &i in members {
owner[i] = c;
}
}
let mut dag = vec![BTreeSet::new(); comps.len()];
for (a, targets) in arcs.iter().enumerate() {
for &b in targets {
if owner[a] != owner[b] {
dag[owner[a]].insert(owner[b]);
}
}
}
let mut ranks = vec![0usize; comps.len()];
let mut done = BTreeSet::new();
while done.len() < comps.len() {
let next = (0..comps.len())
.find(|c| {
!done.contains(c)
&& (0..comps.len()).all(|p| !dag[p].contains(c) || done.contains(&p))
})
.ok_or_else(|| error("condensation is cyclic"))?;
charge(&mut work, comps.len() * comps.len())?;
for &to in &dag[next] {
ranks[to] = ranks[to].max(ranks[next] + 1);
}
done.insert(next);
}
let mut blocks = Vec::new();
let mut component_diagnostics = Vec::new();
let mut member_offsets = BTreeMap::new();
for (c, members) in comps.iter().enumerate() {
let mut gap = Size {
width: PAD,
height: PAD,
};
for &(a, b, label) in &links {
if owner[a] == c && owner[b] == c {
gap.width = gap.width.max(label.width + PAD);
gap.height = gap.height.max(label.height + PAD);
}
}
let mut order = Vec::new();
let mut seen = BTreeSet::new();
for &start in members {
let mut stack = vec![start];
while let Some(i) = stack.pop() {
charge(&mut work, 1)?;
if !seen.insert(i) {
continue;
}
order.push(i);
for &j in arcs[i].iter().rev() {
if owner[j] == c && !seen.contains(&j) {
stack.push(j);
}
}
}
}
let cell = Size {
width: members
.iter()
.map(|&i| sizes[&ids[i]].width)
.fold(0.0, f32::max),
height: members
.iter()
.map(|&i| sizes[&ids[i]].height)
.fold(0.0, f32::max),
};
let (slots, rows, cols) = if members.len() == 1 {
(vec![Position { x: 0.0, y: 0.0 }], 1, 1)
} else {
perimeter(members.len(), cell, gap, &mut work)?
};
component_diagnostics.push(serde_json::json!({"component":c,"rank":ranks[c],"members":members.iter().map(|&i|ids[i]).collect::<Vec<_>>(),"walk":order.iter().map(|&i|ids[i]).collect::<Vec<_>>(),"grid_rows":rows,"grid_cols":cols,"gap":gap}));
let mut size = Size {
width: 0.0,
height: 0.0,
};
for (i, pos) in order.into_iter().zip(slots) {
size.width = size.width.max(pos.x + sizes[&ids[i]].width);
size.height = size.height.max(pos.y + sizes[&ids[i]].height);
member_offsets.insert(i, pos);
}
blocks.push(size);
}
let max_rank = ranks.iter().copied().max().unwrap_or(0);
charge(
&mut work,
links
.len()
.saturating_mul(comps.len().saturating_add(1))
.saturating_mul(comps.len().saturating_add(1)),
)?;
let mut block_positions = vec![Position { x: 0.0, y: 0.0 }; comps.len()];
let mut x = 0.0;
let mut total = Size {
width: 0.0,
height: 0.0,
};
let mut prior_order = vec![0usize; comps.len()];
let mut bands = Vec::new();
for rank in 0..=max_rank {
let mut layer: Vec<_> = (0..comps.len()).filter(|&c| ranks[c] == rank).collect();
// Fixed one-pass proximity order, including undirected links, without
// inventing direction or changing condensation ranks.
layer.sort_by_key(|&c| {
let neighbors: Vec<_> = links
.iter()
.filter_map(|&(a, b, _)| {
let (a, b) = (owner[a], owner[b]);
if a == c && ranks[b] < rank {
Some(prior_order[b])
} else if b == c && ranks[a] < rank {
Some(prior_order[a])
} else {
None
}
})
.collect();
(
if neighbors.is_empty() {
c
} else {
neighbors.iter().sum::<usize>() / neighbors.len()
},
c,
)
});
// Keep same-rank undirected neighbours contiguous in one canonical
// breadth-first walk; these links never become directed rank arcs.
let mut proximity = Vec::new();
let mut remaining: BTreeSet<_> = layer.iter().copied().collect();
for &start in &layer {
if !remaining.remove(&start) {
continue;
}
let mut queue = std::collections::VecDeque::from([start]);
while let Some(c) = queue.pop_front() {
proximity.push(c);
for &next in &layer {
charge(&mut work, links.len() + 1)?;
if remaining.contains(&next)
&& links.iter().any(|&(a, b, _)| {
(owner[a] == c && owner[b] == next)
|| (owner[b] == c && owner[a] == next)
})
{
remaining.remove(&next);
queue.push_back(next);
}
}
}
}
layer = proximity;
let mut cut = Size {
width: PAD,
height: PAD,
};
for &(a, b, label) in &links {
if owner[a] != owner[b] && (ranks[owner[a]] == rank || ranks[owner[b]] == rank) {
cut.width = cut.width.max(label.width + PAD);
cut.height = cut.height.max(label.height + PAD);
}
}
let mut y = 0.0;
let mut width = 0.0_f32;
if order_boundaries && parent.is_some() {
bands.push(boundary::Band {
components: layer.clone(),
gap: cut.height,
});
}
for (i, c) in layer.into_iter().enumerate() {
prior_order[c] = i;
block_positions[c] = Position { x, y };
y += blocks[c].height + cut.height;
width = width.max(blocks[c].width);
}
total.width = total.width.max(x + width);
total.height = total.height.max((y - cut.height).max(0.0));
x += width + cut.width;
}
let header = if let Some(id) = parent {
let n = view.nodes.iter().find(|n| n.id == id).unwrap();
if n.collapsed {
return Err(error("folded node has projected children"));
}
if d.projection.state_machine().is_some() {
projection::state_header_height(project, n.element)
} else {
64.0
}
} else {
0.0
};
for (i, id) in ids.iter().enumerate() {
let b = block_positions[owner[i]];
let m = member_offsets[&i];
offsets.insert(
*id,
Position {
x: b.x + m.x + if parent.is_some() { PAD } else { 0.0 },
y: b.y + m.y + if parent.is_some() { header + PAD } else { 0.0 },
},
);
}
if let Some(id) = parent {
let size = sizes.get_mut(&id).unwrap();
size.width = size.width.max(total.width + 2.0 * PAD);
size.height = size.height.max(total.height + header + 2.0 * PAD);
if order_boundaries {
boundary_groups.push(boundary::Group {
parent: id,
blocks: comps
.iter()
.enumerate()
.map(|(c, members)| boundary::Block {
members: members.iter().map(|&i| ids[i]).collect(),
size: blocks[c],
position: block_positions[c],
})
.collect(),
bands,
undirected: undirected
.iter()
.map(|(a, b)| (owner[index[a]], owner[index[b]]))
.collect(),
});
}
}
let lifted: Vec<_> = arcs
.iter()
.enumerate()
.flat_map(|(a, targets)| targets.iter().map(move |&b| (ids[a], ids[b])))
.collect();
diagnostics.push(serde_json::json!({"visible_parent":parent,"components":component_diagnostics,"directed_lifted_edges":lifted,"undirected_lifted_pairs":undirected,"block_positions":block_positions,"bounds":total,"policy":"SCCs of sibling-subtree quotient, not global semantic SCCs. Undirected edges affect local gap and deterministic proximity only; no rank direction invented."}));
}
let boundary_report = if order_boundaries {
let report = boundary::reorder(
&mut boundary_groups,
&parents,
&mut offsets,
&sizes,
&view.edges,
&mut work,
)?;
for group in &boundary_groups {
let diagnostic = diagnostics
.iter_mut()
.find(|entry| entry["visible_parent"] == serde_json::json!(group.parent))
.unwrap();
diagnostic["block_positions"] =
serde_json::json!(group.blocks.iter().map(|b| b.position).collect::<Vec<_>>());
}
Some(report)
} else {
None
};
let mut plans = Vec::new();
for n in &view.nodes {
let mut position = offsets[&n.id];
let mut parent = n.visual_parent;
while let Some(id) = parent {
charge(&mut work, 1)?;
let p = offsets[&id];
position.x += p.x;
position.y += p.y;
parent = parents[&id];
}
position.x += 40.0;
position.y += 40.0;
let size = sizes[&n.id];
if !position.x.is_finite()
|| !position.y.is_finite()
|| position.x + size.width > SPAN
|| position.y + size.height > SPAN
{
return Err(error("extent bound exceeded"));
}
plans.push(PlacementNode {
id: n.id,
position,
size,
});
}
let result = import_placement(
project,
diagram,
PlacementPlan {
schema: 1,
nodes: plans,
},
)?;
let final_view = projection::project_view(&result, diagram);
charge(
&mut work,
final_view.edges.len() * (final_view.nodes.len() + 1) * 16,
)?;
if !routing::lead_incompatibilities(&result, &result.diagrams[&diagram], &final_view).is_empty()
{
return Err(error(
"final mandatory port lead incompatible; no repair attempted",
));
}
let mut report = serde_json::json!({"groups":diagnostics,"work_charged":work,"work_limit":LIMIT,"scope":"Projected-forest quotient heuristic; actual final reprojection and necessary lead guard checked. No full-route or readability acceptance."});
if let Some(boundary_report) = boundary_report {
report["boundary_order"] = boundary_report;
}
Ok((result, report))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn directed_cycles_remain_separate_across_one_way_bridge() {
let arcs = vec![
BTreeSet::from([1]),
BTreeSet::from([0, 2]),
BTreeSet::from([3]),
BTreeSet::from([2]),
];
assert_eq!(
components(&arcs, &mut 0).unwrap(),
vec![vec![0, 1], vec![2, 3]]
);
}
#[test]
fn perimeter_places_ten_unique_cells_without_overlap() {
let (positions, _, _) = perimeter(
10,
Size {
width: 224.0,
height: 132.0,
},
Size {
width: 32.0,
height: 32.0,
},
&mut 0,
)
.unwrap();
assert_eq!(positions.len(), 10);
for (i, a) in positions.iter().enumerate() {
for b in &positions[i + 1..] {
assert!((a.x - b.x).abs() >= 256.0 || (a.y - b.y).abs() >= 164.0);
}
}
}
#[test]
fn two_node_perimeter_scores_occupied_cells_instead_of_an_unused_row() {
let (positions, rows, cols) = perimeter(
2,
Size {
width: 224.0,
height: 160.0,
},
Size {
width: 250.0,
height: 56.0,
},
&mut 0,
)
.unwrap();
assert_eq!((rows, cols), (2, 1));
assert_eq!(
positions,
vec![Position { x: 0.0, y: 0.0 }, Position { x: 0.0, y: 216.0 }]
);
}
}
@@ -0,0 +1,686 @@
//! One deterministic boundary-order pass; dependency cycles use frozen scores.
use super::{charge, components, error, lift};
use oa_core::{Id, ModelError, Position, Size, projection::ProjectedEdge};
use std::collections::{BTreeMap, BTreeSet};
pub(super) struct Block {
pub members: Vec<Id>,
pub size: Size,
pub position: Position,
}
pub(super) struct Band {
pub components: Vec<usize>,
pub gap: f32,
}
pub(super) struct Group {
pub parent: Id,
pub blocks: Vec<Block>,
pub bands: Vec<Band>,
pub undirected: BTreeSet<(usize, usize)>,
}
#[derive(Clone)]
struct Unit {
blocks: Vec<usize>,
sources: BTreeSet<Id>,
hints: Vec<(Id, Id, Id)>,
}
fn center(
id: Id,
parents: &BTreeMap<Id, Option<Id>>,
offsets: &BTreeMap<Id, Position>,
sizes: &BTreeMap<Id, Size>,
work: &mut usize,
) -> Result<f64, ModelError> {
let mut at = Some(id);
let mut seen = BTreeSet::new();
let mut y = 0.0_f32;
while let Some(node) = at {
charge(work, 1)?;
if !seen.insert(node) {
return Err(error("boundary cyclic ancestry"));
}
let pos = offsets
.get(&node)
.ok_or_else(|| error("boundary missing offset"))?;
if !pos.x.is_finite() || !pos.y.is_finite() {
return Err(error("boundary nonfinite offset"));
}
if seen.len() == 1 {
y = pos.y;
} else {
y += pos.y;
}
if !y.is_finite() {
return Err(error("boundary composed position overflow"));
}
at = *parents
.get(&node)
.ok_or_else(|| error("boundary missing parent"))?;
}
let size = sizes
.get(&id)
.ok_or_else(|| error("boundary missing source size"))?;
y += 40.0;
let center = f64::from(y) + f64::from(size.height) / 2.0;
if !center.is_finite() {
return Err(error("boundary nonfinite center"));
}
Ok(center)
}
fn translate(value: f32, old_origin: f32, new_origin: f32) -> Result<f32, ModelError> {
// Bound the complete displacement, including origin subtraction. A rounded
// f32 delta can hide lost relative precision even when its addition is exact.
let intended = f64::from(value) + (f64::from(new_origin) - f64::from(old_origin));
let next = intended as f32;
if !next.is_finite() || (f64::from(next) - intended).abs() > 0.001 {
return Err(error("boundary member translation precision exceeded"));
}
Ok(next)
}
fn score(
unit: &Unit,
parents: &BTreeMap<Id, Option<Id>>,
offsets: &BTreeMap<Id, Position>,
sizes: &BTreeMap<Id, Size>,
work: &mut usize,
) -> Result<Option<f64>, ModelError> {
if unit.sources.is_empty() {
return Ok(None);
}
let mut total = 0.0;
for &source in &unit.sources {
total += center(source, parents, offsets, sizes, work)?;
}
let value = total / unit.sources.len() as f64;
if !value.is_finite() {
return Err(error("boundary nonfinite mean"));
}
Ok(Some(value))
}
fn ordered_units(scores: &[Option<f64>]) -> Vec<usize> {
let mut anchored: Vec<_> = (0..scores.len()).filter(|&i| scores[i].is_some()).collect();
anchored.sort_by(|&a, &b| {
scores[a]
.unwrap()
.total_cmp(&scores[b].unwrap())
.then(a.cmp(&b))
});
let mut next = anchored.into_iter();
(0..scores.len())
.map(|i| {
if scores[i].is_some() {
next.next().unwrap()
} else {
i
}
})
.collect()
}
fn packing(
blocks: &[Block],
before: &[usize],
after: &[usize],
gap: f32,
) -> Result<Vec<f32>, ModelError> {
const EPS: f64 = 0.001;
let origin = f64::from(blocks[before[0]].position.y);
let mut canonical = origin;
for &c in before {
if (f64::from(blocks[c].position.y) - canonical).abs() > EPS {
return Err(error("boundary non-prefix canonical band"));
}
canonical += f64::from(blocks[c].size.height) + f64::from(gap);
}
let mut next = origin;
let mut ys = Vec::new();
for &c in after {
let y = next as f32;
if !y.is_finite() || (f64::from(y) - next).abs() > EPS {
return Err(error("boundary prefix precision bound exceeded"));
}
ys.push(y);
next += f64::from(blocks[c].size.height) + f64::from(gap);
}
if (next - canonical).abs() > EPS {
return Err(error("boundary envelope changed"));
}
if before == after {
Ok(before.iter().map(|&c| blocks[c].position.y).collect())
} else {
Ok(ys)
}
}
pub(super) fn reorder(
groups: &mut [Group],
parents: &BTreeMap<Id, Option<Id>>,
offsets: &mut BTreeMap<Id, Position>,
sizes: &BTreeMap<Id, Size>,
edges: &[ProjectedEdge],
work: &mut usize,
) -> Result<serde_json::Value, ModelError> {
let mut group_order: Vec<_> = (0..groups.len()).collect();
group_order.sort_by_key(|&i| groups[i].parent);
let mut offset_owner = BTreeMap::new();
let mut parent_seen = BTreeSet::new();
let mut units: Vec<Vec<Vec<Unit>>> = vec![Vec::new(); groups.len()];
let mut active = BTreeSet::new();
for &g in &group_order {
let group = &groups[g];
if !parent_seen.insert(group.parent) || !parents.contains_key(&group.parent) {
return Err(error("boundary duplicate/missing group parent"));
}
let mut child_block = BTreeMap::new();
for (c, block) in group.blocks.iter().enumerate() {
if !block.size.width.is_finite()
|| !block.size.height.is_finite()
|| block.size.width <= 0.0
|| block.size.height <= 0.0
|| !block.position.x.is_finite()
|| !block.position.y.is_finite()
{
return Err(error("boundary invalid block geometry"));
}
for &id in &block.members {
if parents.get(&id) != Some(&Some(group.parent))
|| !offsets.contains_key(&id)
|| child_block.insert(id, c).is_some()
|| offset_owner.insert(id, g).is_some()
{
return Err(error("boundary invalid child membership"));
}
}
}
let mut covered = BTreeSet::new();
for band in &group.bands {
if !band.gap.is_finite() || band.gap < 0.0 || band.components.is_empty() {
return Err(error("boundary invalid band"));
}
let local: BTreeMap<_, _> = band
.components
.iter()
.enumerate()
.map(|(i, &c)| (c, i))
.collect();
for &c in &band.components {
if c >= group.blocks.len() || !covered.insert(c) {
return Err(error("boundary duplicate/unknown band block"));
}
}
let mut arcs = vec![BTreeSet::new(); band.components.len()];
for &(a, b) in &group.undirected {
charge(work, 1)?;
if let (Some(&a), Some(&b)) = (local.get(&a), local.get(&b)) {
arcs[a].insert(b);
arcs[b].insert(a);
}
}
let bundles = components(&arcs, work)?;
let mut band_units = Vec::new();
for bundle in bundles {
if bundle.windows(2).any(|v| v[1] != v[0] + 1) {
return Err(error("boundary undirected bundle not contiguous"));
}
let blocks: Vec<_> = bundle.iter().map(|&i| band.components[i]).collect();
let mut unit = Unit {
blocks,
sources: BTreeSet::new(),
hints: Vec::new(),
};
for edge in edges {
charge(work, 1)?;
if !edge.oriented {
continue;
}
let target = lift(edge.target, Some(group.parent), parents, work)?;
let Some(target) = target else {
continue;
};
if !unit.blocks.contains(
child_block
.get(&target)
.ok_or_else(|| error("boundary missing lifted target"))?,
) {
continue;
}
if lift(edge.source, Some(group.parent), parents, work)?.is_none() {
unit.sources.insert(edge.source);
unit.hints.push((edge.id, edge.source, edge.target));
}
}
unit.hints.sort();
band_units.push(unit);
}
if band_units.iter().filter(|u| !u.sources.is_empty()).count() >= 2 {
active.insert(g);
}
units[g].push(band_units);
}
if covered.len() != group.blocks.len() {
return Err(error("boundary incomplete band inventory"));
}
}
let active_order: Vec<_> = group_order
.into_iter()
.filter(|g| active.contains(g))
.collect();
let active_index: BTreeMap<_, _> = active_order
.iter()
.enumerate()
.map(|(i, &g)| (g, i))
.collect();
let mut dependencies = vec![BTreeSet::new(); active_order.len()];
let mut dependency_evidence = BTreeSet::new();
for (&g, &gi) in &active_index {
for unit in units[g].iter().flatten() {
for &source in &unit.sources {
let mut at = Some(source);
let mut seen = BTreeSet::new();
while let Some(node) = at {
charge(work, 1)?;
if !seen.insert(node) {
return Err(error("boundary dependency ancestry cycle"));
}
if let Some(&owner) = offset_owner.get(&node)
&& let Some(&oi) = active_index.get(&owner)
{
dependencies[oi].insert(gi);
dependency_evidence.insert((
groups[owner].parent,
groups[g].parent,
source,
node,
));
}
at = *parents
.get(&node)
.ok_or_else(|| error("boundary missing dependency ancestor"))?;
}
}
}
}
let sccs = components(&dependencies, work)?;
let mut scc_owner = vec![0; active_order.len()];
for (s, members) in sccs.iter().enumerate() {
for &i in members {
scc_owner[i] = s;
}
}
let mut dag = vec![BTreeSet::new(); sccs.len()];
for (a, targets) in dependencies.iter().enumerate() {
for &b in targets {
if scc_owner[a] != scc_owner[b] {
dag[scc_owner[a]].insert(scc_owner[b]);
}
}
}
let mut done = BTreeSet::new();
let mut records = Vec::new();
let mut processed = Vec::new();
while done.len() < sccs.len() {
charge(work, sccs.len() * sccs.len())?;
let s = (0..sccs.len())
.find(|s| {
!done.contains(s)
&& (0..sccs.len()).all(|p| !dag[p].contains(s) || done.contains(&p))
})
.ok_or_else(|| error("boundary condensation cycle"))?;
// Score the entire dependency SCC before modifying any offsets.
let mut snapshots = Vec::new();
for &i in &sccs[s] {
let g = active_order[i];
for (b, band_units) in units[g].iter().enumerate() {
let scores = band_units
.iter()
.map(|u| score(u, parents, offsets, sizes, work))
.collect::<Result<Vec<_>, _>>()?;
snapshots.push((g, b, scores));
}
}
for (g, b, scores) in snapshots {
let band_units = &units[g][b];
let order = ordered_units(&scores);
let before = groups[g].bands[b].components.clone();
let gap = groups[g].bands[b].gap;
let after: Vec<_> = order
.iter()
.flat_map(|&u| band_units[u].blocks.iter().copied())
.collect();
let ys = packing(&groups[g].blocks, &before, &after, gap)?;
let mut changed = Vec::new();
for (&c, y) in after.iter().zip(ys) {
charge(work, groups[g].blocks[c].members.len() + 1)?;
let old = groups[g].blocks[c].position.y;
if !y.is_finite() {
return Err(error("boundary packing overflow"));
}
if y != old {
changed.push(c);
}
for id in &groups[g].blocks[c].members {
let p = offsets
.get_mut(id)
.ok_or_else(|| error("boundary lost member offset"))?;
p.y = translate(p.y, old, y)?;
}
groups[g].blocks[c].position.y = y;
}
groups[g].bands[b].components = after.clone();
let changed_units: Vec<_> = band_units
.iter()
.enumerate()
.filter(|(_, u)| u.blocks.iter().any(|c| changed.contains(c)))
.map(|(i, _)| i)
.collect();
records.push(serde_json::json!({"parent":groups[g].parent,"band":b,"before_blocks":before,"after_blocks":after,"unit_order":order,"scores":scores,"changed_blocks":changed,"changed_units":changed_units,"envelope_epsilon":0.001,"units":band_units.iter().map(|u|serde_json::json!({"blocks":u.blocks,"source_owners":u.sources,"edge_hints":u.hints})).collect::<Vec<_>>()}));
}
processed.push(serde_json::json!({"parents":sccs[s].iter().map(|&i|groups[active_order[i]].parent).collect::<Vec<_>>(),"cyclic":sccs[s].len()>1||sccs[s].iter().any(|&i|dependencies[i].contains(&i)),"policy":"all scores snapshotted before one simultaneous group-permutation pass"}));
done.insert(s);
}
Ok(
serde_json::json!({"active_parents":active_order.iter().map(|&g|groups[g].parent).collect::<Vec<_>>(),"dependencies":dependency_evidence,"dependency_components":processed,"bands":records,"limitation":"One pass; cyclic dependencies use a common snapshot, not a fixed-point solution. Root unchanged; no quality or repeat-stability acceptance."}),
)
}
#[cfg(test)]
mod tests {
use super::*;
fn id(n: u128) -> Id {
Id::from_u128(n)
}
fn block(n: u128, y: f32, height: f32) -> Block {
Block {
members: vec![id(n)],
size: Size {
width: 10.0,
height,
},
position: Position { x: 0.0, y },
}
}
fn edge(n: u128, source: u128, target: u128) -> ProjectedEdge {
ProjectedEdge {
id: id(n),
source: id(source),
target: id(target),
trace: false,
oriented: true,
source_port: None,
target_port: None,
}
}
#[test]
fn anchored_sort_preserves_unanchored_ordinal_slot() {
assert_eq!(
ordered_units(&[Some(90.0), None, Some(10.0), Some(10.0)]),
vec![2, 1, 3, 0]
);
}
#[test]
fn heterogeneous_blocks_use_new_prefix_not_old_slots() {
let blocks = vec![
Block {
members: vec![],
size: Size {
width: 10.0,
height: 100.0,
},
position: Position { x: 0.0, y: 0.0 },
},
Block {
members: vec![],
size: Size {
width: 10.0,
height: 20.0,
},
position: Position { x: 0.0, y: 132.0 },
},
];
assert_eq!(
packing(&blocks, &[0, 1], &[1, 0], 32.0).unwrap(),
vec![0.0, 52.0]
);
}
#[test]
fn center_includes_grandparent_offset_change() {
let (a, b, c) = (Id::from_u128(1), Id::from_u128(2), Id::from_u128(3));
let parents = BTreeMap::from([(a, None), (b, Some(a)), (c, Some(b))]);
let mut offsets = BTreeMap::from([
(a, Position { x: 0.0, y: 100.0 }),
(b, Position { x: 0.0, y: 20.0 }),
(c, Position { x: 0.0, y: 5.0 }),
]);
let sizes = BTreeMap::from([(
c,
Size {
width: 10.0,
height: 10.0,
},
)]);
assert_eq!(
center(c, &parents, &offsets, &sizes, &mut 0).unwrap(),
170.0
);
offsets.get_mut(&a).unwrap().y += 300.0;
assert_eq!(
center(c, &parents, &offsets, &sizes, &mut 0).unwrap(),
470.0
);
}
#[test]
fn ancestor_dependency_updates_downstream_scores_before_its_permutation() {
// Downstream parent1 sorts before upstream20, so an absent ancestor
// dependency would leave downstream order unchanged and fail this test.
let mut groups = vec![
Group {
parent: id(1),
blocks: vec![block(2, 0.0, 100.0), block(3, 132.0, 100.0)],
bands: vec![Band {
components: vec![0, 1],
gap: 32.0,
}],
undirected: BTreeSet::new(),
},
Group {
parent: id(20),
blocks: vec![block(21, 0.0, 100.0), block(22, 132.0, 100.0)],
bands: vec![Band {
components: vec![0, 1],
gap: 32.0,
}],
undirected: BTreeSet::new(),
},
];
let parents = BTreeMap::from([
(id(1), None),
(id(2), Some(id(1))),
(id(3), Some(id(1))),
(id(20), None),
(id(21), Some(id(20))),
(id(22), Some(id(20))),
(id(23), Some(id(21))),
(id(30), None),
(id(31), None),
(id(32), None),
]);
let mut offsets: BTreeMap<_, _> = [
(1, 0.0),
(2, 0.0),
(3, 132.0),
(20, 0.0),
(21, 0.0),
(22, 132.0),
(23, 10.0),
(30, 300.0),
(31, 0.0),
(32, 50.0),
]
.into_iter()
.map(|(n, y)| (id(n), Position { x: 0.0, y }))
.collect();
let sizes = parents
.keys()
.map(|&n| {
(
n,
Size {
width: 10.0,
height: 10.0,
},
)
})
.collect();
let edges = vec![
edge(101, 30, 21),
edge(102, 31, 22),
edge(103, 23, 2),
edge(104, 32, 3),
];
let report = reorder(&mut groups, &parents, &mut offsets, &sizes, &edges, &mut 0).unwrap();
assert_eq!(groups[1].bands[0].components, vec![1, 0]);
assert_eq!(groups[0].bands[0].components, vec![1, 0]);
assert_eq!(offsets[&id(21)].y, 132.0);
assert_eq!(offsets[&id(23)].y, 10.0); // descendant is not directly moved
assert_eq!(
center(id(23), &parents, &offsets, &sizes, &mut 0).unwrap(),
187.0
);
assert_eq!(
report["dependency_components"][0]["parents"][0],
serde_json::json!(id(20))
);
}
#[test]
fn undirected_bundle_stays_whole_around_unanchored_unit() {
let mut groups = vec![Group {
parent: id(100),
blocks: vec![
block(101, 0.0, 20.0),
block(102, 30.0, 30.0),
block(103, 70.0, 40.0),
block(104, 120.0, 10.0),
],
bands: vec![Band {
components: vec![0, 1, 2, 3],
gap: 10.0,
}],
undirected: BTreeSet::from([(0, 1)]),
}];
let parents = BTreeMap::from([
(id(100), None),
(id(101), Some(id(100))),
(id(102), Some(id(100))),
(id(103), Some(id(100))),
(id(104), Some(id(100))),
(id(110), None),
(id(111), None),
]);
let mut offsets: BTreeMap<_, _> = [
(100, 0.0),
(101, 0.0),
(102, 30.0),
(103, 70.0),
(104, 120.0),
(110, 300.0),
(111, 0.0),
]
.into_iter()
.map(|(n, y)| (id(n), Position { x: 0.0, y }))
.collect();
let sizes = parents
.keys()
.map(|&n| {
(
n,
Size {
width: 10.0,
height: 10.0,
},
)
})
.collect();
let report = reorder(
&mut groups,
&parents,
&mut offsets,
&sizes,
&[
edge(201, 110, 101),
edge(202, 110, 102),
edge(203, 111, 104),
],
&mut 0,
)
.unwrap();
assert_eq!(groups[0].bands[0].components, vec![3, 2, 0, 1]);
assert_eq!(
[
offsets[&id(104)].y,
offsets[&id(103)].y,
offsets[&id(101)].y,
offsets[&id(102)].y
],
[0.0, 20.0, 70.0, 100.0]
);
assert_eq!(
report["bands"][0]["units"][0]["source_owners"]
.as_array()
.unwrap()
.len(),
1
);
}
#[test]
fn center_uses_final_plan_f32_composition_and_translation_has_error_bound() {
let parents = BTreeMap::from([(id(1), None), (id(2), Some(id(1))), (id(3), Some(id(2)))]);
let offsets = BTreeMap::from([
(
id(1),
Position {
x: 0.0,
y: -100000.0,
},
),
(
id(2),
Position {
x: 0.0,
y: 100000.0,
},
),
(id(3), Position { x: 0.0, y: 0.1 }),
]);
let sizes = BTreeMap::from([(
id(3),
Size {
width: 10.0,
height: 10.0,
},
)]);
assert_eq!(
center(id(3), &parents, &offsets, &sizes, &mut 0).unwrap(),
45.1015625
);
assert_eq!(translate(10.125, 0.0, 0.375).unwrap(), 10.5);
assert!(translate(32768.0, 0.0, 0.002).is_err());
}
#[test]
fn member_offset_survives_large_origin_subtraction() {
let blocks = vec![
block(1, 0.0, 65404.0),
block(2, 65436.0, 68.0),
block(3, 65536.0, 100.0),
block(4, 65668.0, 68.002),
];
let ys = packing(&blocks, &[0, 1, 2, 3], &[3, 2, 1, 0], 32.0).unwrap();
let member = translate(65568.0, 65536.0, ys[1]).unwrap();
assert!((f64::from(member) - f64::from(ys[1]) - 32.0).abs() <= 0.001);
}
}
@@ -0,0 +1,192 @@
//! Frozen-corpus route-only timing. Protocol: harness/experiments/routing-independent-20260925/timing-protocol.md.
use oa_core::{Id, Project, projection, routing, validate_candidate};
use serde::Deserialize;
use serde_json::json;
use std::hint::black_box;
use std::path::{Component, Path, PathBuf};
use std::time::{Duration, Instant};
const ROUNDS: usize = 7;
const SLOW_CALL: Duration = Duration::from_secs(5);
#[derive(Deserialize)]
struct Manifest {
schema: u32,
cases: Vec<Case>,
#[serde(flatten)]
metadata: std::collections::BTreeMap<String, serde_json::Value>,
}
#[derive(Deserialize)]
struct Case {
name: String,
project_file: PathBuf,
diagram: Id,
description: String,
#[serde(flatten)]
metadata: std::collections::BTreeMap<String, serde_json::Value>,
}
fn timed_route(
project: &Project,
diagram: &oa_core::Diagram,
view: &projection::ProjectedView,
) -> (routing::RoutedView, Duration) {
// Input black_box is outside the clock. Result consumption is inside it;
// allocation is part of routing, result destruction is outside the clock.
let project = black_box(project);
let diagram = black_box(diagram);
let view = black_box(view);
let started = Instant::now();
let result = black_box(routing::route_diagram(project, diagram, view));
let elapsed = started.elapsed();
(result, elapsed)
}
fn point_digest(route: &routing::RoutedView) -> String {
// Stable FNV-1a64 over ID bytes, point count and IEEE754 coordinate bits,
// little endian. Diagnostic only, not a cryptographic integrity guarantee.
let mut hash = 0xcbf29ce484222325_u64;
let mut feed = |bytes: &[u8]| {
for byte in bytes {
hash ^= u64::from(*byte);
hash = hash.wrapping_mul(0x100000001b3);
}
};
for (id, edge) in &route.edges {
feed(id.as_bytes());
feed(&(edge.points.len() as u64).to_le_bytes());
for point in &edge.points {
feed(&point.x.to_bits().to_le_bytes());
feed(&point.y.to_bits().to_le_bytes());
}
}
format!("{hash:016x}")
}
fn relative_project(root: &Path, file: &Path) -> Result<PathBuf, Box<dyn std::error::Error>> {
if file.as_os_str().is_empty()
|| !file
.components()
.all(|part| matches!(part, Component::Normal(_)))
{
return Err(
"project_file must be a nonempty relative path without parent traversal".into(),
);
}
let path = root.join(file).canonicalize()?;
if !path.starts_with(root) {
return Err("project_file resolves outside the manifest directory".into());
}
Ok(path)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = std::env::args_os().skip(1);
let manifest_path = PathBuf::from(
args.next()
.ok_or("usage: routing_cost_probe MANIFEST.json")?,
)
.canonicalize()?;
if args.next().is_some() {
return Err(
"protocol is fixed: one warmup and seven measured calls; no extra arguments".into(),
);
}
let manifest: Manifest = serde_json::from_slice(&std::fs::read(&manifest_path)?)?;
if manifest.schema != 1 || manifest.cases.is_empty() {
return Err("expected schema1 with at least one case".into());
}
let root = manifest_path
.parent()
.ok_or("manifest has no parent directory")?;
println!(
"{}",
json!({
"protocol": "routing_cost_probe_v1", "manifest_schema": manifest.schema,
"warmup_calls": 1, "measured_calls": ROUNDS,
"slow_call_limit_ns": SLOW_CALL.as_nanos(),
"debug_assertions": cfg!(debug_assertions),
"os": std::env::consts::OS, "arch": std::env::consts::ARCH,
"case_count": manifest.cases.len(),
"corpus_metadata": manifest.metadata,
"clock_scope": "route_diagram plus result black_box; excludes projection, JSON, equality, digest, output and result destruction",
"digest": "FNV-1a64 IDs/counts/f32 point bits; diagnostic, not cryptographic",
"acceptance": "none; external receipts must bind source, optimized build, binary and corpus"
})
);
let mut names = std::collections::BTreeSet::new();
for case in manifest.cases {
if !names.insert(case.name.clone()) {
return Err("duplicate case name".into());
}
let bytes = std::fs::read(relative_project(root, &case.project_file)?)?;
let project: Project = serde_json::from_slice(&bytes)?;
validate_candidate(&project)?;
let original = project.clone();
let diagram = project
.diagrams
.get(&case.diagram)
.ok_or("case diagram is absent")?;
let view = projection::project_diagram(&project, diagram);
let (first, warmup) = timed_route(&project, diagram, &view);
let mut samples = Vec::with_capacity(ROUNDS);
let mut equality = Vec::with_capacity(ROUNDS);
let mut endpoints = Vec::with_capacity(ROUNDS);
let mut censored = warmup > SLOW_CALL;
if !censored {
for _ in 0..ROUNDS {
let (route, elapsed) = timed_route(&project, diagram, &view);
samples.push(elapsed.as_nanos());
equality.push(route == first);
endpoints.push(
route.edges.len() == first.edges.len()
&& route.edges.iter().all(|(id, edge)| {
first.edges.get(id).is_some_and(|other| {
edge.points.first() == other.points.first()
&& edge.points.last() == other.points.last()
})
}),
);
if elapsed > SLOW_CALL {
censored = true;
break;
}
}
}
let mut ordered = samples.clone();
ordered.sort_unstable();
let complete = !censored && samples.len() == ROUNDS;
let median = complete.then(|| ordered[ROUNDS / 2]);
let warnings: usize = first.edges.values().map(|edge| edge.warnings.len()).sum();
let project_unchanged = project == original;
let stable = equality.iter().all(|same| *same);
println!(
"{}",
json!({
"case": case.name, "description": case.description,
"corpus_case_metadata": case.metadata,
"project_file": case.project_file, "diagram": case.diagram,
"project_bytes": bytes.len(), "nodes": view.nodes.len(),
"edges": view.edges.len(), "ports": view.ports.len(),
"routed_edges": first.edges.len(), "warnings": warnings,
"route_points": first.edges.values().map(|edge| edge.points.len()).sum::<usize>(),
"route_point_digest": point_digest(&first),
"warmup_ns": warmup.as_nanos(), "samples_ns": samples,
"median_ns": median, "max_observed_measured_ns": ordered.last(),
"complete": complete, "censored": censored,
"censor_reason": if censored { Some("single call exceeded five seconds; remaining repeats skipped") } else { None },
"repeat_full_routed_view_equal_warmup": equality,
"repeat_endpoints_equal_warmup": endpoints,
"stability_observed": !samples.is_empty(),
"project_unchanged": project_unchanged
})
);
if !stable || !project_unchanged {
return Err(
"routing stability or Project preservation failed; receipt above retained".into(),
);
}
}
Ok(())
}
@@ -0,0 +1,555 @@
//! Source-first inputs for independent routing experiments. Never invokes layout/routing.
use oa_core::*;
use serde_json::{Value, json};
use std::{collections::BTreeMap, error::Error, fs, path::PathBuf};
struct Case {
name: &'static str,
description: &'static str,
project: Project,
diagram: Id,
trace_edges: Vec<Id>,
metadata: Value,
}
struct Builder {
project: Project,
diagram: Id,
base: u128,
next: u128,
edges: Vec<Id>,
}
impl Builder {
fn new(name: &str, base: u128) -> Self {
let mut project = Project::empty();
project.id = Id::from_u128(base);
project.alias = name.into();
project.name = name.into();
let old = project.ensure_diagram(Layer::Sa);
let diagram = Id::from_u128(base + 1);
reidentify(&mut project, old, diagram).unwrap();
let d = project.diagrams.get_mut(&diagram).unwrap();
d.alias = format!("{name}_main");
d.name = format!("{name} main view");
d.projection = ProjectionKind::FunctionalDataflow;
Self {
project,
diagram,
base,
next: base + 100,
edges: Vec::new(),
}
}
fn stable(&mut self, old: Id) -> Id {
let id = Id::from_u128(self.next);
self.next += 1;
reidentify(&mut self.project, old, id).unwrap();
id
}
fn function(&mut self, name: &str, x: f32, y: f32) -> Id {
let old = self
.project
.add_element(Kind::Function, Layer::Sa, name, None)
.unwrap();
let id = self.stable(old);
let old = self.project.place(self.diagram, id, Position { x, y });
self.stable(old);
id
}
fn exchange(
&mut self,
name: &str,
source: Id,
target: Id,
source_port: PortChoice,
target_port: PortChoice,
) -> Id {
let id = Id::from_u128(self.base + 10_000 + self.edges.len() as u128);
let request = FunctionalExchangeRequest {
id,
alias: format!("flow_{:02}", self.edges.len()),
name: name.into(),
description: String::new(),
source,
target,
source_port,
target_port,
items: vec![],
};
let commands = ports::plan_functional_exchange(&self.project, &request).unwrap();
self.project = execute_batch(&self.project, &commands).unwrap();
self.edges.push(id);
id
}
fn port_pair(&self, edge: Id) -> (Id, Id) {
let RelationBody::FunctionalExchange {
source_port,
target_port,
..
} = self.project.relations[&edge].body
else {
unreachable!()
};
(source_port, target_port)
}
fn anchor(&mut self, owner: Id, port: Id, side: PortAnchorSide, offset: f32) {
let node = self.project.diagrams[&self.diagram]
.nodes
.values()
.find(|n| n.element == owner)
.unwrap()
.id;
self.project = prepare_command(
&self.project,
&Command::SetPortAnchor {
diagram: self.diagram,
node,
anchor: PortAnchor { port, side, offset },
},
)
.unwrap()
.project;
}
}
fn sentinel(edge: Id, x: f32, y: f32) -> EdgeRoute {
EdgeRoute {
edge,
source_attachment: None,
target_attachment: None,
waypoints: vec![Position { x, y }],
label: Some(EdgeLabel {
fraction: 0.4,
offset: Position { x: -30., y: -70. },
}),
}
}
fn workshop() -> Vec<Case> {
let original =
persistence::decode(include_bytes!("../../../examples/routing-workshop.json")).unwrap();
let diagram = original
.diagrams
.values()
.find(|d| d.alias == "sa_system_boundary_and_functions")
.unwrap()
.id;
assert_eq!(
original.diagrams[&diagram].projection,
ProjectionKind::Allocation
);
assert_eq!(original.diagrams[&diagram].nodes.len(), 12);
let container = original
.elements
.values()
.find(|e| e.alias == "rescue_coordination_system")
.unwrap()
.id;
let placement = original.diagrams[&diagram]
.nodes
.values()
.find(|n| n.element == container)
.unwrap()
.id;
let traces: Vec<_> = [
"sa_report_to_relay",
"sa_direct_advice",
"sa_incident_decision",
]
.iter()
.map(|alias| {
original
.relations
.values()
.find(|r| r.alias == *alias)
.unwrap()
.id
})
.collect();
let mut folded = original.clone();
assert!(!folded.diagrams[&diagram].nodes[&placement].collapsed);
folded
.diagrams
.get_mut(&diagram)
.unwrap()
.nodes
.get_mut(&placement)
.unwrap()
.collapsed = true;
let mut restored = folded.clone();
restored
.diagrams
.get_mut(&diagram)
.unwrap()
.nodes
.get_mut(&placement)
.unwrap()
.collapsed = false;
assert_eq!(restored, original);
vec![
Case {
name: "workshop_sa_original",
description: "Saved coastal rescue Allocation view, all source records retained.",
project: original,
diagram,
trace_edges: traces.clone(),
metadata: json!({"source":"examples/routing-workshop.json","view_alias":"sa_system_boundary_and_functions"}),
},
Case {
name: "workshop_sa_folded",
description: "Same saved Project with only rescue_coordination_system placement folded.",
project: folded,
diagram,
trace_edges: traces,
metadata: json!({"source":"examples/routing-workshop.json","folded_placement":placement,
"folded_element":container,"unfold_restores_original_exact":true}),
},
]
}
fn mixed() -> Vec<Case> {
let mut b = Builder::new("mixed_dispatch", 100_000);
let nodes: Vec<_> = [
("Sensor A", 40., 90.),
("Sensor B", 40., 510.),
("Ingest", 380., 250.),
("Validate", 720., 80.),
("Archive", 720., 510.),
("Correlate", 1060., 270.),
("Plan", 1400., 80.),
("Dispatch", 1740., 270.),
("Actuator", 1400., 680.),
("Operator", 1740., 680.),
]
.into_iter()
.map(|(name, x, y)| b.function(name, x, y))
.collect();
let e0 = b.exchange(
"Sensor A observations",
nodes[0],
nodes[2],
PortChoice::Create,
PortChoice::Create,
);
let ingest_input = b.port_pair(e0).1;
let e1 = b.exchange(
"Sensor B observations",
nodes[1],
nodes[2],
PortChoice::Create,
PortChoice::Reuse(ingest_input),
);
let e2 = b.exchange(
"Validate incoming observations",
nodes[2],
nodes[3],
PortChoice::Create,
PortChoice::Create,
);
let ingest_output = b.port_pair(e2).0;
let e3 = b.exchange(
"Archive incoming observations",
nodes[2],
nodes[4],
PortChoice::Reuse(ingest_output),
PortChoice::Create,
);
b.exchange(
"Validated observations",
nodes[3],
nodes[5],
PortChoice::Create,
PortChoice::Create,
);
b.exchange(
"Archived context",
nodes[4],
nodes[5],
PortChoice::Create,
PortChoice::Create,
);
b.exchange(
"Correlated situation",
nodes[5],
nodes[6],
PortChoice::Create,
PortChoice::Create,
);
b.exchange(
"Planned actions",
nodes[6],
nodes[7],
PortChoice::Create,
PortChoice::Create,
);
let e8 = b.exchange(
"Actuator dispatch",
nodes[7],
nodes[8],
PortChoice::Create,
PortChoice::Create,
);
let dispatch_output = b.port_pair(e8).0;
let e9 = b.exchange(
"Operator dispatch copy",
nodes[7],
nodes[9],
PortChoice::Reuse(dispatch_output),
PortChoice::Create,
);
b.exchange(
"Operator acknowledgement",
nodes[9],
nodes[8],
PortChoice::Create,
PortChoice::Create,
);
b.exchange(
"Archived actuator policy",
nodes[4],
nodes[8],
PortChoice::Create,
PortChoice::Create,
);
b.exchange(
"Sensor B archive stream",
nodes[1],
nodes[4],
PortChoice::Create,
PortChoice::Create,
);
let feedback = b.exchange(
"Sensor A sampling feedback",
nodes[6],
nodes[0],
PortChoice::Create,
PortChoice::Create,
);
let (feedback_output, feedback_input) = b.port_pair(feedback);
b.anchor(nodes[0], b.port_pair(e0).0, PortAnchorSide::Right, 0.25);
b.anchor(nodes[2], ingest_input, PortAnchorSide::Left, 0.3);
b.anchor(nodes[2], ingest_output, PortAnchorSide::Bottom, 0.6);
b.anchor(nodes[6], feedback_output, PortAnchorSide::Top, 0.5);
b.anchor(nodes[0], feedback_input, PortAnchorSide::Left, 0.6);
b.anchor(nodes[7], dispatch_output, PortAnchorSide::Right, 0.5);
b.project
.diagrams
.get_mut(&b.diagram)
.unwrap()
.routes
.push(sentinel(feedback, 300., -100.));
let secondary = Id::from_u128(b.base + 2);
let mut other = b.project.diagrams[&b.diagram].clone();
other.id = secondary;
other.alias = "mixed_dispatch_secondary".into();
other.name = "Feedback review sentinel".into();
other.description = "Unaffected other-view preservation sentinel".into();
other.nodes.clear();
other.routes = vec![sentinel(feedback, 460., 480.)];
b.project.diagrams.insert(secondary, other);
for (i, element) in [nodes[0], nodes[2], nodes[6]].into_iter().enumerate() {
let old = b.project.place(
secondary,
element,
Position {
x: 100. + i as f32 * 340.,
y: 100.,
},
);
let stable = b.stable(old);
b.project
.diagrams
.get_mut(&secondary)
.unwrap()
.nodes
.get_mut(&stable)
.unwrap()
.alias = format!("feedback_review_{i}");
}
assert_eq!(b.edges.len(), 14);
assert_eq!(b.project.diagrams[&b.diagram].nodes.len(), 10);
let originals = b.edges.clone();
let replacements: Vec<_> = originals.iter().rev().copied().collect();
let mut permuted = b.project.clone();
for (i, id) in originals.iter().enumerate() {
reidentify(&mut permuted, *id, Id::from_u128(1_000_000 + i as u128)).unwrap();
}
for (i, id) in replacements.iter().enumerate() {
reidentify(&mut permuted, Id::from_u128(1_000_000 + i as u128), *id).unwrap();
}
let mut restored = permuted.clone();
for (i, id) in replacements.iter().enumerate() {
reidentify(&mut restored, *id, Id::from_u128(1_000_000 + i as u128)).unwrap();
}
for (i, id) in originals.iter().enumerate() {
reidentify(&mut restored, Id::from_u128(1_000_000 + i as u128), *id).unwrap();
}
assert_eq!(restored, b.project);
let correspondence: BTreeMap<_, _> = originals.iter().copied().zip(replacements).collect();
let traces = vec![e1, e3, e9, feedback];
let permuted_traces = traces.iter().map(|id| correspondence[id]).collect();
let metadata = json!({"shared_input":ingest_input,"shared_outputs":[ingest_output,dispatch_output],
"sentinel_edge":feedback,"secondary_diagram":secondary,"fixed_anchor_records":6,
"authored_waypoint_count_main":1,"authored_label_count_main":1,
"declared_feedback_cycle":[nodes[0],nodes[2],nodes[3],nodes[5],nodes[6],nodes[0]]});
vec![
Case {
name: "mixed_dispatch",
description: "Ten-function sensing/decision/dispatch network, explicit port sharing and fixed anchors.",
project: b.project,
diagram: b.diagram,
trace_edges: traces,
metadata,
},
Case {
name: "mixed_dispatch_edge_ids_reversed",
description: "Same mixed Project with fixed reversed relation-ID permutation, remapped references.",
project: permuted,
diagram: b.diagram,
trace_edges: permuted_traces,
metadata: json!({"paired_case":"mixed_dispatch","edge_id_correspondence":correspondence,
"inverse_recovers_original_exact":true,"secondary_diagram":secondary}),
},
]
}
fn sparse() -> Case {
let mut b = Builder::new("subsystems_40_sparse", 200_000);
let names = [
"Sensing",
"Communications",
"Assessment",
"Planning",
"Delivery",
];
let stages = [
"Acquire",
"Decode",
"Validate",
"Enrich",
"Aggregate",
"Decide",
"Package",
"Publish",
];
let mut nodes = Vec::new();
for (group, name) in names.iter().enumerate() {
let row: Vec<_> = stages
.iter()
.enumerate()
.map(|(stage, label)| {
b.function(
&format!("{name} {label}"),
80. + stage as f32 * 300.,
80. + group as f32 * 240.,
)
})
.collect();
nodes.push(row);
}
for group in 0..5 {
for stage in 0..7 {
b.exchange(
&format!(
"{} {} to {}",
names[group],
stages[stage],
stages[stage + 1]
),
nodes[group][stage],
nodes[group][stage + 1],
PortChoice::Create,
PortChoice::Create,
);
}
}
let mut trace_edges = Vec::new();
for group in 0..5 {
for stage in [1, 3, 5, 7] {
let next = (group + 1) % 5;
let id = b.exchange(
&format!(
"{} {} handoff to {} {}",
names[group],
stages[stage],
names[next],
stages[stage - 1]
),
nodes[group][stage],
nodes[next][stage - 1],
PortChoice::Create,
PortChoice::Create,
);
if (group == 0 && stage == 1) || (group == 4 && stage == 7) {
trace_edges.push(id);
}
}
}
assert_eq!(b.edges.len(), 55);
assert_eq!(b.project.diagrams[&b.diagram].nodes.len(), 40);
Case {
name: "subsystems_40_sparse",
description: "Five eight-stage subsystem chains with twenty directed cross-subsystem handoffs; all ports distinct.",
project: b.project,
diagram: b.diagram,
trace_edges,
metadata: json!({"groups":names,"stages":stages,"chain_edges":35,"cross_edges":20,
"all_exchange_ports_distinct":true,"grid_columns":8,"grid_rows":5}),
}
}
fn main() -> Result<(), Box<dyn Error>> {
let mut args = std::env::args_os().skip(1);
let output = PathBuf::from(
args.next()
.ok_or("Usage: routing_eval_corpus NEW_DIRECTORY")?,
);
if args.next().is_some() {
return Err("Expected exactly one new output directory".into());
}
if output.exists() {
return Err("Output directory already exists; refusing overwrite".into());
}
let mut cases = workshop();
cases.extend(mixed());
cases.push(sparse());
let mut files = Vec::new();
let mut entries = Vec::new();
for case in cases {
validate_candidate(&case.project)?;
let file = format!("{}.json", case.name);
let traces: Vec<_> = case
.trace_edges
.iter()
.map(|id| {
let relation = &case.project.relations[id];
json!({"edge":id,"alias":relation.alias,"name":relation.name,
"source":relation.source(),"target":relation.target()})
})
.collect();
entries.push(json!({"name":case.name,"project_file":file,"diagram":case.diagram,
"description":case.description,"metadata":case.metadata,"trace_tasks":traces,
"source_counts":{"elements":case.project.elements.len(),"relations":case.project.relations.len(),
"views":case.project.diagrams.len(),"selected_view_placements":case.project.diagrams[&case.diagram].nodes.len(),
"selected_view_authored_routes":case.project.diagrams[&case.diagram].routes.len()}}));
files.push((file, serde_json::to_vec_pretty(&case.project)?));
}
let manifest = json!({"schema":1,"cases":entries,"definition_baseline":"f72aa2ca",
"construction":"Source-authored positions/topology, no Layout/projection/routing calls; validate all before writing.",
"invariants":"Routing is read-only. Preserve all semantic records, port identities, fixed anchors, authored routes/labels, fold flags, and other views. ID permutation correspondence is explicit. No quality or automatic endpoint-side expectation.",
"generation_in_routing_timing":false});
let manifest_bytes = serde_json::to_vec_pretty(&manifest)?;
fs::create_dir(&output)?;
for (name, bytes) in files {
fs::write(output.join(name), bytes)?;
}
fs::write(output.join("manifest.json"), manifest_bytes)?;
println!("{}", output.join("manifest.json").display());
Ok(())
}
+85 -206
View File
@@ -6,7 +6,9 @@ use crate::{
RelationBody, RelationKind, Size,
};
mod attachments;
mod leads;
pub use attachments::{attachment_from_point, attachment_point, semantic_port_endpoint};
pub use leads::{LeadBlocker, LeadEndpoint, LeadIncompatibility, lead_incompatibilities};
use std::cmp::Ordering;
use std::collections::{BTreeMap, BTreeSet, BinaryHeap};
use std::fmt;
@@ -420,6 +422,73 @@ fn endpoints(
.collect()
}
fn effective_route<'a>(
project: &Project,
diagram: &Diagram,
edge: &ProjectedEdge,
stored: Option<&'a crate::EdgeRoute>,
) -> (
bool,
Option<&'a crate::EdgeRoute>,
[Option<EdgeAttachment>; 2],
) {
let promoted = projection::edge_endpoint_placements(project, diagram, edge.id)
.is_some_and(|(source, target)| source != edge.source || target != edge.target);
let route = if promoted { None } else { stored };
let attachments = [EdgeEnd::Source, EdgeEnd::Target].map(|end| {
semantic_port_endpoint(project, edge.id, end)
.is_none()
.then(|| route.and_then(|r| r.attachment(end)))
.flatten()
});
(promoted, route, attachments)
}
#[allow(clippy::too_many_arguments)]
fn edge_endpoints(
project: &Project,
diagram: &Diagram,
edge: &ProjectedEdge,
source: &ProjectedNode,
target: &ProjectedNode,
view: &ProjectedView,
attachments: [Option<EdgeAttachment>; 2],
) -> [Vec<Endpoint>; 2] {
[
endpoints(
project,
diagram,
source,
semantic_port_endpoint(project, edge.id, EdgeEnd::Source).or(edge.source_port),
view,
attachments[0],
),
endpoints(
project,
diagram,
target,
semantic_port_endpoint(project, edge.id, EdgeEnd::Target).or(edge.target_port),
view,
attachments[1],
),
]
}
fn allowed_endpoint_pair(edge: &ProjectedEdge, a: Endpoint, b: Endpoint, coincident: bool) -> bool {
!(edge.source == edge.target
&& edge.source_port.is_none()
&& edge.target_port.is_none()
&& a.point == b.point
&& a.stub == b.stub
&& !coincident)
}
fn lead_pair_clear(edge: &ProjectedEdge, a: Endpoint, b: Endpoint, obstacles: &[Rect]) -> bool {
!obstacles
.iter()
.any(|r| r.id != edge.source && r.crosses(a.point, a.stub))
&& !obstacles
.iter()
.any(|r| r.id != edge.target && r.crosses(b.point, b.stub))
}
fn ancestors(id: Id, nodes: &BTreeMap<Id, &ProjectedNode>, out: &mut BTreeSet<Id>) {
let mut current = nodes.get(&id).and_then(|n| n.visual_parent);
let mut seen = BTreeSet::new();
@@ -512,16 +581,8 @@ fn route_diagram_impl(
continue;
};
let stored = authored.get(&edge.id).copied();
let promoted = projection::edge_endpoint_placements(project, diagram, edge.id)
.is_some_and(|(source, target)| source != edge.source || target != edge.target);
let custom_suspended = promoted;
let route = if promoted { None } else { stored };
let attachments = [EdgeEnd::Source, EdgeEnd::Target].map(|end| {
semantic_port_endpoint(project, edge.id, end)
.is_none()
.then(|| route.and_then(|r| r.attachment(end)))
.flatten()
});
let (custom_suspended, route, attachments) =
effective_route(project, diagram, edge, stored);
let pins = route.map_or_else(Vec::new, |r| r.waypoints.clone());
let obstacles = edge_obstacles(edge, &nodes, &rectangles, &headers);
@@ -559,24 +620,11 @@ fn route_diagram_impl(
});
}
}
let ends = edge_endpoints(project, diagram, edge, source, target, view, attachments);
let (points, pin_lengths, failure) = route_edge(
edge,
&endpoints(
project,
diagram,
source,
semantic_port_endpoint(project, edge.id, EdgeEnd::Source).or(edge.source_port),
view,
attachments[0],
),
&endpoints(
project,
diagram,
target,
semantic_port_endpoint(project, edge.id, EdgeEnd::Target).or(edge.target_port),
view,
attachments[1],
),
&ends[0],
&ends[1],
&pins,
&obstacles,
&previous,
@@ -793,13 +841,7 @@ fn route_edge(
for &b in target_ends {
// A real self-relation must leave and return at distinct anchors.
// Reusing one anchor makes the cheapest path a degenerate stub.
if edge.source == edge.target
&& edge.source_port.is_none()
&& edge.target_port.is_none()
&& a.point == b.point
&& a.stub == b.stub
&& !coincident
{
if !allowed_endpoint_pair(edge, a, b, coincident) {
continue;
}
let estimate = manhattan(a.stub, pins.first().copied().unwrap_or(b.stub))
@@ -823,13 +865,7 @@ fn route_edge(
}) {
continue;
}
if obstacles
.iter()
.any(|r| r.id != edge.source && r.crosses(a.point, a.stub))
|| obstacles
.iter()
.any(|r| r.id != edge.target && r.crosses(b.point, b.stub))
{
if !lead_pair_clear(edge, a, b, obstacles) {
continue;
}
let mut points = vec![a.point, a.stub];
@@ -846,19 +882,15 @@ fn route_edge(
.enumerate()
{
let incoming = points.iter().rev().find(|&&p| p != start).copied();
// Only the final leg has a known continuation. Intermediate
// authored pins must not inherit the target's terminal direction.
let outgoing = (index == pins.len()).then_some(b.point);
let path =
fast_path(start, end, &space, &occupied, incoming, outgoing).or_else(|| {
if !search {
return None;
}
let (path, hit_limit) =
grid_path(start, end, &space, &occupied, incoming, outgoing, budget);
exhausted |= hit_limit;
path
});
let path = fast_path(start, end, &space, &occupied, incoming).or_else(|| {
if !search {
return None;
}
let (path, hit_limit) =
grid_path(start, end, &space, &occupied, incoming, budget);
exhausted |= hit_limit;
path
});
let Some(path) = path else {
failed = true;
break;
@@ -1055,7 +1087,6 @@ fn fast_path(
space: &RoutingSpace<'_>,
previous: &[Segment],
incoming: Option<Position>,
outgoing: Option<Position>,
) -> Option<Vec<Position>> {
let obstacles = space.obstacles;
if obstacles
@@ -1075,9 +1106,6 @@ fn fast_path(
incoming
.zip(path.get(1))
.map_or(0.0, |(before, &after)| turn_cost(before, start, after))
+ outgoing
.zip(path.len().checked_sub(2).and_then(|i| path.get(i)))
.map_or(0.0, |(after, &before)| turn_cost(before, end, after))
};
let estimate = |path: &[Position]| base_cost(path) + join(path);
candidates.sort_by(|a, b| estimate(a).total_cmp(&estimate(b)));
@@ -1149,14 +1177,12 @@ impl Ord for QueueItem {
}
}
#[allow(clippy::too_many_arguments)]
fn grid_path(
start: Position,
end: Position,
space: &RoutingSpace<'_>,
previous: &[Segment],
incoming: Option<Position>,
outgoing: Option<Position>,
budget: &mut usize,
) -> (Option<Vec<Position>>, bool) {
let obstacles = space.obstacles;
@@ -1247,10 +1273,6 @@ fn grid_path(
let cost = current.cost
+ manhattan(a, b)
+ before.map_or(0.0, |before| turn_cost(before, a, b))
// Charge before queueing the target so competing arrival
// directions are compared by their complete terminal cost.
+ outgoing.filter(|_| next == last)
.map_or(0.0, |after| turn_cost(a, b, after))
+ crossing_cost(a, b, previous);
if cost >= costs[state] {
continue;
@@ -1605,146 +1627,3 @@ impl BoundsBuilder {
}
}
}
#[cfg(test)]
mod terminal_join_tests {
use super::*;
fn complete_cost(
path: &[Position],
before: Position,
after: Position,
occupied: &[Segment],
) -> f32 {
let mut complete = vec![before];
complete.extend_from_slice(path);
complete.push(after);
path_cost(&complete, occupied)
}
#[test]
fn terminal_join_prefers_equal_bend_witness_without_shared_trunk() {
// Four orientations prevent an accidental horizontal/right-only fix.
for orientation in 0..4 {
let transform = |p: Position| match orientation {
0 => p,
1 => pos(-p.x, p.y),
2 => pos(p.y, p.x),
_ => pos(-p.y, -p.x),
};
let start = transform(pos(0.0, 0.0));
let end = transform(pos(46.0, 180.0));
let before = transform(pos(-18.0, 0.0));
let after = transform(pos(64.0, 180.0));
let occupied = vec![Segment {
a: start,
b: transform(pos(46.0, 0.0)),
count: 1,
}];
let space = RoutingSpace::new(&[]);
let witness = vec![start, transform(pos(0.0, 180.0)), end];
// Length262 + two turns48 =310. The other complete L path has
// the same bends/length but pays46*0.12=5.52 in shared-run cost.
assert!((complete_cost(&witness, before, after, &occupied) - 310.0).abs() < EPSILON);
let fast = fast_path(start, end, &space, &occupied, Some(before), Some(after)).unwrap();
assert_eq!(fast, witness);
assert!((complete_cost(&fast, before, after, &occupied) - 310.0).abs() < EPSILON);
// Exercise grid directly; public routing's valid fast path would
// otherwise hide a target-state ordering regression in grid search.
let mut budget = VIEW_SEARCH_BUDGET;
let (grid, exhausted) = grid_path(
start,
end,
&space,
&occupied,
Some(before),
Some(after),
&mut budget,
);
assert!(!exhausted);
let grid = grid.unwrap();
assert_eq!(grid, witness);
assert!((complete_cost(&grid, before, after, &occupied) - 310.0).abs() < EPSILON);
}
}
#[test]
fn unspecified_continuation_keeps_intermediate_leg_choice() {
let start = pos(0.0, 0.0);
let pin = pos(46.0, 180.0);
let before = pos(-18.0, 0.0);
let occupied = vec![Segment {
a: start,
b: pos(46.0, 0.0),
count: 1,
}];
let space = RoutingSpace::new(&[]);
let witness = vec![start, pos(46.0, 0.0), pin];
let fast = fast_path(start, pin, &space, &occupied, Some(before), None).unwrap();
assert_eq!(fast, witness);
// An intermediate authored pin has no known outgoing continuation:
// length226 + one turn24 + shared5.52 =255.52 for this leg.
assert!((path_cost(&fast, &occupied) - 255.52).abs() < EPSILON);
let mut budget = VIEW_SEARCH_BUDGET;
let (grid, exhausted) = grid_path(
start,
pin,
&space,
&occupied,
Some(before),
None,
&mut budget,
);
assert!(!exhausted);
assert_eq!(grid.unwrap(), witness);
}
#[test]
fn straight_and_degenerate_terminal_legs_remain_exact() {
let space = RoutingSpace::new(&[]);
let start = pos(0.0, 0.0);
let end = pos(46.0, 0.0);
for after in [pos(64.0, 0.0), pos(28.0, 0.0)] {
let before = pos(-18.0, 0.0);
let fast = fast_path(start, end, &space, &[], Some(before), Some(after)).unwrap();
let expected = if after.x > end.x { 82.0 } else { 130.0 };
assert!((complete_cost(&fast, before, after, &[]) - expected).abs() < EPSILON);
let mut budget = VIEW_SEARCH_BUDGET;
let (grid, exhausted) = grid_path(
start,
end,
&space,
&[],
Some(before),
Some(after),
&mut budget,
);
assert!(!exhausted);
assert_eq!(grid.unwrap(), fast);
}
assert_eq!(
fast_path(
start,
start,
&space,
&[],
Some(pos(-18.0, 0.0)),
Some(pos(18.0, 0.0))
)
.unwrap(),
vec![start]
);
let mut budget = VIEW_SEARCH_BUDGET;
let (grid, exhausted) = grid_path(
start,
start,
&space,
&[],
Some(pos(-18.0, 0.0)),
Some(pos(18.0, 0.0)),
&mut budget,
);
assert!(!exhausted);
assert_eq!(grid.unwrap(), vec![start]);
}
}
+173
View File
@@ -0,0 +1,173 @@
//! Necessary terminal-lead checks shared with experimental placement consumers.
use super::*;
#[derive(Debug, Clone, PartialEq)]
pub struct LeadBlocker {
pub id: Id,
/// The actual routing obstacle: clearance inflated, ancestor body excluded.
pub bounds: RoutingBounds,
}
#[derive(Debug, Clone, PartialEq)]
pub struct LeadEndpoint {
pub owner: Id,
pub tip: Position,
pub stub: Position,
pub blockers: Vec<LeadBlocker>,
/// Separate information only; not part of the router's early lead guard.
pub stub_containers: Vec<LeadBlocker>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct LeadIncompatibility {
pub edge: Id,
pub source: Vec<LeadEndpoint>,
pub target: Vec<LeadEndpoint>,
pub allowed_pair_count: usize,
pub lead_clear_pair_count: usize,
}
fn blocker(r: &Rect) -> LeadBlocker {
LeadBlocker {
id: r.id,
bounds: RoutingBounds {
position: pos(r.left, r.top),
size: Size {
width: r.right - r.left,
height: r.bottom - r.top,
},
},
}
}
fn describe(owner: Id, endpoint: Endpoint, obstacles: &[Rect]) -> LeadEndpoint {
LeadEndpoint {
owner,
tip: endpoint.point,
stub: endpoint.stub,
blockers: obstacles
.iter()
.filter(|r| r.id != owner && r.crosses(endpoint.point, endpoint.stub))
.map(blocker)
.collect(),
stub_containers: obstacles
.iter()
.filter(|r| r.contains(endpoint.stub))
.map(blocker)
.collect(),
}
}
/// Return only edges for which every allowed endpoint pair fails the router's
/// existing mandatory-lead guard. Empty output is NECESSARY ONLY: it does not
/// establish a clear route, clear pins, successful search, or label clearance.
/// Uses the supplied final projection; does not modify the Project or choose
/// different ports/attachments. Stub containment is reported separately and
/// does not change the lead guard or its historical pinned/degenerate behavior.
pub fn lead_incompatibilities(
project: &Project,
diagram: &Diagram,
view: &ProjectedView,
) -> Vec<LeadIncompatibility> {
let nodes: BTreeMap<_, _> = view.nodes.iter().map(|n| (n.id, n)).collect();
let rectangles: Vec<_> = nodes.values().map(|n| Rect::node(n)).collect();
let authored: BTreeMap<_, _> = diagram.routes.iter().map(|r| (r.edge, r)).collect();
let headers: BTreeMap<_, _> = nodes
.values()
.map(|node| {
(
node.id,
if diagram.projection.state_machine().is_some() && !node.collapsed {
projection::state_header_height(project, node.element)
} else {
HEADER
},
)
})
.collect();
let mut ordered: Vec<_> = view.edges.iter().collect();
ordered.sort_by_key(|e| e.id);
let mut result = Vec::new();
for edge in ordered {
let (Some(source), Some(target)) = (nodes.get(&edge.source), nodes.get(&edge.target))
else {
continue;
};
let (_, _, attachments) =
effective_route(project, diagram, edge, authored.get(&edge.id).copied());
let ends = edge_endpoints(project, diagram, edge, source, target, view, attachments);
let obstacles = edge_obstacles(edge, &nodes, &rectangles, &headers);
let coincident = edge.source == edge.target
&& ends[0].len() == 1
&& ends[1].len() == 1
&& ends[0][0].point == ends[1][0].point
&& ends[0][0].stub == ends[1][0].stub;
let mut allowed_pair_count = 0;
let mut lead_clear_pair_count = 0;
for &a in &ends[0] {
for &b in &ends[1] {
if !allowed_endpoint_pair(edge, a, b, coincident) {
continue;
}
allowed_pair_count += 1;
if lead_pair_clear(edge, a, b, &obstacles) {
lead_clear_pair_count += 1;
}
}
}
if lead_clear_pair_count == 0 {
result.push(LeadIncompatibility {
edge: edge.id,
source: ends[0]
.iter()
.map(|&e| describe(edge.source, e, &obstacles))
.collect(),
target: ends[1]
.iter()
.map(|&e| describe(edge.target, e, &obstacles))
.collect(),
allowed_pair_count,
lead_clear_pair_count,
});
}
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn coincident_selfloop_exception_and_stub_containment_remain_separate() {
let owner = Id::from_u128(1);
let edge = ProjectedEdge {
id: Id::from_u128(2),
source: owner,
target: owner,
source_port: None,
target_port: None,
trace: false,
oriented: true,
};
let endpoint = Endpoint {
point: pos(0., 0.),
stub: pos(18., 0.),
};
assert!(!allowed_endpoint_pair(&edge, endpoint, endpoint, false));
assert!(allowed_endpoint_pair(&edge, endpoint, endpoint, true));
let obstacles = [Rect {
id: owner,
left: -1.,
right: 20.,
top: -1.,
bottom: 1.,
}];
assert!(lead_pair_clear(&edge, endpoint, endpoint, &obstacles));
let diagnostic = describe(owner, endpoint, &obstacles);
assert!(diagnostic.blockers.is_empty());
assert_eq!(diagnostic.stub_containers.len(), 1);
// This diagnostic must not be folded into the historical early guard.
assert_eq!(diagnostic.stub_containers[0].id, owner);
}
}
+238
View File
@@ -0,0 +1,238 @@
use oa_core::{projection, routing, *};
struct Fixture {
p: Project,
d: Id,
edge: Id,
source: Id,
target: Id,
blocker: Id,
}
fn fixture(ports: bool, gap: f32) -> Fixture {
let mut p = Project::empty();
let kind = if ports {
Kind::Function
} else {
Kind::DataType
};
let a = p.add_element(kind, Layer::Sa, "Source", None).unwrap();
let b = p.add_element(kind, Layer::Sa, "Target", None).unwrap();
let c = p.add_element(kind, Layer::Sa, "Blocker", None).unwrap();
for element in p.elements.values_mut() {
if let Some(SharedBody::DataType { definition, .. }) = element.shared_mut() {
*definition = DataTypeDefinition::Record { supertype: None };
}
}
let edge = p.relate(
if ports {
RelationKind::FunctionalExchange
} else {
RelationKind::DataAssociation
},
"Flow",
a,
b,
);
let d = p.ensure_diagram(Layer::Sa);
let source = p.place(d, a, Position { x: 0., y: 0. });
let target = p.place(
d,
b,
Position {
x: 500.,
y: 180. + gap,
},
);
let blocker = p.place(d, c, Position { x: 500., y: 20. });
for n in p.diagrams.get_mut(&d).unwrap().nodes.values_mut() {
n.size = Size {
width: 224.,
height: 160.,
};
}
if ports {
for (owner, end, side) in [
(source, EdgeEnd::Source, PortAnchorSide::Right),
(target, EdgeEnd::Target, PortAnchorSide::Top),
] {
let port = routing::semantic_port_endpoint(&p, edge, end).unwrap();
p.diagrams
.get_mut(&d)
.unwrap()
.nodes
.get_mut(&owner)
.unwrap()
.port_anchors
.push(PortAnchor {
port,
side,
offset: 0.5,
});
}
}
validate_candidate(&p).unwrap();
Fixture {
p,
d,
edge,
source,
target,
blocker,
}
}
fn report(f: &Fixture) -> Vec<routing::LeadIncompatibility> {
routing::lead_incompatibilities(
&f.p,
&f.p.diagrams[&f.d],
&projection::project_view(&f.p, f.d),
)
}
fn attachment_route(edge: Id) -> EdgeRoute {
EdgeRoute {
edge,
source_attachment: Some(EdgeAttachment {
side: PortAnchorSide::Top,
offset: 0.25,
}),
target_attachment: Some(EdgeAttachment {
side: PortAnchorSide::Bottom,
offset: 0.75,
}),
waypoints: vec![Position { x: 300., y: 400. }],
label: None,
}
}
#[test]
fn exact_twenty_gap_is_blocked_thirty_plus_clears_without_mutation() {
let f = fixture(true, 20.);
let original = f.p.clone();
let r = report(&f);
assert_eq!(r.len(), 1);
assert_eq!(
(
r[0].edge,
r[0].allowed_pair_count,
r[0].lead_clear_pair_count
),
(f.edge, 1, 0)
);
assert_eq!(r[0].source[0].owner, f.source);
let end = &r[0].target[0];
assert_eq!(end.owner, f.target);
assert_eq!(end.tip, Position { x: 612., y: 200. });
assert_eq!(end.stub, Position { x: 612., y: 182. });
assert_eq!(end.blockers.len(), 1);
assert_eq!(end.blockers[0].id, f.blocker);
assert_eq!(
end.blockers[0].bounds,
routing::RoutingBounds {
position: Position { x: 488., y: 8. },
size: Size {
width: 248.,
height: 184.
},
}
);
assert_eq!(end.stub_containers, end.blockers);
assert_eq!(f.p, original);
assert!(report(&fixture(true, 30.)).is_empty());
assert!(report(&fixture(true, 31.)).is_empty());
}
#[test]
fn semantic_manual_ports_override_dormant_route_attachments_and_pins() {
let mut f = fixture(true, 20.);
let expected = report(&f);
f.p.diagrams
.get_mut(&f.d)
.unwrap()
.routes
.push(attachment_route(f.edge));
assert_eq!(report(&f), expected);
let view = projection::project_view(&f.p, f.d);
let routed = routing::route_diagram(&f.p, &f.p.diagrams[&f.d], &view);
assert_eq!(
routed.edges[&f.edge].points.last(),
Some(&expected[0].target[0].tip)
);
assert!(
routed.edges[&f.edge]
.warnings
.contains(&routing::RouteWarning::NoClearPath)
);
}
#[test]
fn unconstrained_nonport_alternative_is_not_hard_blocked() {
let mut f = fixture(false, 20.);
assert!(report(&f).is_empty());
let mut route = attachment_route(f.edge);
route.source_attachment = Some(EdgeAttachment {
side: PortAnchorSide::Right,
offset: 0.5,
});
route.target_attachment = Some(EdgeAttachment {
side: PortAnchorSide::Top,
offset: 0.5,
});
f.p.diagrams.get_mut(&f.d).unwrap().routes.push(route);
let r = report(&f);
assert_eq!(r.len(), 1);
assert_eq!(r[0].allowed_pair_count, 1);
assert_eq!(r[0].target[0].blockers[0].id, f.blocker);
}
#[test]
fn nested_endpoint_body_is_traversable_and_promoted_attachments_are_suspended() {
let mut f = fixture(false, 20.);
// DataType containment is not required for this routing-only view witness:
// construct the supplied projected forest explicitly, retaining real owners.
let mut view = projection::project_view(&f.p, f.d);
let parent = Id::new_v4();
let source = view.nodes.iter_mut().find(|n| n.id == f.source).unwrap();
source.visual_parent = Some(parent);
source.position = Position { x: 40., y: 100. };
let element = source.element;
view.nodes.push(projection::ProjectedNode {
id: parent,
element,
position: Position { x: 0., y: 0. },
size: Size {
width: 300.,
height: 300.,
},
visual_parent: None,
depth: 0,
collapsed: false,
allocation_summary: false,
});
let mut route = attachment_route(f.edge);
route.source_attachment = Some(EdgeAttachment {
side: PortAnchorSide::Right,
offset: 0.5,
});
route.target_attachment = Some(EdgeAttachment {
side: PortAnchorSide::Top,
offset: 0.5,
});
f.p.diagrams.get_mut(&f.d).unwrap().routes.push(route);
let r = routing::lead_incompatibilities(&f.p, &f.p.diagrams[&f.d], &view);
assert_eq!(r.len(), 1);
assert!(
r[0].source[0].blockers.is_empty(),
"Ancestor body must not block source lead"
);
// Promotion changes actual projected owner: custom attachments no longer apply.
view.edges
.iter_mut()
.find(|e| e.id == f.edge)
.unwrap()
.source = parent;
let with_dormant = routing::lead_incompatibilities(&f.p, &f.p.diagrams[&f.d], &view);
f.p.diagrams.get_mut(&f.d).unwrap().routes.clear();
assert_eq!(
with_dormant,
routing::lead_incompatibilities(&f.p, &f.p.diagrams[&f.d], &view)
);
}
+98
View File
@@ -498,3 +498,101 @@ editing remains separate from semantic reconnect. The [decision and evidence
map](edge-attachments-20260922.md) records alternatives, lifecycle rules,
independent falsifiers, evaluators and the Process/Scenario applicability limits.
This is branch-specific work; it does not establish an integrated release.
## Retain released routing after independent corpus comparison — 2026-09-25
Issue #32's [fixed comparison](experiments/routing-independent-20260925/results.md)
rejects adoption of target-join J and bounded-lane L at this checkpoint. Optimized
timings pass the declared screen, but a fixed edge-ID permutation worsens shared
runs under both candidates; workshop label conflicts also increase. L's large
workshop overlap improvement does not establish native traceability. Keep released
`715036e` routing for the separate explicit Arrange-reset candidate. Preserve the
experiments and stop tuning this corpus. Reconsider adoption only with meaningful
named trace-task improvements, no newly ambiguous task, and appropriate runtime
evidence. This is a branch-specific decision, not a completed Arrange feature or
integrated release; the linked record retains rejected alternatives and limits.
## Placement must respect derived ports and mandatory exits — 2026-09-25
Branch-specific issue32 research, not an integrated release. The bounded
[placement comparison](experiments/connection-layout-reference-20260925/results.md)
shows that a node/label layout followed by independent port selection and routing
is not a faithful transfer of a port-constrained engine result. Automatic ports
change sides/slots after positions move even though authored anchors stay exact.
The sparse reference's20-unit gap cannot contain the released router's18-unit
port lead plus12-unit obstacle clearance. The sole endpoint pair is rejected
before path search; increasing search work would not repair that placement.
Keep both candidates experimental. A future candidate needs explicit final-port
and mandatory-lead compatibility checks, compound/undirected semantics, and the
existing preservation/native trace gates. Raw engine paths avoiding uninflated
node interiors do not prove compatibility with our inflated obstacles and leads.
Do not silently shorten those leads, move authored anchors, or persist external
generated bends to make a comparison pass. Revisit engine integration only with
a faithful geometry interface and observed usability benefit.
## Lead compatibility does not establish layout quality — 2026-09-25
The [bounded separation experiment](experiments/placement-clearance-20260925/results.md)
at07405126 fixes the exact sparse mandatory-lead conflict by moving eight nodes
down11 units. It removes NoClearPath and node penetration while preserving model
records, anchors and repeated-call stability. Existing route-control output is
byte-identical to released routing. However crossings20→22, shared length666→761
and label/stroke intersections0→1 prevent a general readability improvement
claim. Keep this flat-only repair isolated; do not connect it to production
Arrange or increase its rounds to tune away the result. Use actual endpoint
compatibility as a necessary placement constraint in a future initial coordinate
assignment with connection ordering and corridor/label space. Compound geometry,
automatic side changes and native tracing remain separate required evidence.
This is branch-specific experimental evidence, not an integrated capability.
## Keep cyclic groups coherent before assigning global ranks — 2026-09-25
The [SCC placement experiment](experiments/scc-placement-20260925/results.md)
at `2426d286` supports condensation of sibling-subtree cycles as a useful
structural step. Independent reconstruction finds four ten-node components in
the sparse case. Compact blocks remove the old layered prototype's shared top
corridor: raw pairwise sharing falls from 40,522 to 32, with fewer crossings and
less area than that prototype. The released router is unchanged. The full
comparison includes original and Arrange-reset controls; this is not a universal
improvement across all measures or scenes.
Preserve effective geometry at the placement-transfer boundary. An old
projected size can depend on children that subsequently move inward; retaining
the old authored size then loses an explicitly requested minimum. The corrected
example importer makes one conditional simultaneous minimum restoration and
still demands exact final projection. All 14 frozen cases now complete; the
13 prior successful outputs remain exactly unchanged, with conservation,
roundtrip and ten-call checks recorded. This is an experimental transfer
contract, not a production command or history integration.
Do not adopt the whole candidate yet. The two-container case still ignores
external-neighbor order within each parent and is worse than the old layered
zero-sharing witness. Sparse residual label conflicts, folded route retracing,
bipartite sharing and area tradeoffs remain distinct issues. The next bounded
comparison should preserve coherent SCC ranks while using actual cross-boundary
neighbors to order siblings. Treat label association separately from route
sharing, preserve the full quality vector, and retain native tracing as a later
acceptance gate. No global gap or routing-penalty sweep follows from this result.
## Incoming boundary order is useful but not sufficient — 2026-09-25
The [boundary-order comparison](experiments/boundary-order-20260925/results.md)
at3e21c1bc preserves SCC blocks/ranks and orders same-rank child blocks using
incoming external source centers. Dependency components provide deterministic
propagation; cycles use one simultaneous snapshot. It fixes the declared
simple two-container tracing witness (sharing164→0) and three-parent chain,
while preserving all ten flat Projects/metrics exactly. All20 candidates pass
independent full-Project conservation. Native saved-Project inspection confirms
the simple trace improvement without establishing a native planner integration.
Retain the mechanism experimentally. Folded workshop sharing726.5→1077.5,
expanded crossing6→7, and anchored/local-SCC label intersections prevent
unconditional adoption. Native anchored labels remain readable while their
backgrounds interrupt the parent border: geometric collision counts require
severity and ownership interpretation, not silent removal. Full member displacement
must be checked in f64 before final f32 rounding; checking only a rounded delta
misses large-origin errors. No further parameter sweep or release change is
justified by this checkpoint. Production selection, label handling and integration
remain open; the user requested a stop after publication.
@@ -16,6 +16,17 @@ isolates a routing score correction with fixed Projects/nodes/ports/endpoints.
Its 185 regression checks pass, but an original-scene overlap regression and
additional bipartite T contacts prevent a general readability acceptance.
The [completed scoring/lane comparison](experiments/auto-layout-20260925/results-lanes.md)
records J/P/PL/L and closes this fixture-tuning experiment. L passes 188 selected
checks and strict core Clippy, but residual ambiguity and a runtime cost signal
require broader, independently selected evidence before production adoption.
The [frozen independent corpus comparison](experiments/routing-independent-20260925/results.md)
passes its optimized timing screen but exposes additional ID-order and label
tradeoffs. Retain released routing for the separate route-reset work; J/L remain
experiments without native traceability acceptance. Its complete inputs, raw
receipts, corrected evaluator and independent reviews are recorded together.
## Question and existing evidence
Can explicit Auto-layout produce a readable arrangement that accounts for
@@ -106,3 +117,44 @@ Actual representative Windows workflows, including meaningful window/zoom sizes,
selection and saved reopen, follow an implemented candidate. Linux remains
excluded by the current user instruction. The separately published State label
candidate in issue36 is not silently treated as integrated into this base.
## Placement/reference compatibility checkpoint
The [fixed external placement comparison](experiments/connection-layout-reference-20260925/results.md)
tests the old native prototype and elkjs0.12.0 positions through the released
router on the same independent corpus. Mixed placement metrics improve, but
automatic ports differ from the engine's assumptions; the sparse candidate
violates mandatory port-exit clearance and falls back before path search.
Both workshop reference cases reject an unsupported undirected edge. Neither
candidate is adopted. The next interface must account for final automatic
ports and mandatory leads, not only node/label boxes. All results remain
branch-specific; Gitea holds publication and integration status.
The follow-up [mandatory-lead separation experiment](experiments/placement-clearance-20260925/results.md)
supplies that necessary check using the router's actual endpoint choices. One
bounded flat repair removes the sparse hard routing failure, but worsens crossing,
shared-run and label/stroke measures. Preserve the compatibility result without
adopting this repair as Arrange. Initial connection ordering and reserved routing/
label space, with compound handling, remain the next planner questions; more
repair iterations or router penalty tuning are not supported by this evidence.
The [coherent cyclic-group experiment](experiments/scc-placement-20260925/results.md)
then isolates the old native candidate's rank-stretching problem. Sparse sharing
falls from 40,522 to 32 with unchanged released routing. A corrected importer
preserves requested effective container minima after child movement; all 14
frozen cases complete and the 13 previously successful results remain exact.
This is useful structural evidence, not an Arrange replacement. Cross-boundary
child ordering, local label conflicts and folded backtracking remain explicit
witnesses. Source, failed/successful runs, conservation and independent reviews
are linked from the result. Gitea remains authoritative for live ownership and
publication status; no integrated checkpoint or release change is implied.
The [incoming boundary-order experiment](experiments/boundary-order-20260925/results.md)
resolves the exact simple two-container tracing defect and preserves all flat
SCC results. Twenty supported cases retain model/anchor/block invariants, but
workshop sharing/crossing and label tradeoffs remain. Saved-Project native
inspection confirms the simple benefit and limits the severity interpretation
of anchored label intersections. This is a published research checkpoint, not
an integrated Arrange replacement. Gitea records handoff and the user-requested
pause; no further experiment is authorized during that pause.
@@ -0,0 +1,46 @@
# L results and four-way routing experiment audit
Recommendation: stop tuning these fixtures. L is a useful experimental witness that route alternatives affect sharing, but its small layered benefit and material runtime signal do not presently justify its per-leg preprocessing as a production default. Keep J as the simpler independently motivated scoring correction candidate; decide L only against frozen independent scenes and route-only timing. No production/native acceptance claimed.
## Verified final L result
Primary J06 pin `08656b18bf8934cf264469cf68fc6dea97c15cbb`; L11 pin `e8ec6dbb3160f62476a5557f14605f68959f65fe`. Both recorded offline dev/gnullvm probe commands exit0, source unchanged, failure null. Verified receipt log hashes. Separate raw-output traversal confirms all37 Projects, projected nodes/ports and per-edge endpoint records exactly equal. All nine candidate supported/repeat-input/idempotence/ten-call/JSON-and-single-source-roundtrip results remain true, with unchanged conservation and baseline history checks. Candidate Command/Undo integration remains absent.
J→L changed scalar rows only:
- Original bipartite raw sharing872→724, nonterminal800→652.
- Layered bipartite raw187→176, nonterminal115→104; drawing area175960→165360.
- Original two-container raw/nonterminal54→12.
- Two-container baseline and reset raw/nonterminal18→12 each.
The other32 rows are unchanged in recorded scalar quality metrics. No changed point-contact, proper-crossing, length, bend, warning or collision counts in J→L. Independently comparing full candidate metric objects confirms all nine L layered metrics exactly equal PL, not merely the headline totals. Remaining layered bipartite104 nonterminal shared units still prohibit a solved-traceability claim.
Test10 receipts record135+7+13+18+2+13=188 passed,0 failed/ignored, exit0, unchanged source. J02 and L10 command argv and entire recorded environment dictionaries compare equal. Their routing_geometry test summary elapsed4.30s versus16.43s (~3.82 times, +12.13s); parent reports no concurrent agent compiler. This is a material cost signal, not a controlled routing benchmark: suite runtime includes varied tests and scheduling effects, with no repeated route-only timing. It must not be dismissed by quoting cargo compilation time or presented as an established scaling law.
Verified37 L schematic image hashes/lengths and manifest input hash. Native/glyph rendering was not exercised. Strict Clippy12 was active when assigned and is outside this audit; no outcome inferred.
## Four-way conclusion
All numbers below are raw pairwise shared length; inspect the preceding audits for contacts/area/turn tradeoffs.
| Scene/variant | J | P | P+L | L |
|---|---:|---:|---:|---:|
| Layered bipartite |187|187|176|176|
| Original bipartite |872|730|724|724|
| Baseline/reset bipartite |276|276|72|276|
| Original two-container |54|6|12|12|
| Baseline/reset two-container |18|18|12|12|
P has no layered benefit. P+L's baseline bipartite72 means only common terminal sharing remains, but proper crossings rise0→1, length+24 and area+19392; L alone does not produce that tradeoff. The strongest ordinary two-container sharing result is P6, at an extra bend,12 length units and one T contact. Neither the coefficient nor lanes dominates all vectors. J diamond's isolated improvement remains valid but does not erase its original bipartite regression.
Next scope should be finite and specified before inspecting outcomes: one realistic nested/folded scene, one mixed fan-in/out with a fixed edge-ID permutation, and one modest sparse scene measured by route-only timing and warning/budget counts. Preserve endpoint/model constraints and evaluate traceability, collisions, bends/length/area jointly. Do not silently extend unsupported layered folded behavior into an acceptance claim. Set practical timing and readability criteria before repeating improvement. If L does not show proportionate independent benefit, omit it; avoid adding configuration/architecture solely to retain every experiment. The explicit Layout reset policy and ordinary input/Undo/Save lifecycle are still separate implementation work.
## Evidence identities
J06 output `f9ac7c1320b1cf026259bfcaf13a39e968ae317463712d8dc793375d9a4a541f`.
L11 output `64232f580600b7a874a6f4ceb128a6188fd5ff72655bc6b93d824ebed27ffb7d`.
L11 result.json `feee84c2fde115c22ea865033ff2d136da2aace1f1c8a7423c8add11358366a8`.
L comparison JSON `e1e23e6c2a50cd384457bb061d5b70a740f586f42767164fad9703ecbb4096a8`.
L contact audit JSON `6f6cc674c27d3f43001fe1751ef3b09332caa9ddca396759f5525f811cbe1aaf`.
Read-only audit of completed records; no build/probe/helper rerun, source edit or publication. Earlier independent J/P/PL source/results notes retain grid-axis, subdivision-score, capped retained coordinates versus unbounded preprocessing, stable-edge-order and approximate-label limitations.
@@ -0,0 +1,20 @@
# Bounded L lane-candidate source review
Reviewed routing.rs SHA256 `af5995af10c8e3b30c5c6fb776a2ac2678eeef59dd58eb0cdb3d5c62cd153f1b` before parent formatting. Static inspection only; no builds or source edits. No blocking implementation finding for the finite nine-fixture P+L / J+L probe comparison.
The code retains all sorted base obstacle coordinates and adds at most64 unique extras EACH axis (128 total), filters nonfinite generated values, deduplicates before ranking, then ranks distance from the start/end axis interval, distance from its midpoint, and numeric value. Final lists return to coordinate order. It derives perpendicular offsets only from nondegenerate settled other-edge segments. The current edge's earlier legs/source stub still contribute occupied scoring but do not generate lanes. Fast/grid receive the identical per-leg RoutingSpace; obstacles, endpoints, authored pins, terminal joins and fallback remain unchanged.
Three new tests cover80 retained base coordinates plus64 extras per axis, previous-segment reorder/duplication invariance, nearest-interval/midpoint selection and nonfinite rejection, and direct calls to fast/grid sharing the same parallel-lane witness. The latter expects min(direct cost,272) and supports both coefficients. No test success is inferred before execution.
Test-scope caveat sent to parent: the existing `unspecified_continuation_keeps_intermediate_leg_choice` test deliberately hardcodes baseline coefficient0.12, path choice and cost255.52. At P3, the shared penalty caps80 and the alternative is cheaper; a whole private suite at P3 can fail that baseline-policy assertion. Preserve the result honestly; restore0.12 for baseline-suite claims or explicitly distinguish experimental tests. This does not block a diagnostic P+L probe.
Limits relevant to interpreting results:
-64 bounds retained coordinates, not scan/sort work. Every endpoint-pair/leg constructs candidates from all previous segments; this preprocessing is outside the search-step budget. No large-scene performance guarantee.
- Added coordinates can make the grid exceed65536 cells even when its original grid fit. Existing exhaustion warning/fallback is the evidence to inspect, not something to suppress.
- Grid scoring is coordinate-subdivision-sensitive: strict-interior crossing tests can miss contacts at inserted grid vertices, and per-segment capped overlap charges can change with subdivision. Therefore a grid result can change due to scoring partition as well as newly offered parallel lanes. Keep independent contact/shared-interval metrics authoritative for quality observations.
- Rank uses one axis and does not filter segment extent on the other; remote lanes can consume the cap. This deterministic heuristic is not proof of optimal lane coverage. The router still uses a feasible fast path before grid, two-axis rather than signed-direction search state, stable sequential edge order, and local hard-pin legs.
Required experiment interpretation: compare P+L to P and J+L to J with exact Project/node/port/endpoints, all quality metrics and warning counts. Retain label collisions, T/bend contacts, length/turn/area regressions; fewer shared units alone is not acceptance. No broad production or native readability conclusion follows from this finite source review.
Current formatted routing SHA256: 3a8af7a44f8f32bd9fb94dddd9184fafcf64c93c510025169c62958566bbaedf. Reread formatted lane construction: filtering/ranking/cap semantics agree with reviewed candidate. No mechanical original-byte whitespace comparison claimed. Parent plans exactly the three lane-filtered private tests for P+L, then restores0.12 for the full baseline suite; that appropriately separates the baseline-policy assertion noted above.
@@ -0,0 +1,35 @@
# P+L results independent audit
P+L demonstrates that additional lanes can remove one scene's nonterminal overlap, but adds a proper crossing and gives only a small layered improvement. It does not yet justify adopting the extra heuristic as a general production default. Static record audit only; no reruns, builds or source edits.
Compared P07 `3d7adff923dee5bed54dfdccc119dbee0c7c2773` with PL09 `d0be9ff0674373fcf9623daf62bbf50dad02c4df`. Both probe receipts exit0, failure null, unchanged source; all logged hashes independently checked. Separate raw-output traversal confirms all37 Projects, projected nodes/ports and route endpoint records exact. All nine candidate support/repeat/idempotence/ten-call/roundtrip results remain true; conservation and baseline Command::Layout history checks match P. Candidate Undo integration remains untested.
Test08 actually ran `cargo test --locked --offline -p oa-core --lib lane`: five passed,130 filtered, zero failed/ignored. This is three new routing lane tests plus two existing scenario-layout tests, not a whole core-suite pass.
All changed numeric-vector rows, P→PL:
| Scene/variant | Sharing raw / nonterminal | Other changes |
|---|---|---|
| bipartite before |730→724 /658→652|contacts10→9; bends5→4; length2076→2064|
| bipartite baseline |276→72 /204→0|proper crossings0→1; contacts6→5; length3284→3308; area300576→319968|
| bipartite reset |276→72 /204→0|same changes as baseline|
| bipartite layered |187→176 /115→104|area175960→165360; contacts9 unchanged|
| two-container before |6→12 /6→12|contacts3→2; bends5→4; length1524→1512|
| two-container baseline |18→12 /18→12|no other scalar change|
| two-container reset |18→12 /18→12|no other scalar change|
Remaining30 rows unchanged; eight other layered vectors unchanged. No new label-collision or warning-count changes appear. The baseline/reset proper crossing is a real quality tradeoff, not an automatic failure: a visible isolated crossing may be easier to trace than coincident routes. Conversely, zero proper crossings in the layered scene still accompanies104 nonterminal shared units. Two-container original sharing doubles6→12 despite fewer contacts/turns. No single scalar orders all these results.
Viewed the baseline and layered bipartite PNGs. Baseline channels separate except for the isolated crossing; layered channels retain shared horizontals. Verified all37 offline image hashes/lengths and manifest input binding. These are schematic core geometry, not actual font/native rendering or a user traceability test.
Performance/complexity: probe command elapsed approximately67.1s(P) and69.7s(PL), but these cargo invocations include compilation; they are not comparable routing benchmarks and establish no overhead bound. The new code scans/sorts all prior segments for each endpoint-pair/leg;64-per-axis limits retained coordinates, not preparation work. It can expand the grid past its existing cell cap. Grid crossing/overlap scoring also changes under coordinate subdivision. None of these limitations is resolved by the tiny fixture set.
Recommendation: finish the already-declared J/P/PL/L grid and stop coefficient/lane-spacing tuning on these fixtures. Retain L as an experimental option unless the final comparison supplies stronger value. The next useful acceptance scope is a frozen, modest set of independent scenes chosen before results: one realistic authored diagram with nested/folded content, one mixed-direction fan-in/out, and one moderately sized sparse diagram for routing time/budget behavior, including a fixed edge-order permutation. Choose a preferred traceability tradeoff explicitly; do not add architectural hooks merely to preserve this heuristic. Prioritize the explicit Layout command/reset contract and production integration lifecycle once a maintainable geometry choice is selected. No #32 closure or native readability acceptance follows here.
Bindings:
- P output SHA256 `13111fe89e4e637d1af572a8a45b8bdd763e94b58a2ec5ec6ca83e40ffa209c7`.
- PL output `04bb9ba4ab551a965cea130510cca6b96d9c1012911f191b14a7aa7efbf563dd`.
- PL result.json `538aa79bcedd4cf646c63d5309ec738be4676e2045715db1035a4f334a536117`.
- PL comparison JSON `81f57e651a8840aaaeacc085df2eb90174b2e494182f6cd40ccd6d50e7bb531e`.
- PL contact audit JSON `60ce7e9735ceef50a92d29a0414aafe3d8fb6174dab99eff6397e2abc88e0afa` (inspected as independent worker evidence, not rerun here).
@@ -0,0 +1,26 @@
# P overlap-penalty experiment independent audit
Confirmed the reported finite result. Static read-only audit; no build, probe rerun, source edit or GUI action. P does not improve any of the nine layered candidate metric vectors and is not a demonstrated solution to their remaining shared routes.
Primary comparison: J06 `08656b18bf8934cf264469cf68fc6dea97c15cbb` versus P07 `3d7adff923dee5bed54dfdccc119dbee0c7c2773`. Inspected the latter commit: only routing.rs changes, overlap coefficient0.12→3.0 plus an experiment comment; cap80 remains unchanged. Both recorded `cargo run --locked --offline -p oa-core --example auto_layout_probe` receipts are Windows gnullvm/dev, exit0, inputs unchanged, failure null. Independently verified every log hash in both receipts.
Independent traversal of the raw outputs confirmed all37 variant Projects, projected nodes, projected ports and emitted route endpoint records match exactly. All nine layered candidates retain supported=true, repeat-input exactness, idempotence, passes2–10 equal first/previous, exact JSON/single-source roundtrips and identical conservation results. The authored-detour route-reset exception remains intentional. Baseline Command::Layout history/Undo checks remain identical; this is still not candidate-command Undo evidence.
Only two variant rows change numeric metrics:
| Original/before scene | Raw sharing J→P | Nonterminal sharing J→P | Bends | Length | Point contacts |
|---|---:|---:|---:|---:|---:|
| crossed_bipartite |872→730|800→658|4→5|2064→2076|9→10|
| two_containers_reversed_children |54→6|54→6|4→5|1512→1524|2→3|
Each extra contact is classified as a T contact in the separately generated independent interval audit: bipartite T3→4 and two-container T1→2; proper crossings remain0. Lower shared length therefore comes with one additional bend,12 length units and one additional point contact in each scene. Bipartite returns to the pre-J shared-length total; this does not establish trace readability. All baseline/reset rows, manual witness and nine layered scalar vectors are unchanged. Exact model/endpoint invariants do not imply identical polylines.
Evidence identities:
- J06 raw output `f9ac7c1320b1cf026259bfcaf13a39e968ae317463712d8dc793375d9a4a541f` (also identical to J03 output).
- P07 raw output `13111fe89e4e637d1af572a8a45b8bdd763e94b58a2ec5ec6ca83e40ffa209c7`.
- P07 result.json `6149122d05d77e02b463edb3dd359b06786bc4468c27d8cd625cbc1bc80c9894`.
- P comparison JSON `9f228fbe78e1888c5d93e87dddd8d2effc01bab723929a87423c61e23f5cad66`.
- P independent contact audit JSON `6f4add5c81f6d16c45efabbefd9e36c9beb637b6823993f0d51adc3e20485ad9`. Its recorded definitions and counts were inspected; this reviewer did not execute that helper again.
Recommendation: archive P as a bounded negative result for the layered overlap objective, preserving the two ordinary-scene tradeoffs. A predefined bounded lane-candidate experiment can now test whether available route geometry, rather than this single coefficient, limits improvement. Retain the same Projects/endpoints and all quality metrics; do not tune indefinitely against these nine fixtures or claim general quality/native acceptance. The cap, sequential edge order, fast-path preference, axis-only grid state and estimated label bounds remain limits.
@@ -0,0 +1,112 @@
# Complete scoring/lane comparison
**Stop tuning these nine fixtures; retain the variants as experimental evidence.**
Bounded parallel lane candidates have some measurable value, but do not resolve
the compact bipartite ambiguity and introduce a routing-cost concern. The
stronger overlap coefficient is no longer present at the branch tip. No routing
or Arrange replacement has been accepted for production.
PL source `d0be9ff0674373fcf9623daf62bbf50dad02c4df` combines target-join J,
coefficient 3.0/cap 80 and bounded lanes. L source
`e8ec6dbb3160f62476a5557f14605f68959f65fe` restores coefficient 0.12, retaining
J and lanes. Each leg keeps every obstacle coordinate and adds at most 64
deterministic coordinates per axis at CLEARANCE offsets from settled other-edge
segments. Fast/grid searches receive the same augmented space. Endpoint geometry,
authored pins, attachments and model metadata are not edited by this operation.
The [source review](lanes-source-review.md) records attribution limits: retained
coordinates are bounded, but collection/sorting of prior segments is not charged
to the search budget. Extra axes can hit the existing grid-cell cap and can alter
grid scores through segment subdivision. This is not a proof of globally optimal
paths or constant preparation cost. No new engine/runtime dependency was added.
## Results
Every one of the 37 complete Projects, node sets, port sets and exact endpoints
matches its control in both comparisons. All nine candidate invariants,
roundtrips and repeated-call checks hold. Values below are raw pairwise shared
length for the crossed-bipartite fixture; complete vectors remain in the archive.
| Router | Original scene | Existing Layout/reset | Layered candidate |
| --- | ---: | ---: | ---: |
| Released router | 730 | 276 | 344 |
| J | 872 | 276 | 187 |
| J + stronger penalty (P) | 730 | 276 | 187 |
| J + stronger penalty + lanes (PL) | 724 | 72 | 176 |
| J + lanes, original penalty (L) | 724 | 276 | 176 |
PL's existing-Layout/reset result eliminates 204 nonterminal shared units but
adds one proper crossing, 24 route-length units and 19392 area units. Contacts
decrease 6→5; these tradeoffs stay explicit. L with the original coefficient
does not achieve that baseline improvement. Both lane variants leave 104
nonterminal units in the compact layered case, with nine point contacts. Its
drawing area returns from J's 175960 to 165360. Eight other layered metric
vectors are unchanged. The parent viewed the PL bipartite schematic: vertical
channels are separated, but horizontal tails still join at ambiguous branches.
Compared with J, L reduces original bipartite sharing 872→724 and original
two-container sharing 54→12 without changing the other original quality fields;
two-container baseline/reset sharing reduces 18→12. PL compared with P includes
a two-container original sharing regression 6→12 while reducing one bend, 12
length units and one contact. The [PL audit](penalty-lanes-audit.md) documents all
seven changed rows; no scalar is treated as a universal quality score. Labels,
obstacles and warnings remain separately checked. Core schematics and approximate
label boxes do not establish actual glyph layout or native route traceability.
## Verification and evidence
Same frozen Windows Rust1.98.1 gnullvm environment, one Cargo job, locked/offline,
incremental disabled. Linux excluded. All runs close with exit0, unchanged
inputs and no runner failure:
```text
# PL: five matched tests, including all three new lane tests
cargo test --locked --offline -p oa-core --lib lane
# L: 188 tests passed, zero failed/ignored
cargo test --locked --offline -p oa-core --lib --test release_routing --test routing_geometry --test routing_labels --test state_diagrams --test group_movement
# Both variants: complete nine-fixture diagnostic
cargo run --locked --offline -p oa-core --example auto_layout_probe
# L: strict core/all-target Clippy passed
cargo clippy --locked --offline -p oa-core --all-targets -- -D warnings
```
The full 188 check is for L, not PL: an existing private J test intentionally
asserts the original 0.12 cost. PL's filtered run executes three new lane tests
and two existing Scenario tests matched by `lane`; 130 other library tests are
filtered. Lane witnesses cover base-coordinate preservation, 64-extra bounds,
deduplication/order independence, relevance ranking, nonfinite rejection and
fast/grid selection of a feasible parallel path under the experimental cost.
**Cost signal:** routing_geometry's 18-test runtime is 16.43s under L versus
4.30s under J on the same machine/environment. This excludes compilation, but
is one suite observation per variant, not an isolated route benchmark or a
performance bound. It warrants profiling before adopting per-leg lane scans.
Whole cargo/probe elapsed times include compilation and are unsuitable for that
comparison.
The [independent final L/four-way audit](lanes-results-audit.md) confirms all 37
fixed bindings and the 188-test result, checks the recorded geometry/contact
evidence, and likewise recommends withholding L from production pending the
independent corpus and route-only timing.
[Evidence archive](run-lanes/lanes-e8ec6db.zip), 3518507 bytes, SHA256
`5512b4cbd99e3bf03eb975e25fb980f7b1a95a5cb19f3687fb3d6d83d1839e8f`,
contains original runs08–12, 74 offline images, complete comparisons, independent
axis-based contact audits, binary identities and runners. [Manifest](
run-lanes/manifest.json) binds every member, all byte-compared to originals.
PL output SHA256 `04bb9ba4ab551a965cea130510cca6b96d9c1012911f191b14a7aa7efbf563dd`;
L output SHA256 `64232f580600b7a874a6f4ceb128a6188fd5ff72655bc6b93d824ebed27ffb7d`.
The earlier P result and original archive remain linked in [results-p.md](results-p.md).
## Decision and next evidence
Do not choose a global router policy from these nine scenes. Freeze a small
independent corpus before the next run: realistic authored nested/folded content,
mixed-direction shared/distinct-port fan-in/out with a fixed edge-ID permutation,
and a modest sparse diagram for isolated routing-time/budget observations. Compare
J and L with an explicit route-tracing rubric and full quality vector. Preserve
the original Scene/Arrange distinction and source/history lifecycle constraints.
This should decide whether the lane cost is justified or the simpler router
should be retained before broadening the Layout prototype. Fold/filter rules,
one-command Undo, API/source parity and real desktop acceptance remain required;
the separately pending State-label issue36 is not silently included here.
@@ -0,0 +1,50 @@
# Capped overlap-penalty experiment
**P alone does not solve the arranged bipartite overlap.** Source
`3d7adff923dee5bed54dfdccc119dbee0c7c2773` changes only the overlap coefficient
from 0.12 to 3.0 (plus an experiment comment), retaining the per-segment cap 80.
Node placement, ports, target-join J logic, edge order and crossing cost remain
unchanged. This is a transient diagnostic source variant, not a proposed default.
Windows command `cargo run --locked --offline -p oa-core --example
auto_layout_probe` completed exit 0 with unchanged inputs at
2026-09-25T01:04:57Z. Same frozen Rust1.98.1 gnullvm environment as J; Linux
excluded. Output SHA256
`13111fe89e4e637d1af572a8a45b8bdd763e94b58a2ec5ec6ca83e40ffa209c7`.
J's 185 passing tests and strict Clippy are not claimed for P; this run executes
the diagnostic observer and its analytic primitives only.
[Original evidence archive](run-p/penalty-3d7adff.zip), 916568 bytes, SHA256
`6b819b01c8012aa72d423443f4dc04ae261f1ee9dc6907f0063c219ff173ad36`,
contains receipts, complete Projects/geometry, independent contact audit,
comparison, renderer output and runner. [Manifest](run-p/manifest.json) binds
original bytes and post-run probe executable; every member was checked against
its local original.
Complete Projects, nodes, ports and route endpoints are exact versus J in all
37 variants. All nine layered candidates retain the previous quality vector;
in particular bipartite sharing remains 187 (115 nonterminal), with nine contacts
and zero proper crossings. Two original-scene vectors change; the other 35 do
not:
| Original scene | Shared length J → P | Bends | Route length | Point contacts |
| --- | ---: | ---: | ---: | ---: |
| Crossed bipartite | 872 → 730 | 4 → 5 | 2064 → 2076 | 9 → 10 |
| Reversed children in two containers | 54 → 6 | 4 → 5 | 1512 → 1524 | 2 → 3 |
The bipartite result restores the first experiment's original-scene vector;
the extra bend/length tradeoff was predicted by the low overlap cost diagnosis.
Both contact increases remain visible rather than being counted as a clean
readability win. These results concern core geometry, not native route tracing.
The [independent P audit](penalty-results-audit.md) confirms these results and
all nine recorded conservation/roundtrip/repetition checks. Both additional
point contacts are T contacts; no proper crossing change is hidden by the table.
The next L comparison adds a bounded number of deterministic parallel lane
coordinates while preserving all existing obstacle coordinates and fixed
endpoints. Use the same augmented geometry for fast/grid search. P+L and J+L
will distinguish available alternatives from preference. The cap 80 may still
reject a four-turn detour whose extra length/turn cost exceeds it; retain that
outcome rather than retuning cap, ordering and spacing together. No weight or
lane policy is accepted for production by this diagnostic run.
@@ -0,0 +1 @@
* -text whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol
@@ -0,0 +1,565 @@
{
"scope": "Finite PL/L experiments; no production/native/performance acceptance",
"runs": [
{
"name": "08-lane-tests",
"source_commit": "d0be9ff0674373fcf9623daf62bbf50dad02c4df",
"exit_code": 0
},
{
"name": "09-penalty-lanes-probe",
"source_commit": "d0be9ff0674373fcf9623daf62bbf50dad02c4df",
"exit_code": 0
},
{
"name": "10-lanes-core-tests",
"source_commit": "e8ec6dbb3160f62476a5557f14605f68959f65fe",
"exit_code": 0
},
{
"name": "11-lanes-probe",
"source_commit": "e8ec6dbb3160f62476a5557f14605f68959f65fe",
"exit_code": 0
},
{
"name": "12-lanes-clippy",
"source_commit": "e8ec6dbb3160f62476a5557f14605f68959f65fe",
"exit_code": 0
}
],
"post_run_l_probe_binary": {
"bytes": 24202240,
"sha256": "3c6a6fd09bc86e7e6b3ff1ace05540c103393d66bbb02c46bf0ebd6214fbabb1"
},
"members": {
"08-lane-tests/command/changes.patch": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"08-lane-tests/command/context.json": {
"bytes": 3478,
"sha256": "7f30e52a87c964d86e86229061be72372a9cfc1a3fad9a37c326370c38aec4ad"
},
"08-lane-tests/command/inputs-after.json": {
"bytes": 1730052,
"sha256": "2173ea00107237f320ab249a6fcde0ec616421aa09d6c274ef563e9974b47e6e"
},
"08-lane-tests/command/inputs-before.json": {
"bytes": 1730052,
"sha256": "2173ea00107237f320ab249a6fcde0ec616421aa09d6c274ef563e9974b47e6e"
},
"08-lane-tests/command/output.log": {
"bytes": 670,
"sha256": "1b3cc48bee9bb4d564f0479a692b7b20fa6df5da3b8dccfda5d1487b6b93f53e"
},
"08-lane-tests/command/result.json": {
"bytes": 4121,
"sha256": "9a48e66ce638944e885e708b3f361ce2d099352e154536a46fafa6bca49af12f"
},
"08-lane-tests/command/stderr.log": {
"bytes": 304,
"sha256": "c534ac6e8df5add7c08f663cd516b9a0da947a93127ebda6c378ede9bd42f575"
},
"08-lane-tests/environment.json": {
"bytes": 9463,
"sha256": "14e53dd6359601bdd9be3ad24c527fca96310d9eb4ffa91965f71841f8df2f82"
},
"08-lane-tests/orchestration.log": {
"bytes": 170,
"sha256": "bf1ebdbbdd1955bd7b874592340e3d79a48a145a9b39faec898aaa807133f81a"
},
"09-penalty-lanes-probe/command/changes.patch": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"09-penalty-lanes-probe/command/context.json": {
"bytes": 3502,
"sha256": "4c95894559f60d51fda0e2af09b2ec66abf9dc687d623c1e67c9e042747d0084"
},
"09-penalty-lanes-probe/command/inputs-after.json": {
"bytes": 1730052,
"sha256": "2173ea00107237f320ab249a6fcde0ec616421aa09d6c274ef563e9974b47e6e"
},
"09-penalty-lanes-probe/command/inputs-before.json": {
"bytes": 1730052,
"sha256": "2173ea00107237f320ab249a6fcde0ec616421aa09d6c274ef563e9974b47e6e"
},
"09-penalty-lanes-probe/command/output.log": {
"bytes": 371062,
"sha256": "04bb9ba4ab551a965cea130510cca6b96d9c1012911f191b14a7aa7efbf563dd"
},
"09-penalty-lanes-probe/command/result.json": {
"bytes": 4166,
"sha256": "538aa79bcedd4cf646c63d5309ec738be4676e2045715db1035a4f334a536117"
},
"09-penalty-lanes-probe/command/stderr.log": {
"bytes": 279,
"sha256": "126be48ed1535d641835bd72b6fc5aa05a9a2120dd2012daa3e30108eb1703e2"
},
"09-penalty-lanes-probe/environment.json": {
"bytes": 9463,
"sha256": "14e53dd6359601bdd9be3ad24c527fca96310d9eb4ffa91965f71841f8df2f82"
},
"09-penalty-lanes-probe/orchestration.log": {
"bytes": 179,
"sha256": "4e398b4fed1ac76d6bd61cb18fe2c50cae2764f040d878006e464c5728428cd3"
},
"10-lanes-core-tests/command/changes.patch": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"10-lanes-core-tests/command/context.json": {
"bytes": 3655,
"sha256": "2ee756c13c33bccf0cb7c87492bb62be5d5203044a066af0af36389059b2181c"
},
"10-lanes-core-tests/command/inputs-after.json": {
"bytes": 1730052,
"sha256": "27af33c77ce384358dfbd8a6730d2eff7399575fb1cacbb2c338eaa441e5db91"
},
"10-lanes-core-tests/command/inputs-before.json": {
"bytes": 1730052,
"sha256": "27af33c77ce384358dfbd8a6730d2eff7399575fb1cacbb2c338eaa441e5db91"
},
"10-lanes-core-tests/command/output.log": {
"bytes": 19032,
"sha256": "bde8202db1c2f3f407a7dcbf6a1184830d0914e2bbba0e5f7cbd2c55d72d56b4"
},
"10-lanes-core-tests/command/result.json": {
"bytes": 4312,
"sha256": "828871867eb7ff0ccfd5953a694ae594ae145e89bf2eca831368297d1ea9b874"
},
"10-lanes-core-tests/command/stderr.log": {
"bytes": 990,
"sha256": "df86da47eb1884669f1d0ce14107713ea9afd9e3cbb68becf451a018a1bf7303"
},
"10-lanes-core-tests/environment.json": {
"bytes": 9463,
"sha256": "14e53dd6359601bdd9be3ad24c527fca96310d9eb4ffa91965f71841f8df2f82"
},
"10-lanes-core-tests/orchestration.log": {
"bytes": 176,
"sha256": "6a2f55638fd26b60333bcd61cc1faaa29baaf9041962cbc1cfacd762bfc933e5"
},
"11-lanes-probe/command/changes.patch": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"11-lanes-probe/command/context.json": {
"bytes": 3494,
"sha256": "d8ec80836b09c1859b7d482dbd2ebb0243495be3e022ce2cb5dcc5c47e9464bf"
},
"11-lanes-probe/command/inputs-after.json": {
"bytes": 1730052,
"sha256": "27af33c77ce384358dfbd8a6730d2eff7399575fb1cacbb2c338eaa441e5db91"
},
"11-lanes-probe/command/inputs-before.json": {
"bytes": 1730052,
"sha256": "27af33c77ce384358dfbd8a6730d2eff7399575fb1cacbb2c338eaa441e5db91"
},
"11-lanes-probe/command/output.log": {
"bytes": 371182,
"sha256": "64232f580600b7a874a6f4ceb128a6188fd5ff72655bc6b93d824ebed27ffb7d"
},
"11-lanes-probe/command/result.json": {
"bytes": 4142,
"sha256": "feee84c2fde115c22ea865033ff2d136da2aace1f1c8a7423c8add11358366a8"
},
"11-lanes-probe/command/stderr.log": {
"bytes": 278,
"sha256": "2e73f2722528e8f80b9e64f722643769e279d822835e9ea47e96cb07eaf51162"
},
"11-lanes-probe/environment.json": {
"bytes": 9463,
"sha256": "14e53dd6359601bdd9be3ad24c527fca96310d9eb4ffa91965f71841f8df2f82"
},
"11-lanes-probe/orchestration.log": {
"bytes": 171,
"sha256": "93c3867e1dc8b07314a7ac03db0d76b641eda2eaad1ad58a61914f1d6ec64794"
},
"12-lanes-clippy/command/changes.patch": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"12-lanes-clippy/command/context.json": {
"bytes": 3513,
"sha256": "eb644e36413cc55e61b7f6aa6162f7f17f21f67911123f951f1ed96c91b30430"
},
"12-lanes-clippy/command/inputs-after.json": {
"bytes": 1730052,
"sha256": "27af33c77ce384358dfbd8a6730d2eff7399575fb1cacbb2c338eaa441e5db91"
},
"12-lanes-clippy/command/inputs-before.json": {
"bytes": 1730052,
"sha256": "27af33c77ce384358dfbd8a6730d2eff7399575fb1cacbb2c338eaa441e5db91"
},
"12-lanes-clippy/command/output.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"12-lanes-clippy/command/result.json": {
"bytes": 4158,
"sha256": "ea20c2e64c26667f575b70b598a790aceb1804070c208e5f8f1dd7839e8b0a8f"
},
"12-lanes-clippy/command/stderr.log": {
"bytes": 177,
"sha256": "5e1eff044f676ea902db61f76e53375f034cc2cd33c8671a56d11dd4a2aa2936"
},
"12-lanes-clippy/environment.json": {
"bytes": 9463,
"sha256": "14e53dd6359601bdd9be3ad24c527fca96310d9eb4ffa91965f71841f8df2f82"
},
"12-lanes-clippy/orchestration.log": {
"bytes": 172,
"sha256": "44d905169275ce11c8f66e16ce232d750f6b2701e6fb085880e9ad013219d18b"
},
"pl-geometry/authored_detour_and_label-after.png": {
"bytes": 12492,
"sha256": "44e30b94ef11b176155ab3df90fe5b52788c07442a42a355d3458fa904c147bd"
},
"pl-geometry/authored_detour_and_label-before.png": {
"bytes": 12468,
"sha256": "097588fae4fd6253c25ab4b60be1ad685ead3a3012b206f382cec0be1341e700"
},
"pl-geometry/authored_detour_and_label-experimental_candidate-metrics.png": {
"bytes": 13162,
"sha256": "82a07de168cda7dacdad2bd532dae408172466b2776acf8cfaabef6711c0539b"
},
"pl-geometry/authored_detour_and_label-reset_only_control-metrics.png": {
"bytes": 12777,
"sha256": "e676edc49ec6ebb2fe29e976c36cba589f76330e7f9eb27b8835415a2ed5d225"
},
"pl-geometry/chain_7_row_wrap-after.png": {
"bytes": 14271,
"sha256": "a020c1535e3d6e48cb5e6d7ae8403a256767c68ce26876fd773f3b626c61e365"
},
"pl-geometry/chain_7_row_wrap-before.png": {
"bytes": 13771,
"sha256": "0b282cbd29eb3e29fa7d3bb9c3c9746caa14c77372b3191d78fa1a60743d0b11"
},
"pl-geometry/chain_7_row_wrap-experimental_candidate-metrics.png": {
"bytes": 14396,
"sha256": "3ca042155d918083c5f4135ae059205b29b8ee5944819a6040a22eeb572f5f04"
},
"pl-geometry/chain_7_row_wrap-reset_only_control-metrics.png": {
"bytes": 14549,
"sha256": "8828f289159deb0c2bedd130495197639775cd8edeb561f0de5501e2980d1e1d"
},
"pl-geometry/crossed_bipartite-after.png": {
"bytes": 13163,
"sha256": "bb809e93b44e802d05430903cf397618fb901efdb6c5ab272574064e20641af6"
},
"pl-geometry/crossed_bipartite-before.png": {
"bytes": 13399,
"sha256": "9b7af6a43ec655cdcb05da49b5fffea661d4f5c9a5ae70a0c74c6e7696b066d3"
},
"pl-geometry/crossed_bipartite-experimental_candidate-metrics.png": {
"bytes": 13856,
"sha256": "c386b537f077f014e73e99831fdbb57e64ae9709a30afd2909dd50d7443c1899"
},
"pl-geometry/crossed_bipartite-reset_only_control-metrics.png": {
"bytes": 13368,
"sha256": "bdcf079498dc2dce5245e47eac8038d736cea7af6176ada13bf682671c70b4b4"
},
"pl-geometry/diamond-after.png": {
"bytes": 12556,
"sha256": "6afcff1e5c10758e5eab3b803ec858d0af3da953be4af93df75257544a7252b2"
},
"pl-geometry/diamond-before.png": {
"bytes": 13228,
"sha256": "38e341a1ed51d4b4a94513f34c3d48b05c72177dcc3792dc660cb780fd7f98c9"
},
"pl-geometry/diamond-experimental_candidate-metrics.png": {
"bytes": 13555,
"sha256": "a61d178e2cd3fcff8fc4ed3c42e5ab71b042d26d776f59fe5eaadb3ef8481e5e"
},
"pl-geometry/diamond-reset_only_control-metrics.png": {
"bytes": 12982,
"sha256": "48414d7a859c774f2cef51d0fc1512b1c9fe1540c540f96fac7f9531583d8731"
},
"pl-geometry/fixed_ports-after.png": {
"bytes": 11889,
"sha256": "574cb0249c3bcc3140b9d61906332295a8462e32fbcd6b9526d8b05e202e38a0"
},
"pl-geometry/fixed_ports-before.png": {
"bytes": 12013,
"sha256": "d07ef2105aa63f3aaacb19e9a7ca4960239b01f05f734baa6270657a465b4ab0"
},
"pl-geometry/fixed_ports-experimental_candidate-metrics.png": {
"bytes": 12394,
"sha256": "d7fdcd7d4a1a014dd34243400dcd74a7596388fc5747853e5a6629535ca3083e"
},
"pl-geometry/fixed_ports-reset_only_control-metrics.png": {
"bytes": 12231,
"sha256": "237e181db92baf49c24554ec4325137b014413603b62cb08dee63e6e68fa3e8d"
},
"pl-geometry/flat_chain_4-after.png": {
"bytes": 12582,
"sha256": "7326cd482a61bea4cb787770449253a55f41e102794c8fc6a8500d9244c20cc7"
},
"pl-geometry/flat_chain_4-before.png": {
"bytes": 12723,
"sha256": "b086e2b23d4b68cb43366725a26fbb39fdc2e87d18cd7109c9b3ec950ab665ba"
},
"pl-geometry/flat_chain_4-experimental_candidate-metrics.png": {
"bytes": 13405,
"sha256": "3bb352dd5066a3b2cc5bb298c9f47a02416186421df4841b96c944e523d11104"
},
"pl-geometry/flat_chain_4-reset_only_control-metrics.png": {
"bytes": 12918,
"sha256": "eba3eede6771a1ebfc7b773b48b599f5ca49613ad7444ab26acfea7d20dde515"
},
"pl-geometry/long_ordinary_labels-after.png": {
"bytes": 12643,
"sha256": "f4f0c360e9ce44d631dd1d9f7c202954be943fdbede6288edbaddf9b890fcaec"
},
"pl-geometry/long_ordinary_labels-before.png": {
"bytes": 12661,
"sha256": "3c17c1195337cda7cd4141a15428b66cac1475421600b6ecffc3db57dbfd9f94"
},
"pl-geometry/long_ordinary_labels-experimental_candidate-metrics.png": {
"bytes": 13235,
"sha256": "d2931b576901fec68b23afd1a54d4c301eda4a75ba30184344749e0add277bc0"
},
"pl-geometry/long_ordinary_labels-reset_only_control-metrics.png": {
"bytes": 12969,
"sha256": "68aacc7196a4995ff8a884a15ec91a31bd386bdd2d232fd2c27696a7f83cf791"
},
"pl-geometry/manifest.json": {
"bytes": 8099,
"sha256": "dc9c09882d841e6ba050caabf411de8dd0e868879fe8f0b7a1b44cece9ffde8b"
},
"pl-geometry/nested_cross_boundary-after.png": {
"bytes": 13344,
"sha256": "51db6785ab89f5d92c61288604ae3c76aee467e291738b54466db5704c0eec8b"
},
"pl-geometry/nested_cross_boundary-before.png": {
"bytes": 13547,
"sha256": "3b3963f5ef5a42106a006f1825ae5d85b722aa3bf163452ba986ef3369b57cc2"
},
"pl-geometry/nested_cross_boundary-experimental_candidate-metrics.png": {
"bytes": 13535,
"sha256": "0ba365785753e748dc7c86c3f1eb5767f9ccb87c0ae0e18085e6a9d32b79f60d"
},
"pl-geometry/nested_cross_boundary-reset_only_control-metrics.png": {
"bytes": 13549,
"sha256": "fbe21b57616459ecdbbd083dccd73bd120f5b7ad59a8ad80ea38cbbf9c3f49c1"
},
"pl-geometry/two_containers_reversed_children-after.png": {
"bytes": 13957,
"sha256": "b0911f8afb39313e6ce43661396d6553276d5db53c659937acf87252ed502c6e"
},
"pl-geometry/two_containers_reversed_children-before.png": {
"bytes": 14083,
"sha256": "2d42d34af4674bbf1739e85967d743e6fc78c117ef1e7645724c504b006ee881"
},
"pl-geometry/two_containers_reversed_children-experimental_candidate-metrics.png": {
"bytes": 14500,
"sha256": "8a0744cf04d305a0431468395b3676604e03991e577f9f9d2f45e8497b1ef9ca"
},
"pl-geometry/two_containers_reversed_children-manual_planar_order_witness-metrics.png": {
"bytes": 14531,
"sha256": "60623d358d9cb930c2c2c4995c9286c653e597c411b8879b77ac099fe9b0406b"
},
"pl-geometry/two_containers_reversed_children-reset_only_control-metrics.png": {
"bytes": 14136,
"sha256": "f690678d5697cbec20e64bf92a128a8fd3a1dffe3948fcbe75ad99a4f33de96d"
},
"support/auto-layout-pl-comparison-20260925.json": {
"bytes": 75815,
"sha256": "81f57e651a8840aaaeacc085df2eb90174b2e494182f6cd40ccd6d50e7bb531e"
},
"support/auto-layout-pl-contact-audit-20260925.json": {
"bytes": 103918,
"sha256": "60ce7e9735ceef50a92d29a0414aafe3d8fb6174dab99eff6397e2abc88e0afa"
},
"support/auto-layout-pl-binary-20260925.json": {
"bytes": 220,
"sha256": "00f0ceb0e92a156de2d870e32b1d57d88465e5acedd9c5f5e733f183a750c46e"
},
"l-geometry/authored_detour_and_label-after.png": {
"bytes": 12492,
"sha256": "44e30b94ef11b176155ab3df90fe5b52788c07442a42a355d3458fa904c147bd"
},
"l-geometry/authored_detour_and_label-before.png": {
"bytes": 12468,
"sha256": "097588fae4fd6253c25ab4b60be1ad685ead3a3012b206f382cec0be1341e700"
},
"l-geometry/authored_detour_and_label-experimental_candidate-metrics.png": {
"bytes": 13162,
"sha256": "82a07de168cda7dacdad2bd532dae408172466b2776acf8cfaabef6711c0539b"
},
"l-geometry/authored_detour_and_label-reset_only_control-metrics.png": {
"bytes": 12777,
"sha256": "e676edc49ec6ebb2fe29e976c36cba589f76330e7f9eb27b8835415a2ed5d225"
},
"l-geometry/chain_7_row_wrap-after.png": {
"bytes": 14271,
"sha256": "a020c1535e3d6e48cb5e6d7ae8403a256767c68ce26876fd773f3b626c61e365"
},
"l-geometry/chain_7_row_wrap-before.png": {
"bytes": 13771,
"sha256": "0b282cbd29eb3e29fa7d3bb9c3c9746caa14c77372b3191d78fa1a60743d0b11"
},
"l-geometry/chain_7_row_wrap-experimental_candidate-metrics.png": {
"bytes": 14396,
"sha256": "3ca042155d918083c5f4135ae059205b29b8ee5944819a6040a22eeb572f5f04"
},
"l-geometry/chain_7_row_wrap-reset_only_control-metrics.png": {
"bytes": 14549,
"sha256": "8828f289159deb0c2bedd130495197639775cd8edeb561f0de5501e2980d1e1d"
},
"l-geometry/crossed_bipartite-after.png": {
"bytes": 13144,
"sha256": "54a1b5e983bc9b6f619e67c13173d0ff5000e30f080aaf6c0a9064f59036f4b7"
},
"l-geometry/crossed_bipartite-before.png": {
"bytes": 13399,
"sha256": "9b7af6a43ec655cdcb05da49b5fffea661d4f5c9a5ae70a0c74c6e7696b066d3"
},
"l-geometry/crossed_bipartite-experimental_candidate-metrics.png": {
"bytes": 13856,
"sha256": "c386b537f077f014e73e99831fdbb57e64ae9709a30afd2909dd50d7443c1899"
},
"l-geometry/crossed_bipartite-reset_only_control-metrics.png": {
"bytes": 13349,
"sha256": "0b2a8c49368258b23c15a8e06bf9b881f0e53fed8b5fd7d6f216a09837634abc"
},
"l-geometry/diamond-after.png": {
"bytes": 12556,
"sha256": "6afcff1e5c10758e5eab3b803ec858d0af3da953be4af93df75257544a7252b2"
},
"l-geometry/diamond-before.png": {
"bytes": 13228,
"sha256": "38e341a1ed51d4b4a94513f34c3d48b05c72177dcc3792dc660cb780fd7f98c9"
},
"l-geometry/diamond-experimental_candidate-metrics.png": {
"bytes": 13555,
"sha256": "a61d178e2cd3fcff8fc4ed3c42e5ab71b042d26d776f59fe5eaadb3ef8481e5e"
},
"l-geometry/diamond-reset_only_control-metrics.png": {
"bytes": 12982,
"sha256": "48414d7a859c774f2cef51d0fc1512b1c9fe1540c540f96fac7f9531583d8731"
},
"l-geometry/fixed_ports-after.png": {
"bytes": 11889,
"sha256": "574cb0249c3bcc3140b9d61906332295a8462e32fbcd6b9526d8b05e202e38a0"
},
"l-geometry/fixed_ports-before.png": {
"bytes": 12013,
"sha256": "d07ef2105aa63f3aaacb19e9a7ca4960239b01f05f734baa6270657a465b4ab0"
},
"l-geometry/fixed_ports-experimental_candidate-metrics.png": {
"bytes": 12394,
"sha256": "d7fdcd7d4a1a014dd34243400dcd74a7596388fc5747853e5a6629535ca3083e"
},
"l-geometry/fixed_ports-reset_only_control-metrics.png": {
"bytes": 12231,
"sha256": "237e181db92baf49c24554ec4325137b014413603b62cb08dee63e6e68fa3e8d"
},
"l-geometry/flat_chain_4-after.png": {
"bytes": 12582,
"sha256": "7326cd482a61bea4cb787770449253a55f41e102794c8fc6a8500d9244c20cc7"
},
"l-geometry/flat_chain_4-before.png": {
"bytes": 12723,
"sha256": "b086e2b23d4b68cb43366725a26fbb39fdc2e87d18cd7109c9b3ec950ab665ba"
},
"l-geometry/flat_chain_4-experimental_candidate-metrics.png": {
"bytes": 13405,
"sha256": "3bb352dd5066a3b2cc5bb298c9f47a02416186421df4841b96c944e523d11104"
},
"l-geometry/flat_chain_4-reset_only_control-metrics.png": {
"bytes": 12918,
"sha256": "eba3eede6771a1ebfc7b773b48b599f5ca49613ad7444ab26acfea7d20dde515"
},
"l-geometry/long_ordinary_labels-after.png": {
"bytes": 12643,
"sha256": "f4f0c360e9ce44d631dd1d9f7c202954be943fdbede6288edbaddf9b890fcaec"
},
"l-geometry/long_ordinary_labels-before.png": {
"bytes": 12661,
"sha256": "3c17c1195337cda7cd4141a15428b66cac1475421600b6ecffc3db57dbfd9f94"
},
"l-geometry/long_ordinary_labels-experimental_candidate-metrics.png": {
"bytes": 13235,
"sha256": "d2931b576901fec68b23afd1a54d4c301eda4a75ba30184344749e0add277bc0"
},
"l-geometry/long_ordinary_labels-reset_only_control-metrics.png": {
"bytes": 12969,
"sha256": "68aacc7196a4995ff8a884a15ec91a31bd386bdd2d232fd2c27696a7f83cf791"
},
"l-geometry/manifest.json": {
"bytes": 8099,
"sha256": "897b9d42b494bac1e5263a8bab42756c3038403948e6ac76028d86fd6e56ae20"
},
"l-geometry/nested_cross_boundary-after.png": {
"bytes": 13344,
"sha256": "51db6785ab89f5d92c61288604ae3c76aee467e291738b54466db5704c0eec8b"
},
"l-geometry/nested_cross_boundary-before.png": {
"bytes": 13547,
"sha256": "3b3963f5ef5a42106a006f1825ae5d85b722aa3bf163452ba986ef3369b57cc2"
},
"l-geometry/nested_cross_boundary-experimental_candidate-metrics.png": {
"bytes": 13535,
"sha256": "0ba365785753e748dc7c86c3f1eb5767f9ccb87c0ae0e18085e6a9d32b79f60d"
},
"l-geometry/nested_cross_boundary-reset_only_control-metrics.png": {
"bytes": 13549,
"sha256": "fbe21b57616459ecdbbd083dccd73bd120f5b7ad59a8ad80ea38cbbf9c3f49c1"
},
"l-geometry/two_containers_reversed_children-after.png": {
"bytes": 13957,
"sha256": "b0911f8afb39313e6ce43661396d6553276d5db53c659937acf87252ed502c6e"
},
"l-geometry/two_containers_reversed_children-before.png": {
"bytes": 14083,
"sha256": "2d42d34af4674bbf1739e85967d743e6fc78c117ef1e7645724c504b006ee881"
},
"l-geometry/two_containers_reversed_children-experimental_candidate-metrics.png": {
"bytes": 14500,
"sha256": "8a0744cf04d305a0431468395b3676604e03991e577f9f9d2f45e8497b1ef9ca"
},
"l-geometry/two_containers_reversed_children-manual_planar_order_witness-metrics.png": {
"bytes": 14531,
"sha256": "60623d358d9cb930c2c2c4995c9286c653e597c411b8879b77ac099fe9b0406b"
},
"l-geometry/two_containers_reversed_children-reset_only_control-metrics.png": {
"bytes": 14136,
"sha256": "f690678d5697cbec20e64bf92a128a8fd3a1dffe3948fcbe75ad99a4f33de96d"
},
"support/auto-layout-l-comparison-20260925.json": {
"bytes": 76659,
"sha256": "e1e23e6c2a50cd384457bb061d5b70a740f586f42767164fad9703ecbb4096a8"
},
"support/auto-layout-l-contact-audit-20260925.json": {
"bytes": 103893,
"sha256": "6f6cc674c27d3f43001fe1751ef3b09332caa9ddca396759f5525f811cbe1aaf"
},
"support/auto-layout-l-binary-20260925.json": {
"bytes": 220,
"sha256": "9c6d6e20c86237e5d1b917a981f2a5a8612d1c58b6e0706d4701e6c7cc59e06f"
},
"support/auto-layout-contact-audit-20260925.py": {
"bytes": 9838,
"sha256": "398b9677d2ef2333514dd9c1ba5bc2f020c9927f395ed33bf11ac59b68139f46"
},
"support/run-auto-layout-check-20260925.py": {
"bytes": 2771,
"sha256": "d652c4df47f13aefc723bc54362d7b61308b8983c8d39ae7721c012519358ea2"
},
"support/auto-layout-format-j-20260925.json": {
"bytes": 203,
"sha256": "5bd0e4b979aedf21bd38e4c41a1521dafffb78c3cccb61cd12dad56d4f4699e9"
},
"support/run.py": {
"bytes": 13814,
"sha256": "698ed7182726c77fa4a1c85fc6dd08187ed20689941f57e749e3f0bc845f3252"
}
},
"archive": {
"name": "lanes-e8ec6db.zip",
"bytes": 3518507,
"sha256": "5512b4cbd99e3bf03eb975e25fb980f7b1a95a5cb19f3687fb3d6d83d1839e8f"
}
}
@@ -0,0 +1 @@
* -text whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol
@@ -0,0 +1,223 @@
{
"source_commit": "3d7adff923dee5bed54dfdccc119dbee0c7c2773",
"scope": "Transient P coefficient3.0/cap80 experiment, not production acceptance or claim that J tests pass with P.",
"post_run_probe_binary": {
"bytes": 24156160,
"sha256": "8f3ac5aa1fa01be6a8ab664e8ae269f6527b8ffb7e326c2926c8fae7c3d7e366"
},
"members": {
"run/command/changes.patch": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"run/command/context.json": {
"bytes": 3504,
"sha256": "6f6019b2be69e12e3270d8570e9e4950c93e42e8b3093a0e0324a30f7e5eb0ff"
},
"run/command/inputs-after.json": {
"bytes": 1727969,
"sha256": "607febcd0d74d11deaa07a44b8b9cf6c382fd65d55deadb2d8ac7e889797dcf1"
},
"run/command/inputs-before.json": {
"bytes": 1727969,
"sha256": "607febcd0d74d11deaa07a44b8b9cf6c382fd65d55deadb2d8ac7e889797dcf1"
},
"run/command/output.log": {
"bytes": 371606,
"sha256": "13111fe89e4e637d1af572a8a45b8bdd763e94b58a2ec5ec6ca83e40ffa209c7"
},
"run/command/result.json": {
"bytes": 4172,
"sha256": "6149122d05d77e02b463edb3dd359b06786bc4468c27d8cd625cbc1bc80c9894"
},
"run/command/stderr.log": {
"bytes": 279,
"sha256": "fe5d8d303700ef5b92bfaa95ac1f99a2214e1fc5f6c5ac8d83f6303aa258965b"
},
"run/environment.json": {
"bytes": 9463,
"sha256": "14e53dd6359601bdd9be3ad24c527fca96310d9eb4ffa91965f71841f8df2f82"
},
"run/orchestration.log": {
"bytes": 181,
"sha256": "db5af22d893966919b9342fd06b99e7e1c82c5c87593544b7762cc85f9a7e45a"
},
"geometry/authored_detour_and_label-after.png": {
"bytes": 12492,
"sha256": "44e30b94ef11b176155ab3df90fe5b52788c07442a42a355d3458fa904c147bd"
},
"geometry/authored_detour_and_label-before.png": {
"bytes": 12468,
"sha256": "097588fae4fd6253c25ab4b60be1ad685ead3a3012b206f382cec0be1341e700"
},
"geometry/authored_detour_and_label-experimental_candidate-metrics.png": {
"bytes": 13162,
"sha256": "82a07de168cda7dacdad2bd532dae408172466b2776acf8cfaabef6711c0539b"
},
"geometry/authored_detour_and_label-reset_only_control-metrics.png": {
"bytes": 12777,
"sha256": "e676edc49ec6ebb2fe29e976c36cba589f76330e7f9eb27b8835415a2ed5d225"
},
"geometry/chain_7_row_wrap-after.png": {
"bytes": 14271,
"sha256": "a020c1535e3d6e48cb5e6d7ae8403a256767c68ce26876fd773f3b626c61e365"
},
"geometry/chain_7_row_wrap-before.png": {
"bytes": 13771,
"sha256": "0b282cbd29eb3e29fa7d3bb9c3c9746caa14c77372b3191d78fa1a60743d0b11"
},
"geometry/chain_7_row_wrap-experimental_candidate-metrics.png": {
"bytes": 14396,
"sha256": "3ca042155d918083c5f4135ae059205b29b8ee5944819a6040a22eeb572f5f04"
},
"geometry/chain_7_row_wrap-reset_only_control-metrics.png": {
"bytes": 14549,
"sha256": "8828f289159deb0c2bedd130495197639775cd8edeb561f0de5501e2980d1e1d"
},
"geometry/crossed_bipartite-after.png": {
"bytes": 13144,
"sha256": "54a1b5e983bc9b6f619e67c13173d0ff5000e30f080aaf6c0a9064f59036f4b7"
},
"geometry/crossed_bipartite-before.png": {
"bytes": 13413,
"sha256": "8622726dfdfc01e93fcd2d9d22c6d082e5a169b9dcd59f788e876954431214fd"
},
"geometry/crossed_bipartite-experimental_candidate-metrics.png": {
"bytes": 13855,
"sha256": "e3cc0a326a2c8b577e40101c5f67ea9c3182bca6d3f0498cdc1f25a64df57b90"
},
"geometry/crossed_bipartite-reset_only_control-metrics.png": {
"bytes": 13349,
"sha256": "0b2a8c49368258b23c15a8e06bf9b881f0e53fed8b5fd7d6f216a09837634abc"
},
"geometry/diamond-after.png": {
"bytes": 12556,
"sha256": "6afcff1e5c10758e5eab3b803ec858d0af3da953be4af93df75257544a7252b2"
},
"geometry/diamond-before.png": {
"bytes": 13228,
"sha256": "38e341a1ed51d4b4a94513f34c3d48b05c72177dcc3792dc660cb780fd7f98c9"
},
"geometry/diamond-experimental_candidate-metrics.png": {
"bytes": 13555,
"sha256": "a61d178e2cd3fcff8fc4ed3c42e5ab71b042d26d776f59fe5eaadb3ef8481e5e"
},
"geometry/diamond-reset_only_control-metrics.png": {
"bytes": 12982,
"sha256": "48414d7a859c774f2cef51d0fc1512b1c9fe1540c540f96fac7f9531583d8731"
},
"geometry/fixed_ports-after.png": {
"bytes": 11889,
"sha256": "574cb0249c3bcc3140b9d61906332295a8462e32fbcd6b9526d8b05e202e38a0"
},
"geometry/fixed_ports-before.png": {
"bytes": 12013,
"sha256": "d07ef2105aa63f3aaacb19e9a7ca4960239b01f05f734baa6270657a465b4ab0"
},
"geometry/fixed_ports-experimental_candidate-metrics.png": {
"bytes": 12394,
"sha256": "d7fdcd7d4a1a014dd34243400dcd74a7596388fc5747853e5a6629535ca3083e"
},
"geometry/fixed_ports-reset_only_control-metrics.png": {
"bytes": 12231,
"sha256": "237e181db92baf49c24554ec4325137b014413603b62cb08dee63e6e68fa3e8d"
},
"geometry/flat_chain_4-after.png": {
"bytes": 12582,
"sha256": "7326cd482a61bea4cb787770449253a55f41e102794c8fc6a8500d9244c20cc7"
},
"geometry/flat_chain_4-before.png": {
"bytes": 12723,
"sha256": "b086e2b23d4b68cb43366725a26fbb39fdc2e87d18cd7109c9b3ec950ab665ba"
},
"geometry/flat_chain_4-experimental_candidate-metrics.png": {
"bytes": 13405,
"sha256": "3bb352dd5066a3b2cc5bb298c9f47a02416186421df4841b96c944e523d11104"
},
"geometry/flat_chain_4-reset_only_control-metrics.png": {
"bytes": 12918,
"sha256": "eba3eede6771a1ebfc7b773b48b599f5ca49613ad7444ab26acfea7d20dde515"
},
"geometry/long_ordinary_labels-after.png": {
"bytes": 12643,
"sha256": "f4f0c360e9ce44d631dd1d9f7c202954be943fdbede6288edbaddf9b890fcaec"
},
"geometry/long_ordinary_labels-before.png": {
"bytes": 12661,
"sha256": "3c17c1195337cda7cd4141a15428b66cac1475421600b6ecffc3db57dbfd9f94"
},
"geometry/long_ordinary_labels-experimental_candidate-metrics.png": {
"bytes": 13235,
"sha256": "d2931b576901fec68b23afd1a54d4c301eda4a75ba30184344749e0add277bc0"
},
"geometry/long_ordinary_labels-reset_only_control-metrics.png": {
"bytes": 12969,
"sha256": "68aacc7196a4995ff8a884a15ec91a31bd386bdd2d232fd2c27696a7f83cf791"
},
"geometry/manifest.json": {
"bytes": 8099,
"sha256": "c1b59384878e519efec99757efee571635f30d814247db2f183eebbf9c467a0f"
},
"geometry/nested_cross_boundary-after.png": {
"bytes": 13344,
"sha256": "51db6785ab89f5d92c61288604ae3c76aee467e291738b54466db5704c0eec8b"
},
"geometry/nested_cross_boundary-before.png": {
"bytes": 13547,
"sha256": "3b3963f5ef5a42106a006f1825ae5d85b722aa3bf163452ba986ef3369b57cc2"
},
"geometry/nested_cross_boundary-experimental_candidate-metrics.png": {
"bytes": 13535,
"sha256": "0ba365785753e748dc7c86c3f1eb5767f9ccb87c0ae0e18085e6a9d32b79f60d"
},
"geometry/nested_cross_boundary-reset_only_control-metrics.png": {
"bytes": 13549,
"sha256": "fbe21b57616459ecdbbd083dccd73bd120f5b7ad59a8ad80ea38cbbf9c3f49c1"
},
"geometry/two_containers_reversed_children-after.png": {
"bytes": 13955,
"sha256": "1722ff21eaadd831e00b2176d61f8fa65b083d2fd5b633a196a3335d48ca125e"
},
"geometry/two_containers_reversed_children-before.png": {
"bytes": 14092,
"sha256": "dcbc521b8e5efd6a201da8a724ed218a9f1331a8abb2eda299a5807828037cb9"
},
"geometry/two_containers_reversed_children-experimental_candidate-metrics.png": {
"bytes": 14500,
"sha256": "8a0744cf04d305a0431468395b3676604e03991e577f9f9d2f45e8497b1ef9ca"
},
"geometry/two_containers_reversed_children-manual_planar_order_witness-metrics.png": {
"bytes": 14531,
"sha256": "60623d358d9cb930c2c2c4995c9286c653e597c411b8879b77ac099fe9b0406b"
},
"geometry/two_containers_reversed_children-reset_only_control-metrics.png": {
"bytes": 14134,
"sha256": "ce6bc93dc38fe5b25552c8ebc5e778da175df53992e6a70ded8377fd99372587"
},
"support/auto-layout-p-comparison-20260925.json": {
"bytes": 77494,
"sha256": "9f228fbe78e1888c5d93e87dddd8d2effc01bab723929a87423c61e23f5cad66"
},
"support/auto-layout-p-contact-audit-20260925.json": {
"bytes": 104912,
"sha256": "6f4add5c81f6d16c45efabbefd9e36c9beb637b6823993f0d51adc3e20485ad9"
},
"support/auto-layout-contact-audit-20260925.py": {
"bytes": 9838,
"sha256": "398b9677d2ef2333514dd9c1ba5bc2f020c9927f395ed33bf11ac59b68139f46"
},
"support/run-auto-layout-check-20260925.py": {
"bytes": 2771,
"sha256": "d652c4df47f13aefc723bc54362d7b61308b8983c8d39ae7721c012519358ea2"
},
"support/run.py": {
"bytes": 13814,
"sha256": "698ed7182726c77fa4a1c85fc6dd08187ed20689941f57e749e3f0bc845f3252"
}
},
"archive": {
"name": "penalty-3d7adff.zip",
"bytes": 916568,
"sha256": "6b819b01c8012aa72d423443f4dc04ae261f1ee9dc6907f0063c219ff173ad36"
}
}
@@ -0,0 +1,19 @@
# Boundary-order conservation review
Read-only audit of `.local/boundary-order-20260925/run01`, source `3e21c1bca245944ae0ec7bb02aaa920f45f2cc30`. No compiler, router, engine or native execution. Twenty boundary candidates are supported; zero unsupported cases. Fourteen current SCC controls and six paired extra-fixture baselines are accounted for separately, not counted as additional boundary cases.
Independent complete-Project reconstruction passes for all20 boundary candidates,14 controls and6 paired baselines. Reconstruction starts from raw original Project, resolves actual endpoint owners and preoperation reset eligibility, retains entire semantic/nongeometry structures, applies only permitted visible geometry/minimum restoration and hidden-owner translation, and compares the entire expected result. No conservation boolean substitutes for this comparison. All66 receipt hash/byte-size bindings read back exactly.
All14 current SCC-control Projects equal their prior SCCrun02 Projects exactly. All20 successful boundary/baseline pairs retain exact effective node sizes, per-group SCC membership/rank/canonical walk/grid/gaps, and rigid internal SCC geometry within0.001units. Eleven boundary Projects equal baseline completely. Nine differ: all six extra fixtures, two_containers_reversed_children, workshop original and workshop folded. Node positions are the intended variable; no semantic reparenting or new authored elbows are persisted.
Every authored port-anchor record, other diagram, route entry identity/order and nongeometry field remains exact. The only authored-route changes are the same three eligible waypoint/label resets (mixed, reversed mixed, authored_detour_and_label). No retained dormant/promoted authored-route translation or nonempty authored attachment coverage occurs; do not infer it from the checker implementing that policy. Folded workshop's three hidden descendants still independently follow Allocation/semantic ancestry under collapsed owner `75920e7a-4586-58b7-9eb2-7e0a3d8a1825` by(-680,0), preserving latent sizes/metadata. All checked non-State container enclosures/minima pass.
Automatic port changes are preserved, not normalized away: boundary_two_local_sccs has two side changes, owner`…000004`/port`…000026` Bottom→Right and owner`…00000a`/port`…00002a` Bottom→Left. Neither is authored. Every pair has identical projected port inventory; no other side changes were observed. These are actual projection results, not evidence that source anchor records changed.
All34 primary successful records report exact same-input output, all nine repeated calls2–10 equal first/previous, and exact JSON/single-source round trips. These remain recorded Rust checks: repeat Projects/source strings are not serialized for independent rerun. Exact intended node plans are absent; final-plan equality remains the source import gate. The audit independently checks final emitted projection, permissible full-Project deltas, component invariants and enclosures, not a second layout implementation. It does not validate renderer text, estimated label collision accuracy, trace readability, general native workflow or adoption.
Auditor: `.local/audit-boundary-conservation-20260925.py`, SHA256 `f14d96f7ee1487d245bd30436dea356df7524006c51f2fbac929b067b881d893`. Final result: `.local/boundary-conservation-audit-final-20260925.json`, SHA256 `f6a3fa93c03174e0eae6f816975f06a10a696659bd3fd58291ac805a69d5edee`. Raw paired rows are read directly and bound to original paths/hashes, with baseline selector attribution; no normalized copy is represented as runtime output.
The first audit output is preserved: it successfully checked conservation but grouped14 SCC controls with20 candidates and used prior baselines directly. Final checker explicitly labels those roles, compares controls to prior results and boundary cases to the current controls, while retaining six in-row baseline/boundary pairs. This is inventory/attribution refinement, not a suppressed model failure. Original SCC auditors/reviews were untouched.
Reproduce: `python audit-boundary-conservation-20260925.py RUN_DIRECTORY NEW_OUTPUT_JSON 3e21c1bca245944ae0ec7bb02aaa920f45f2cc30 PRIOR_SCC_RUN02_DIRECTORY`. UTF-8 is explicit; output refuses overwrite; only the Python checker executes.
@@ -0,0 +1,81 @@
# Boundary-order design critique
Local-only independent design review, 2026-09-25. Read source at `f4fa0c11f2271a93e324541e570ba391dce8122f` in `.local/auto-layout-20260925` and the SCC experiment's results, run02 quality review and transfer diagnosis. No implementation, build, router execution, GUI exercise or Gitea publication. The working tree was clean when inspected. This is a proposal and source-derived reasoning, not new empirical quality evidence.
## Recommendation
Use one deterministic sweep over the SCC condensation of **ordering dependencies between sibling groups**, starting from the complete canonical SCC plan. A dependency must represent every mutable ancestor ordering that can move an external source endpoint. Do not substitute source-parent dependencies, parent ID order, absolute-X order, or a fixed count of snapshot passes. Freeze the internal decision state of a cyclic dependency SCC: compute its members' proposed orders from one pre-SCC snapshot and commit all together. Explicitly document that cyclic dependencies can retain or exchange crossings; this is a bounded heuristic, not a cycle solver.
Preserve the existing semantic SCCs, ranks, member walks, perimeter offsets, block dimensions, gaps and root ordering. Repack the changed ordinal orders from the same block dimensions. Group envelopes are invariant under this operation; assert that fact instead of introducing a new enclosure growth pass. Import only the final plan using the existing exact projection and mandatory-lead guards. This adds precisely the information omitted by the current child-group planner while retaining the sparse structural witness.
The selected policy preserves same-rank undirected-connected bundles as indivisible ordering units with their canonical BFS internal order. A new external-order pass must not silently undo that proximity policy. Use visible endpoint centers as a declared heuristic, and retain final port/route checks; do not pretend center ordering proves attachment alignment or readability.
## Why the alternatives differ
| Candidate | Main benefit | Concrete weakness | Verdict |
| --- | --- | --- | --- |
| One canonical snapshot, incoming only | Smallest change; no mutation-order dependence; handles the two-container witness | A→B→C chain: B changes order to A, but C sorts against B's stale canonical order | Useful control, too weak as the preferred next candidate |
| Fixed number of snapshot passes | Carries influence farther without traversal code | Any fixed count has a longer-chain counterexample; cyclic groups may alternate; the pass count becomes an arbitrary hidden bound on quality | Reject as a generalization of old layered's three passes |
| Parent-ID or X/topological order using only parent relations | Cheap sequential propagation | Source descendants can later move under an ancestor ordering; ancestor-level SCC perimeter X does not express causality; unrelated ID changes select winners | Reject as the dependency definition |
| Complete ordering-dependency SCC sweep | Acyclic influence propagates once; explicit handling of genuine mutual dependence; bounded work | More bookkeeping; cyclic-SCC snapshot retains a declared limitation | Preferred bounded experiment |
| Joint crossing minimization or repeated barycenter optimization | Could optimize opposing constraints and port attachment geometry | Introduces a substantially different optimization problem, objectives and stopping policy before the simple witness is resolved | Defer until evidence defeats the bounded structural candidate |
Incoming-only treatment is meaningful because it anchors downstream order to upstream arrangement. It does not by itself remove cycles: two containers can each have an incoming edge from the other even when their internal child graphs are edgeless. The SCC used for ordering dependencies is distinct from the sibling-subtree semantic SCC already used for rank and perimeter placement. Never merge these concepts or feed ordering dependencies into semantic ranks.
## Precise candidate contract
1. Run the existing canonical planner to an in-memory plan. Keep a record for each sibling group of its SCC blocks, ranks, canonical ordinal order, dimensions, cut gaps and member offsets. Keep the root order fixed. Record a complete canonical absolute-position snapshot without importing an intermediate Project.
2. A target ordering group G is the children of a visible, noncollapsed parent P. An eligible boundary signal is an oriented **projected** edge for which the target lifts to a child of P and the source does not lift to any child of P. Internal-group incoming links are not boundary signals; outgoing and undirected boundary links supply no ordering signal in this candidate. An edge to a hidden endpoint uses its actual projected promoted endpoint, never the latent hidden placement.
3. The unit that moves is an SCC block, or an explicitly defined contiguous undirected-connected bundle of same-rank blocks. If bundle support is deferred, freeze layers with any such cross-block undirected link and report the reason. Do not break an SCC or reorder its perimeter members. A unit is anchored when at least one eligible incoming boundary signal targets one of its members or visible descendants.
4. For each same-rank layer, preserve the canonical ordinal indices occupied by unanchored units. Sort anchored units only into the remaining indices, by the arithmetic mean of their external source endpoint centers' absolute Y coordinates, followed by the existing canonical unit key. Deduplicate external visible source placement IDs per unit; several ports or parallel relations from one source owner contribute once. Sort those placement IDs independently of relation IDs, accumulate in f64, and reject nonfinite values. This is a declared source-owner weighting policy: relation multiplicity does not increase influence. This score is a center-based ordering heuristic, not a crossing objective.
5. Build a dependency graph whose vertices are the nonroot ordering groups that can alter an order. For every eligible signal consumed by G from visible source S, add H→G for **every** mutable group H whose child subtree contains S. In other words, include all ancestor ordering transforms that can change S's absolute position, not merely S's immediate sibling group. A collapsed visible source has no visible interior ordering group; its visible ancestors still matter. Conservative extra dependencies are permissible if reported, but may enlarge SCCs and freeze useful propagation.
6. Condense that graph. Process dependency SCCs in deterministic topological order. Before each SCC, reconstruct a complete absolute-position snapshot from the current relative offsets. All groups inside that SCC read this same snapshot, calculate proposed orders, then commit their orders together. Acyclic singleton SCCs therefore observe completed upstream changes; cyclic SCCs take one simultaneous bounded step. Independent ready SCCs cannot influence each other's consumed sources by construction, but use the canonical key to make diagnostics reproducible.
7. After committing an order, repack by prefix sums of the unchanged block heights and unchanged gaps. Preserve rank X origins and internal block/member offsets. Recompose absolute descendant positions from all relevant relative transforms. Do not move only the source node while leaving its descendants behind.
8. Assert every group's planned envelope and every block size equal their canonical values. Assemble one final complete plan and call the existing importer once. Keep original-to-final route translation, eligible reset, dormant-route preservation, authored anchors, hidden translations, semantic conservation and exact second-projection rules unchanged. A final projection mismatch or incompatible mandatory lead remains a refusal, not permission to grow sizes or iterate.
Two useful simplifications: source-center ordering does not require target-ancestor-before-descendant execution, since a target ancestor's translation does not change the order of consumed external source values. Explicit source-influence dependencies plus absolute coordinate recomposition are sufficient. Also, arbitrary intermediate geometry within a dependency SCC need never be externally visible: compute its decisions before committing any of them.
## Important limits and traps
**Ordinal slots are not fixed Y coordinates.** If an 80-high and 200-high block trade old Y coordinates, they can overlap. Preserve ordinal indices, then recalculate packed Y values using the unchanged heights. The layer envelope is nevertheless unchanged: height is the same sum of heights plus gaps, and width is the same maximum. Every ancestor enclosure is consequently unchanged by induction, even for nested containers. Nested size feedback is not inherent in this permutation stage.
**Automatic port projection remains geometry dependent.** Rearrangement may select different automatic sides or put more ports onto a side, increasing projected size beyond the frozen plan. Derived enclosure invariance does not exclude that. The exact final projection and lead checks must catch it. Preserve explicit port-side and fraction metadata. A center-based score may worsen actual fixed-port endpoint order; inspect routed outcomes and include that counterexample in evaluation.
**Determinism differs from idempotence.** Complete canonical reconstruction plus deterministic dependency processing gives same-input determinism. It does not prove repeated-call equality because the next input's effective minima may include stored enclosure repairs or new side-capacity minima. Existing repeated-call checks must remain, including nested automatic-port cases, and must compare complete Projects. Do not justify a failed repeat by saying that the ordering graph is deterministic.
**Canonical choice is a policy, not evidence of quality.** Alias and placement-ID keys are defensible tie breakers already present in this experiment. They imply sensitivity to alias changes and duplicate-alias placement IDs. Relation-ID permutation should not change geometry or scores. Full graph-isomorphism invariance is neither supplied by the current planner nor established by this proposal. Diagnostics should distinguish a canonical tie from a strict source-derived ordering decision.
**Cyclic dependency SCCs have no guaranteed winner.** Simultaneous calculation is independent of group traversal order, but opposing permutations may both reverse and remain crossed. Freezing canonical order for cyclic SCCs is a still more conservative alternative if the corpus shows worsening; predeclare which policy is being tested. Do not quietly select between the two after routing each fixture. Sequential execution within a cyclic SCC merely chooses an arbitrary winner and is not a resolution of the constraints.
**Non-singleton target blocks weaken the center proxy.** Two SCCs can receive edges into different perimeter rows. Mean external-source center ignores target member offsets, so it can place their block centers in an order that crosses the actual connections. An offset-adjusted score would be a different candidate and would introduce dependencies on target descendants as well. Keep this limitation explicit and use a cyclic-block target fixture; do not add that refinement without a separate reason and specification.
**External order can conflict with internal rank order.** The current canonical pass already uses preceding-rank proximity. Overriding its same-rank order from boundary neighbors can increase internal crossings. A fixture must include this conflict, and evaluation must retain all internal and external routes. Success on one reversed-child witness is insufficient.
## Falsifying fixtures and acceptance evidence
- Preserve the frozen 14 cases and exact complete sparse candidate geometry/metrics. The targeted two-container witness should reach zero shared length and zero label/node collisions like old layered, without semantic, port, fold or import regression; report the whole quality vector rather than only that target.
- Three containers A→B→C, two matched channels, chosen aliases giving differing canonical child orders. A second version with a longer chain distinguishes an actual dependency sweep from a fixed snapshot-pass count. Verify final channel alignment and dependency order from emitted plans, not just zero process exit.
- Ancestor influence: an ordering group moves a container holding an external source whose own immediate child group does not reorder; that source feeds a different target group. The target must consume the source's updated absolute Y. Reverse container IDs to expose accidental iteration dependencies.
- Opposing incoming constraints between two containers; a three-container directed cycle; and an acyclic semantic graph whose container grouping induces a dependency cycle. Confirm the declared cyclic policy and same-input determinism, and report unresolved crossings rather than claiming all cycles solved.
- Heterogeneous block heights with an unanchored block between two anchored blocks. Require unanchored ordinal-slot preservation, no overlap, exact unchanged total envelope and deterministic packing. Repeat with nested containers and a multirow SCC.
- A same-rank chain of undirected-connected blocks plus externally anchored endpoints, and a purely undirected cross-container fixture. Require the declared bundle/freeze policy, no invented directed arcs/ranks and no silent loss of existing contiguity.
- An internal diamond or fan-out whose canonical target order is good but boundary signals prefer its reverse. Detect improvement to the boundary at the cost of internal tracing.
- Fixed ports with source-center order opposite to port-attachment Y order; many automatic ports near a side-choice/capacity threshold. Require exact model-anchor preservation and final projection acceptance or clean refusal, never size chasing.
- A collapsed source container promoting hidden edges; nested collapsed descendants; and a surviving dormant authored route. Require only visible geometry to influence ordering, hidden translation with owner, and the existing route/reset conservation contract.
- Parallel boundary relations and a relation-ID permutation with identical endpoints; equal mean scores; repeated invocation; JSON/text round trips. Require exact geometry determinism under relation-ID changes and exact repeated Projects. Route relation-ID sensitivity remains a separate existing router limitation.
The existing full corpus remains the primary comparative experiment. These small synthetic fixtures test the candidate's mechanism and claimed invariants. No compilation result, small-corpus metric or this design review establishes native usability, production Arrange integration, or release acceptance.
## Final selected-policy review
The parent's final proposal adopts indivisible undirected-connected bundles, deduplicated visible source owners, active groups only when some band has at least two anchored units, source-ancestor dependencies only, and one simultaneous pre-SCC snapshot for each cyclic dependency SCC. I find no material correctness flaw in that bounded contract, provided the following definitions are implemented literally:
- A source owner is the projected edge's visible source **placement ID**, not a semantic element ID or unprojected port owner. Distinct visible placements remain distinct observations; promoted endpoints contribute their visible owner.
- The source influence chain includes the ordering group immediately containing the source placement, and every higher active ordering group that can move it. It must not start one level too high.
- Bundle order is preserved by ordinal slot, then prefix-height packing; old absolute Y coordinates are not reused for differently sized blocks.
- Before an SCC computes scores, all source absolute coordinates are recomposed from the current full offset map. All its proposals are calculated before any are committed.
- Work charging and diagnostic bounds include ancestor-chain discovery, dependency SCC processing, source-set accumulation and absolute-coordinate recomposition.
Active-group restriction is sound for this contract: fewer than two anchored units cannot change order because unanchored unit slots are preserved. Unchanged active groups can conservatively remain dependencies. No extra hierarchy edges are necessary.
The important remaining risks are empirical: cyclic dependencies may preserve or exchange crossings, source-center order can disagree with fixed-port/perimeter attachment order, deduplicated owners intentionally ignore connection multiplicity, and boundary preference can worsen internal rank tracing. Keep those limitations and the chain/ancestor influence fixtures above. Exact repeated-call stability and final automatic-port projection remain acceptance checks, not consequences of the ordering proof.
@@ -0,0 +1,46 @@
# Independent boundary-order evaluator contract
Source inspection at research f4fa0c11; controls are frozen SCC run02 and prior old-layered results. No implementation, compiler, router, UI or Gitea action. Evaluate one predeclared boundary-order candidate, not a family selected after viewing scores.
## Exact missing information
`layered.rs` incoming-neighbor pass (approximately137–167) considers an edge whose target lifts to the current child and whose source does not lift to that same child. An external source need not be a sibling. Its world-space center Y influences downstream child order. Three passes carry updated positions between groups; outgoing neighbors are intentionally not chased simultaneously, avoiding a swap of both groups that preserves reversal. This is a useful mechanism, not a proof that its three-pass update converges for arbitrary parent cycles.
`condensed.rs:224–241` requires BOTH endpoints to lift into the same sibling group before retaining a link. Thus an external source contributes no local child-order information. Lines365–390 only order SCC blocks from lower-ranked neighbors already in that local links list, followed by same-rank proximity. Correct root condensation knows Left→Right, but the singleton children inside Right have neither local arcs nor external order hints. Their component/canonical order survives. This omission is separate from the successfully fixed SCC rank problem.
## Existing two-container witness: fixed expected order
Fixture definitions are `auto_layout_probe.rs:580–603`. Placement suffixes uniquely identify this fixture:
- Left parent002: Left A006 then Left B008.
- Right parent004: Right A00a then Right B00c.
- Directed edge00d: Left A006→Right B00c.
- Directed edge010: Left B008→Right A00a.
In frozen SCC run02 both groups retain A above B: child Y136 and300. The concrete downstream order witness is **Left A < Left B and Right B < Right A** (compare projected centerY; names are labels, IDs are identities). Preserve Left's order as the upstream reference; swapping both groups is not success. The mirrored physical arrangement can be equivalent globally, but it is not the predeclared one-sided witness. Every child remains under its original parent and each parent's local SCC membership/rank remains unchanged.
Old layered establishes a feasible target with unchanged semantic endpoints: zero shared length/contacts/label collisions versus SCC164 sharing,2contacts,1label/node; route length372 versus788, area272800 versus339852. Do not assert the new implementation must reproduce every coordinate. Require the ordered pairs above and compare actual final released routes to that zero-sharing witness. Smaller connector inversions alone do not pass if routing still merges the traces or labels become obstructed.
## Three additional topology falsifiers, fixed before implementation
Use equal-size ordinary SA function children, no authored ports initially; add explicit anchors only as the stated separate invariant variant. Stable aliases A/B determine the unconstrained upstream order. Use the same renderer-independent node sizes/gaps as existing fixtures, not dimensions chosen after candidate output.
1. **Opposing cross-parent evidence.** Two parents L/R, children A/B each; arcs L.A→R.B, L.B→R.A, R.A→L.A, R.B→L.B. The first pair asks for opposite L/R order; the second pair asks for matching order. These demands are incompatible. Expected: semantic direction and SCC condensation remain exact, deterministic bounded resolution with explicit ties/diagnostics, no endless joint swapping or silently dropped arcs. Do NOT require zero crossing or a particular arbitrary winner. Repeated full candidate calls must stabilize; route/label costs and any introduced hard violation remain visible.
2. **Three-parent propagation.** Parents L/M/R with A/B children. Arcs L.A→M.B, L.B→M.A, M.B→R.A, M.A→R.B. With upstream L.A<L.B fixed, expected M.B<M.A and R.A<R.B. This catches a one-step only pass and averaging stale absolute coordinates from differently positioned parents. Add no reverse arcs. Verify final relative child orders and actual connection quality; parent ranks must remain L<M<R. Run a storage/relation-ID permutation without changing semantic topology and report any different order explicitly.
3. **Multiple SCCs and local ranks.** Within target parent T, two two-member directed SCCs X=(X1↔X2) and Y=(Y1↔Y2), each feeds singleton Z via X2→Z and Y2→Z. External parent S has upperA/lowerB, with S.A→Y1 and S.B→X1. Expected same-rank block Y above X, both before Z's rank; preserve exact SCC membership and internal perimeter order. This catches implementations that sort all children globally by external neighbor Y, split cyclic blocks, or move Z into the same rank. Boundary ordering must act on SCC blocks within an existing rank, not override rank constraints. If cross-boundary preference is unsupported for multi-member blocks, return/report that scope explicitly rather than falsely claiming this fixture passes.
These are structural tests, not new gap or penalty parameters. One variant of the main witness should retain authored port-side/offset anchors to ensure order is achieved by permissible geometry, not anchor mutation. Undirected edges supply no invented rank direction; reversing their stored endpoint order must not change their meaning or create hidden directed precedence. Preserve the existing compound/folded corpus instead of constructing a grand taxonomy of synthetic cases.
## Acceptance checks for the single candidate
Retain all14 existing cases with full failures, reset/old-layered/SCC controls and raw before/after Projects. Require exact source/model conservation under declared node geometry plus existing route reset/translation; original semantic orientation, containment, port identities, attachments and route-entry ordering remain exact. Parent owns the complete Project oracle. Folded nodes remain opaque; stored expanded sizes and latent descendant offsets survive fold→layout→expand, and out-of-projection placements are untouched according to the existing contract.
Independently reconstruct quotient SCC membership, condensation ranks and rank membership before comparing boundary orders. Record hints with edge identity, actual external owner and destination block, using final projected coordinates or a deterministic canonical order as explicitly specified; avoid alias-only success claims. If ordering is ordinal, compare like-for-like coordinates within a reference parent rather than treating arbitrary parent Y translation as semantic priority. Parallel edges must not be silently deduplicated or weighted accidentally by whichever container pass saw them first.
Final actual projection is authoritative for automatic port sides/positions, node capacity and enclosure. Require exact authored anchors, no hard lead incompatibility, no new unrelated node/header penetration or overlap, and preserved pin/metadata policy. Report final route crossings, proper/T/bend contacts, raw/edge-deduplicated sharing with identified pairs, labels, area and length. Keep folded retrace visible. A better topological order that worsens actual traceability is not accepted automatically.
**Sparse40 exactness is a predeclared preservation target**: it is flat and lacks cross-parent boundary relations, so its whole candidate Project, plan geometry and metrics should remain exact to run02 (except new diagnostic fields). Prefer the same check for every case without applicable cross-boundary hints. If it changes, demand a causal explanation and classify it as scope leakage rather than accepting an accidental improvement. Mixed and reversed-ID cases are also flat: preserve their existing outputs, including known differences, rather than promising to remove router ID sensitivity in this change.
Require same-input determinism and ten full repeated candidate calls, including opposing parents, multilevel propagation and the real folded/compound views. Success cannot depend on starting from the special fixture's authored Y values alone; compare a harmless uniform translation of an entire parent subtree while preserving local child order. With canonical ordering policy, this should not reverse the result merely by changing the parent's global position. An explicitly geometry-sensitive policy must state that tradeoff before testing.
Stop after one implementation and one frozen comparison. A viable result must solve the exact existing two-container order/tracing witness, preserve sparse/mixed flat outputs, survive the contradictory/chained/multi-SCC tests without topology corruption or instability, and retain all real-case regressions transparently. Production command/history integration and native tracing remain separate acceptance work; passing these geometry checks alone is not closure of #32.
@@ -0,0 +1,791 @@
{
"schema": 1,
"source_commit": "3e21c1bca245944ae0ec7bb02aaa920f45f2cc30",
"archive": {
"file": "boundary-order-3e21c1bc.zip",
"bytes": 4310136,
"sha256": "bb6b896ff2401290869a904f7768ebb52b6f0ab36fada06badbe9abb301c37b8"
},
"members": [
{
"member": "collector/archive-boundary-order-20260925.py",
"bytes": 3843,
"sha256": "81adb0add2c57a4c1109efc8b74ba0f6ffb37250abc8edcd95b30853a93eebab"
},
{
"member": "collector/audit-boundary-conservation-20260925.py",
"bytes": 17232,
"sha256": "f14d96f7ee1487d245bd30436dea356df7524006c51f2fbac929b067b881d893"
},
{
"member": "collector/audit-boundary-order-20260925.py",
"bytes": 5352,
"sha256": "96bb938961255b59add3922f2cc8b30ddc7ec127d77ab1d7b61974e116930432"
},
{
"member": "collector/audit-scc-placement-v3-20260925.py",
"bytes": 8729,
"sha256": "8b238f010eeb81720a59a0ad290544f87934acb8070e58a3fd25f9eda9f47a0d"
},
{
"member": "collector/launch-boundary-native-20260925.py",
"bytes": 13468,
"sha256": "4d75605389ee53a6a2d2b73b7fd9c28400db89efce1097c7fad5656e7bf4d663"
},
{
"member": "collector/run-boundary-order-20260925.py",
"bytes": 4575,
"sha256": "01c6ddd4953ee485123cbed5d99aa4f1b485b21be69083828959cf50c938a9b1"
},
{
"member": "collector/run-routing-corpus-check-20260925.py",
"bytes": 2793,
"sha256": "2726a397bd4ecb4dcfff6fc170a66ce2655229079f42335faa2a4bfe4a202f6d"
},
{
"member": "gates/27-boundary-example-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/27-boundary-example-tests/command/context.json",
"bytes": 3510,
"sha256": "13b6e4d82cd228eabe26a45c3294fef319eccd8edca784f5b41d3de7003b65ec"
},
{
"member": "gates/27-boundary-example-tests/command/inputs-after.json",
"bytes": 1762589,
"sha256": "800940ce4e0bd2b3bd56b87f65308808dc99e5f897d643bffa04405de211bfbd"
},
{
"member": "gates/27-boundary-example-tests/command/inputs-before.json",
"bytes": 1762589,
"sha256": "800940ce4e0bd2b3bd56b87f65308808dc99e5f897d643bffa04405de211bfbd"
},
{
"member": "gates/27-boundary-example-tests/command/output.log",
"bytes": 1385,
"sha256": "a2e29cb282440949664ca33aafc6c0174c6394a2327e76ad16994aa3ee21b3b7"
},
{
"member": "gates/27-boundary-example-tests/command/result.json",
"bytes": 4184,
"sha256": "ccc581072ecdd59c8b9881571aae6aaf32c4eb6ccbbcc7d712e9ef2cec9655ac"
},
{
"member": "gates/27-boundary-example-tests/command/stderr.log",
"bytes": 336,
"sha256": "b3f2054556656f6a805f054ffb8d5c780be84b69c65135cc6c0d28f7d1a7d6f8"
},
{
"member": "gates/27-boundary-example-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/27-boundary-example-tests/orchestration.log",
"bytes": 185,
"sha256": "6f08f77e5593cbd746ee6ab7b6f16641bee0a7058f03b9e2fb04b7cb747c8181"
},
{
"member": "gates/28-boundary-clippy/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/28-boundary-clippy/command/context.json",
"bytes": 3540,
"sha256": "b1686a8cfac3bfec3627da11f0950826c2a06dcb115851723ac1987b8ca91c3d"
},
{
"member": "gates/28-boundary-clippy/command/inputs-after.json",
"bytes": 1762589,
"sha256": "800940ce4e0bd2b3bd56b87f65308808dc99e5f897d643bffa04405de211bfbd"
},
{
"member": "gates/28-boundary-clippy/command/inputs-before.json",
"bytes": 1762589,
"sha256": "800940ce4e0bd2b3bd56b87f65308808dc99e5f897d643bffa04405de211bfbd"
},
{
"member": "gates/28-boundary-clippy/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/28-boundary-clippy/command/result.json",
"bytes": 4197,
"sha256": "2fbd9f68cc45957b62122fda4b022a9e6eb3661a871132f06444f87ef862c9bf"
},
{
"member": "gates/28-boundary-clippy/command/stderr.log",
"bytes": 176,
"sha256": "7be90bc986d32ae1b1f4bf7e877bbcb73389e60288af76e6af2b6626e8cd2626"
},
{
"member": "gates/28-boundary-clippy/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/28-boundary-clippy/orchestration.log",
"bytes": 178,
"sha256": "ce952a08d4fe80b4e7091db3ec33ab562136997a9c6900c3efde32bbf027793f"
},
{
"member": "gates/29-boundary-precision-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/29-boundary-precision-tests/command/context.json",
"bytes": 3512,
"sha256": "df7d084938c7f45b6b4d7229124ad92eeb4dcbde80d77cfac6a1902754d72f9a"
},
{
"member": "gates/29-boundary-precision-tests/command/inputs-after.json",
"bytes": 1762589,
"sha256": "8c1c5b141d9322956c9914284387fd1471879a0cfadd4eb720e1be3cdbcd524e"
},
{
"member": "gates/29-boundary-precision-tests/command/inputs-before.json",
"bytes": 1762589,
"sha256": "8c1c5b141d9322956c9914284387fd1471879a0cfadd4eb720e1be3cdbcd524e"
},
{
"member": "gates/29-boundary-precision-tests/command/output.log",
"bytes": 1473,
"sha256": "bf6344286c5fb4531117b25deef585502167c9ffaf7f11416bd7b9af9fde2659"
},
{
"member": "gates/29-boundary-precision-tests/command/result.json",
"bytes": 4190,
"sha256": "5a412dc08cb74c2bb2206b901e97878b29a1a87f7c26891981b08db374a20fe2"
},
{
"member": "gates/29-boundary-precision-tests/command/stderr.log",
"bytes": 336,
"sha256": "e4f89d4438ee4f29fdd9c827af6c8b9c6be621182e734b094ffedbcd3d03a467"
},
{
"member": "gates/29-boundary-precision-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/29-boundary-precision-tests/orchestration.log",
"bytes": 187,
"sha256": "205746a7fd277265ba7f1a3c52073fdc9618909dfab31b9f15ff210abf4abbed"
},
{
"member": "gates/30-boundary-precision-clippy/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/30-boundary-precision-clippy/command/context.json",
"bytes": 3550,
"sha256": "fe1ce5ca19ef4c19b1c4627c73ef3d42c4be20da52952de5fe0ebf606e549d6c"
},
{
"member": "gates/30-boundary-precision-clippy/command/inputs-after.json",
"bytes": 1762589,
"sha256": "8c1c5b141d9322956c9914284387fd1471879a0cfadd4eb720e1be3cdbcd524e"
},
{
"member": "gates/30-boundary-precision-clippy/command/inputs-before.json",
"bytes": 1762589,
"sha256": "8c1c5b141d9322956c9914284387fd1471879a0cfadd4eb720e1be3cdbcd524e"
},
{
"member": "gates/30-boundary-precision-clippy/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/30-boundary-precision-clippy/command/result.json",
"bytes": 4227,
"sha256": "df153dbc6cfa994be50f3ade29023885397131d4b66727e5464781acd473b339"
},
{
"member": "gates/30-boundary-precision-clippy/command/stderr.log",
"bytes": 176,
"sha256": "971c0f30a7e4473172912bf8e3d34edd27c36a6df689613be3bac74262dc89b7"
},
{
"member": "gates/30-boundary-precision-clippy/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/30-boundary-precision-clippy/orchestration.log",
"bytes": 188,
"sha256": "2aa50a7d9dfa26b6281a5492584836edf59ad7fab5ece9e1ade8df5c618690b0"
},
{
"member": "gates/31-boundary-release/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/31-boundary-release/command/context.json",
"bytes": 3529,
"sha256": "8d95ec8851bdb5298456db6779c3935c992ac94fb01006b5bda77733f035643d"
},
{
"member": "gates/31-boundary-release/command/inputs-after.json",
"bytes": 1762589,
"sha256": "8c1c5b141d9322956c9914284387fd1471879a0cfadd4eb720e1be3cdbcd524e"
},
{
"member": "gates/31-boundary-release/command/inputs-before.json",
"bytes": 1762589,
"sha256": "8c1c5b141d9322956c9914284387fd1471879a0cfadd4eb720e1be3cdbcd524e"
},
{
"member": "gates/31-boundary-release/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/31-boundary-release/command/result.json",
"bytes": 4188,
"sha256": "c9eb4f6148e4dc81bf03225600b67608044ebd9c2a2e5fff8cfa1a6fcedad526"
},
{
"member": "gates/31-boundary-release/command/stderr.log",
"bytes": 179,
"sha256": "cb88f4b7def4df8a09d67f7fdff2046fb076a0ea293f525cae46a59f801bf019"
},
{
"member": "gates/31-boundary-release/environment.json",
"bytes": 9470,
"sha256": "1cda80470e5893747b1aad7eda5ef51d57069441e810698cd7f94f7a7521bfe5"
},
{
"member": "gates/31-boundary-release/orchestration.log",
"bytes": 179,
"sha256": "577b9b108998d0e065a53dc08f658cb42026a539fe4b692bc5d50a44da49eca1"
},
{
"member": "inputs/corpus/manifest.json",
"bytes": 10593,
"sha256": "a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717"
},
{
"member": "inputs/corpus/mixed_dispatch.json",
"bytes": 32787,
"sha256": "81d25af021cbad18af4262a220ba60372e51ca19083b7e80f2b19196baf05990"
},
{
"member": "inputs/corpus/mixed_dispatch_edge_ids_reversed.json",
"bytes": 32787,
"sha256": "25c95be6b6e7ad9ebcdc83aacc13fbbaa5a56651ba2843f8d1658c075ed789f8"
},
{
"member": "inputs/corpus/subsystems_40_sparse.json",
"bytes": 124043,
"sha256": "ad0ee7a0ab9c9f3c5f26a6d839f6627a82aa38858a3d5cc1ca87f5a8d795533e"
},
{
"member": "inputs/corpus/workshop_sa_folded.json",
"bytes": 102922,
"sha256": "ea5fd285d11795e5e543e4144349c32c92a5b328b8c5e2d1be8b75b70703dc97"
},
{
"member": "inputs/corpus/workshop_sa_original.json",
"bytes": 102923,
"sha256": "cc9b26390594513c11b3d85b768d244b2df8e7bed8cb76c4bdf0dc24db1d2ef6"
},
{
"member": "inputs/prior-arrange-controls.jsonl",
"bytes": 1862455,
"sha256": "f924af4038ade0de2e0f44988fa28d2566019d8c4bc2bde70e61fe4813364d40"
},
{
"member": "inputs/released-route-control.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"member": "inputs/scc-run02/mixed_dispatch/stdout.jsonl",
"bytes": 93898,
"sha256": "28a7f598746f4c0c58afd0321861e417b2715976cde52bf55361dce8c35b4d74"
},
{
"member": "inputs/scc-run02/mixed_dispatch_edge_ids_reversed/stdout.jsonl",
"bytes": 93308,
"sha256": "6a723a4899026c2df80327fb76c5dda8e5dc5e4e15e9e066991413c2246bade5"
},
{
"member": "inputs/scc-run02/route-control/stdout.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"member": "inputs/scc-run02/small-controls/stdout.jsonl",
"bytes": 425661,
"sha256": "0ec2bc1f51542b41b5df0b89d2a87306716a49a22951c4dfeb128dd75247d074"
},
{
"member": "inputs/scc-run02/small-scc/stdout.jsonl",
"bytes": 220188,
"sha256": "0c8b9ef7888cd5ba99733f15d22478cdb2878ef02e22d297d02c8b3eea2e9e15"
},
{
"member": "inputs/scc-run02/subsystems_40_sparse/stdout.jsonl",
"bytes": 361147,
"sha256": "452690f23dda57f62d115b6d88e42d7f0283b4c86081d5149d8738ba6052e53b"
},
{
"member": "inputs/scc-run02/workshop_sa_folded/stdout.jsonl",
"bytes": 194613,
"sha256": "ddf05a2ca36950305090bd5d91ec2a6c617d2eae373c33ad84e9ff4157581c0c"
},
{
"member": "inputs/scc-run02/workshop_sa_original/stdout.jsonl",
"bytes": 198272,
"sha256": "e30a2a6a30d1522cb2f8e9377e7eb8f0a81d1fe8b5aa18550f78c4829b8cc408"
},
{
"member": "native/inputs/boundary_two_containers_anchored__boundary.json",
"bytes": 8997,
"sha256": "f84fafbc3a80aee5caebf5b1cd6d41f340d954342664c64e7b627ba4fcefbe39"
},
{
"member": "native/inputs/boundary_two_containers_anchored__scc.json",
"bytes": 8997,
"sha256": "1da4878fa52fe665e4639eb1a9cc99b5b0e85516dd51f898270ed619c4eafb06"
},
{
"member": "native/inputs/boundary_two_local_sccs__boundary.json",
"bytes": 16991,
"sha256": "c408c437d60a8f62952151d1880ea50bc10985d5ffadec1d91b25361c1862737"
},
{
"member": "native/inputs/boundary_two_local_sccs__scc.json",
"bytes": 16991,
"sha256": "a6e83c92dd4b9a4cb59054730b81a995a4ed2351d9a865e0c7a1572a80542dc0"
},
{
"member": "native/inputs/two_containers_reversed_children__boundary.json",
"bytes": 8179,
"sha256": "6ed26cc72a540207f31c04bd989dfa718b1c573be1d15fcffebc8046c32fb84f"
},
{
"member": "native/inputs/two_containers_reversed_children__scc.json",
"bytes": 8179,
"sha256": "56e980ef38cdc24e1a6b710557736c84026bb052da7e88726d55fd61e5d0c375"
},
{
"member": "native/manifest.json",
"bytes": 7509,
"sha256": "940a7605b5a83308261e1fde0ecd7291cc855614a515e87e084823c8fc4e9016"
},
{
"member": "native/observations/01-two-container-boundary.json",
"bytes": 294,
"sha256": "aa930a00b846e037130a219043d0e71892be95ce3c3739ccb2b88956d4d204af"
},
{
"member": "native/observations/01-two-container-boundary.png",
"bytes": 122265,
"sha256": "bc4e28a0fcc37cdc4c904993b67e5b018c66a3a0a2ff7c2511fec324e03d5cd7"
},
{
"member": "native/observations/02-two-container-scc.json",
"bytes": 310,
"sha256": "741b04f292bdfea132a8131525be0f6215fa4d557100dd8114e41cb2e3088dbf"
},
{
"member": "native/observations/02-two-container-scc.png",
"bytes": 122550,
"sha256": "e1c68d66a4eae12c2e2c056858a1d4fc6b5eec8c387ee39b19337abbce7f49cf"
},
{
"member": "native/observations/03-anchored-boundary.json",
"bytes": 310,
"sha256": "e175e1ed5c9ae6a551bad7f6fd16badabeff245e0fe5c37876421467ce4b70eb"
},
{
"member": "native/observations/03-anchored-boundary.png",
"bytes": 122077,
"sha256": "8038656c660d826426c36e059997eb955ef8e84db4bdc2d23bcc214f64580c1d"
},
{
"member": "native/observations/04-local-scc-boundary.json",
"bytes": 310,
"sha256": "81f0bb6e233b37c5c119c6b0c158abb18bb2632af172136cc7411289a14f4865"
},
{
"member": "native/observations/04-local-scc-boundary.png",
"bytes": 120833,
"sha256": "677057c6870103daeeb31d48a11a5f9b8b8ebb604a7864e71a541a28d6024342"
},
{
"member": "native/observations/05-local-scc-selected-lower-boundary.json",
"bytes": 301,
"sha256": "e2ba43b96ffef6f6c6b4a349456d428a1f6b65d329cae7a0cf8fee6e0cec4d26"
},
{
"member": "native/observations/05-local-scc-selected-lower-boundary.png",
"bytes": 132475,
"sha256": "732cc188a8e8fbe3632d3bd824f218560c5a40afac053d5f8936e62be2699861"
},
{
"member": "native/run01/close.json",
"bytes": 3845,
"sha256": "a89d86f5c321299b034d1b5b28a635ee0574736d9ef715ba1c85fd26fc0fde1c"
},
{
"member": "native/run01/preflight.json",
"bytes": 3503,
"sha256": "1aa792b64b96fee428594d76f4c838256db7e4d86ef12f12cfc59e197ff96178"
},
{
"member": "native/run01/profile/ArcadiaStudio/recent-models.json",
"bytes": 946,
"sha256": "cfa44a8c46c193ba27b41ad84ba437a588250b4bed27437dfb4c2a1cb08b8f8b"
},
{
"member": "native/run01/start.json",
"bytes": 453,
"sha256": "5e403aff77fc582f961fad424bbd863ebcd2c069d939963ea2723ccee6f63dd1"
},
{
"member": "native/run01/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "native/run01/stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "native/run01/working/boundary_two_containers_anchored__boundary.json",
"bytes": 8997,
"sha256": "f84fafbc3a80aee5caebf5b1cd6d41f340d954342664c64e7b627ba4fcefbe39"
},
{
"member": "native/run01/working/boundary_two_containers_anchored__scc.json",
"bytes": 8997,
"sha256": "1da4878fa52fe665e4639eb1a9cc99b5b0e85516dd51f898270ed619c4eafb06"
},
{
"member": "native/run01/working/boundary_two_local_sccs__boundary.json",
"bytes": 16991,
"sha256": "c408c437d60a8f62952151d1880ea50bc10985d5ffadec1d91b25361c1862737"
},
{
"member": "native/run01/working/boundary_two_local_sccs__scc.json",
"bytes": 16991,
"sha256": "a6e83c92dd4b9a4cb59054730b81a995a4ed2351d9a865e0c7a1572a80542dc0"
},
{
"member": "native/run01/working/two_containers_reversed_children__boundary.json",
"bytes": 8179,
"sha256": "6ed26cc72a540207f31c04bd989dfa718b1c573be1d15fcffebc8046c32fb84f"
},
{
"member": "native/run01/working/two_containers_reversed_children__scc.json",
"bytes": 8179,
"sha256": "56e980ef38cdc24e1a6b710557736c84026bb052da7e88726d55fd61e5d0c375"
},
{
"member": "native/staging.json",
"bytes": 331,
"sha256": "df221a4389c519db81276595d8154661da78812798af64b49e81c382ecaae348"
},
{
"member": "reviews/boundary-conservation-audit-20260925.json",
"bytes": 221331,
"sha256": "a59a3dcdd72eeab1502570d5189a31b2560bed57ed0d4f072a41e6de1534ac0e"
},
{
"member": "reviews/boundary-conservation-audit-final-20260925.json",
"bytes": 235597,
"sha256": "f6a3fa93c03174e0eae6f816975f06a10a696659bd3fd58291ac805a69d5edee"
},
{
"member": "reviews/boundary-conservation-review-20260925.md",
"bytes": 4315,
"sha256": "2612286fb2696f0276615427b303f3fd348098e59a00ae4f4683b04e812fd7d1"
},
{
"member": "reviews/boundary-native-observation-20260925.md",
"bytes": 2698,
"sha256": "fccd79467f48a0593256c9858ac14609a9291f3271c491f8149739314667cd48"
},
{
"member": "reviews/boundary-native-review-20260925.md",
"bytes": 6850,
"sha256": "e791925f8794e10c966f4e45d5bfb560395873d2dd2b0258340087ef20ba67a2"
},
{
"member": "reviews/boundary-order-design-critique-20260925.md",
"bytes": 17016,
"sha256": "100147aa35aff59840563e8c5c37a7c56298671910e805f55c21cac0373f435f"
},
{
"member": "reviews/boundary-order-evaluation-20260925.md",
"bytes": 8964,
"sha256": "bfdb122e9fdb5532137e5760381d7a61ef094d203ab2e3b157f90c0674894e0b"
},
{
"member": "reviews/boundary-order-implementation-20260925.md",
"bytes": 4464,
"sha256": "31e1657cc05aff9b0a802b84786baf478b3ba8913f3c241e585f24a47875c9ba"
},
{
"member": "reviews/boundary-order-independent-audit-20260925.json",
"bytes": 158196,
"sha256": "914e39cf9297ab025927b9ba9bae02adee157e3dc7061058e67ee280cb6cb212"
},
{
"member": "reviews/boundary-order-result-review-20260925.md",
"bytes": 7224,
"sha256": "b9cc9692c094d35f88f71f43b035d08d375e4350c88bad35ee07420c10bfb9e9"
},
{
"member": "reviews/boundary-order-source-review-20260925.md",
"bytes": 9618,
"sha256": "21eb621bca634a8ab0fbc122092a3c41281d121078b40651bf66eae7f6556165"
},
{
"member": "run01/boundary-extra/receipt.json",
"bytes": 903,
"sha256": "12c11a00ed7931e77034ad69ef35b2f53ea08960ff836c9bd2605b632fc4673b"
},
{
"member": "run01/boundary-extra/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/boundary-extra/stdout.jsonl",
"bytes": 488611,
"sha256": "5695e09f332a2876592134a4b0621e6a6c22b03ab5dbee6d21393a48e3e2d99b"
},
{
"member": "run01/boundary-small/receipt.json",
"bytes": 897,
"sha256": "78dce798e743b1a3547ba81ec8c86644d1a99b8e5f46ff6640db6151a426ad4f"
},
{
"member": "run01/boundary-small/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/boundary-small/stdout.jsonl",
"bytes": 222634,
"sha256": "fadde557248cdf0cbef1a127683f7fb2244608e9940a385b490caf242ab93ed2"
},
{
"member": "run01/capture.json",
"bytes": 5928,
"sha256": "7346d81f31a09ea660121deaee25215829d7d559a6e08f762394500c36a4ced4"
},
{
"member": "run01/mixed_dispatch-scc-control/receipt.json",
"bytes": 1140,
"sha256": "43eb6ce30ee2f9efd27da2b0366618c44e6630f93d2162fdb217b6d2e41088e5"
},
{
"member": "run01/mixed_dispatch-scc-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch-scc-control/stdout.jsonl",
"bytes": 93898,
"sha256": "28a7f598746f4c0c58afd0321861e417b2715976cde52bf55361dce8c35b4d74"
},
{
"member": "run01/mixed_dispatch/receipt.json",
"bytes": 1108,
"sha256": "b18abee69afd6097a54bad381fc56e6e7f842efb7130043b1af4656af11d1e8d"
},
{
"member": "run01/mixed_dispatch/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch/stdout.jsonl",
"bytes": 94148,
"sha256": "ac99f7222fbabdf19cdd9fd64d77251a8bd66f2cc54f285415ffae655df574cb"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-scc-control/receipt.json",
"bytes": 1212,
"sha256": "6739ca9bc76cf7deed0579e74ab784453bce0c2a223cae3e3e041d0e9a5c4b6a"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-scc-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-scc-control/stdout.jsonl",
"bytes": 93308,
"sha256": "6a723a4899026c2df80327fb76c5dda8e5dc5e4e15e9e066991413c2246bade5"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed/receipt.json",
"bytes": 1181,
"sha256": "e20402a551f8b1a0e3bb37880aba6efbeee935f7e33b07e0c2c30852c66873dd"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed/stdout.jsonl",
"bytes": 93558,
"sha256": "2c6fc18cc10edf82b67db666ebbf5a143f3f0090558cb37e6d941c23b5aa49b3"
},
{
"member": "run01/receipt.json",
"bytes": 28320,
"sha256": "9aeaeedd81d968d353c48fc32126c7644c452e3b0679ac67ab4fbad7f985ba49"
},
{
"member": "run01/route-control/receipt.json",
"bytes": 1050,
"sha256": "3bbd687895501ef451d51c300ce084eb0368bd8ecb3fff3de58573c9187cedff"
},
{
"member": "run01/route-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/route-control/stdout.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"member": "run01/scc-small-control/receipt.json",
"bytes": 900,
"sha256": "138fc549ae60641c5eb9fd77b9ca379e2ffb42d21fc365ccdbc967803cdeb44a"
},
{
"member": "run01/scc-small-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/scc-small-control/stdout.jsonl",
"bytes": 220188,
"sha256": "0c8b9ef7888cd5ba99733f15d22478cdb2878ef02e22d297d02c8b3eea2e9e15"
},
{
"member": "run01/small-controls/receipt.json",
"bytes": 868,
"sha256": "475254bd941a3a39296c1b251a1d90f0a540b49d652c9c40ee7a928412439af3"
},
{
"member": "run01/small-controls/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/small-controls/stdout.jsonl",
"bytes": 425661,
"sha256": "0ec2bc1f51542b41b5df0b89d2a87306716a49a22951c4dfeb128dd75247d074"
},
{
"member": "run01/subsystems_40_sparse-scc-control/receipt.json",
"bytes": 1165,
"sha256": "181eb29b33c4b976dddedf12f9527fa2ae1381e588c7af620ad88d5ee47b1706"
},
{
"member": "run01/subsystems_40_sparse-scc-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/subsystems_40_sparse-scc-control/stdout.jsonl",
"bytes": 361147,
"sha256": "452690f23dda57f62d115b6d88e42d7f0283b4c86081d5149d8738ba6052e53b"
},
{
"member": "run01/subsystems_40_sparse/receipt.json",
"bytes": 1134,
"sha256": "6ed2ca8414aa4bb56c3c34a2af7832b844c51cc89e74834bc8800dcb92cdd7ba"
},
{
"member": "run01/subsystems_40_sparse/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/subsystems_40_sparse/stdout.jsonl",
"bytes": 361397,
"sha256": "26925d461fb34af1a728912d143d70f05172823ebf760d2386d2ebea63cfa72d"
},
{
"member": "run01/workshop_sa_folded-scc-control/receipt.json",
"bytes": 1157,
"sha256": "6de602ddd035e3ee667cb28490da5a6f22e31bc429a8e399c82a55699bc72334"
},
{
"member": "run01/workshop_sa_folded-scc-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_folded-scc-control/stdout.jsonl",
"bytes": 194613,
"sha256": "ddf05a2ca36950305090bd5d91ec2a6c617d2eae373c33ad84e9ff4157581c0c"
},
{
"member": "run01/workshop_sa_folded/receipt.json",
"bytes": 1126,
"sha256": "a8a889e96fb85762531352e331b7486cb297f931a89a6ed57c9464ac294e16fb"
},
{
"member": "run01/workshop_sa_folded/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_folded/stdout.jsonl",
"bytes": 195257,
"sha256": "f24b1412784c6985b79ead9f3fa35dc7818fc20d5ca895d4a03473afa9b3497b"
},
{
"member": "run01/workshop_sa_original-scc-control/receipt.json",
"bytes": 1165,
"sha256": "896734b2abdfef5cd53a98aac2f5770c870bff0a43d7a510168dd275083d4237"
},
{
"member": "run01/workshop_sa_original-scc-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_original-scc-control/stdout.jsonl",
"bytes": 198272,
"sha256": "e30a2a6a30d1522cb2f8e9377e7eb8f0a81d1fe8b5aa18550f78c4829b8cc408"
},
{
"member": "run01/workshop_sa_original/receipt.json",
"bytes": 1134,
"sha256": "b2242a1dddb4811c1d795ef9a3d7a0b6c8bb6eade992b674cfa9a1055a6899d1"
},
{
"member": "run01/workshop_sa_original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_original/stdout.jsonl",
"bytes": 199200,
"sha256": "0517a3088f456fed2ee995bf610e2dbfb0cdc3e4d2e7085c2fbf32d02be15464"
}
]
}
@@ -0,0 +1,23 @@
# Final packaging and claim review
Reviewed the final results and copied source/result/conservation/native reviews, plus the completed evidence archive. This is a bounded publication gate for the existing experiment; no compiler, application, new candidate or native investigation was executed.
**No material packaging or claim error found.** The package is ready for the parent's publication/checkpoint step. This review does not assert that publication has already succeeded, that the candidate is adopted, or that issue32 is complete.
## Archive verification
- `evidence/boundary-order-3e21c1bc.zip`: exactly4,310,136bytes; SHA256 `bb6b896ff2401290869a904f7768ebb52b6f0ab36fada06badbe9abb301c37b8`.
- Exactly156 unique ZIP members; member-name set exactly equals `evidence/manifest.json`, with no duplicate or unexpected member.
- ZIP CRC readback passes for all members. Every uncompressed member's byte size and SHA256 equals its manifest entry.
- Five named native PNG captures are present. The independent result audit script and its explicit SCC helper are both included; the helper dependency is not omitted.
- All relative Markdown links in the topic documents resolve at this checkpoint. The new final review is outside the frozen archive and does not imply a replacement archive hash.
## Claim and attribution checks
Results identify generator/test source `3e21c1bca245944ae0ec7bb02aaa920f45f2cc30`, distinguish final15 focused tests/strict Clippy/release gates from earlier14-test evidence at42f595a5, and retain20 candidate outcomes,15 child processes and eight unchanged control streams as distinct inventories. No full-suite, controlled-performance or production acceptance claim is substituted for these scoped checks.
The comparison retains simple-case and chained-parent improvements alongside expanded-workshop crossing/sharing regressions, folded sharing growth, and anchored/local-SCC label problems. Flat full-Project/metric equality and model conservation are attributed to the relevant mechanical audits. Conservation coverage limits are explicit: dormant attachment/translation behavior is not claimed exercised merely because the checker supports it.
Native attribution correctly separates the3e21 candidate Project generator from the reused `d6f45a13a7b8ab8dc9b84ee432a832609f5af6ed` GUI renderer, executable SHA256 `133375d57bdecf3f3effe5ecc13ec121e1257b90838f2cdb64fb91aa9a530d1b`. The planner was not invoked through native Arrange. Four imported Projects and five captures are the observed scope; two other staged controls are not represented as viewed. The independent native review explicitly handles stale window-title metadata, distinguishes readable text from label-background interruption of the parent outline, and limits the local-SCC finding to overview/selection-assisted tracing. No Undo/Redo or production command-integration claim is inferred from these captures.
The final results link the real archive/manifest and bounded reviews, rather than retaining the earlier forthcoming-evidence placeholder. Publication remains the parent's final step. Stop after that requested publication/checkpoint; this review authorizes no further implementation or experiment.
@@ -0,0 +1,19 @@
# One-pass boundary ordering implementation
Owned module only: `examples/auto_layout_probe/condensed/boundary.rs`, preformat SHA256 `d2b1a5882c4b64d79d09d5cca586ad4cef5dac086e5a8fd438f0218e6119889d`. Parent owns integration/format/compilation. No builds, rustfmt, commits or native execution by implementation agent.
Exact requested public-to-parent Block/Band/Group/reorder API. Validates child-parent membership, complete unique band inventory, finite positive block geometry and existing undirected-bundle contiguity. Undirected connectivity is evaluated within each band, preserving existing block order within each indivisible unit; noncontiguous input fails explicitly. Directed incoming edges anchor a unit only when the target lifts into it and source does not lift into the current parent. One vote per distinct visible source placement ID, stable-ID order, f64 arithmetic mean of current absolute source centerY. Full offset ancestry and root40 are composed; parallel edges do not multiply votes.
Only anchored units exchange their previous ordinal slots, using score then canonical unit order. Unanchored unit ordinals remain fixed. Whole-band block heights/gaps are repacked as a prefix, so unequal-height units do not reuse incompatible old Y slots. X, sizes, SCC memberships/ranks, perimeter/member offsets and root layout are untouched. Every member's offset receives its block Y delta; descendants move by ancestor composition rather than duplicate direct edits.
A group is active only if some band contains at least two anchored units. Dependency H→G exists whenever active groupH owns any offset on an actual external source's complete ancestor chain. No additional ancestry-only arcs. Stable parent-ID order feeds SCC condensation; process the dependency DAG once. Every score in one dependency SCC is snapshotted before any member's offset updates. Cycles are therefore a one-pass snapshot heuristic, not a fixed point or a stability guarantee.
Prefix accumulation is f64; conversion and occupied-envelope agreement are checked with explicit0.001units tolerance. Existing canonical prefix positions must also agree within that tolerance. Unchanged orders retain their original f32 positions exactly. No envelope resizing occurs; parent final reprojection remains authoritative. Missing/cyclic/nonfinite structures and excessive charged work return errors. The enclosing candidate owns the private scratch offsets, so it must discard them on failure; this helper does not promise transactional rollback of mutable arguments after an error.
Diagnostics include active parent IDs, dependency edges with source/ancestor witnesses, dependency SCCs/cyclic status, before/after block orders, source-owner sets, actual edge hints, scores, changed units/blocks and tolerance. Pure unrun tests cover anchored sorting with a fixed unanchored ordinal, heterogeneous100/20height repacking, and a source center changing under a grandparent offset. Parent's actual fixtures must test dependency chains/opposition, node/route preservation, repeat behavior and quality; no acceptance is inferred from implementation.
Pre-build review follow-up: module SHA256 `77522e22daf4058a07aafe6b246211bf652d9fc99e2a556cf9f8b20c297eaf0e`. Absolute source Y now follows the final plan's precise f32 order (own offset, ancestors upward, then+40); convert that Y to f64 before adding half-height and averaging votes. Member-offset updates reject actual f32 movement differing from requested delta by more than0.001. Added three unrun tests: actual reorder dependency on a grandparent-owned offset with adversarial parent-ID ordering; actual undirected bundle preservation around an unanchored ordinal with heterogeneous heights and deduplicated sources; noninteger f32 composition plus accepted/rejected translation precision. Six module tests now exist. No policy constants, corpus outcomes or rank/packing heuristics were tuned.
## Parent acceptance addendum
Final tested source3e21c1bca245944ae0ec7bb02aaa920f45f2cc30 corrects full member displacement precision (including origin subtraction), with the real large-origin packing regression. Focused example tests15pass, strict Clippy and optimized Windows build pass with unchanged inputs (gates29–31). Prior gates27–28 at42f595a5 retain14tests/Clippy success. All20candidate outcomes supported inrun01; eightcontrols exact. Result/conservation/native reviews define quality limits; no production adoption.
@@ -0,0 +1,41 @@
# Native renderer observation
Candidate Project generator: `3e21c1bca245944ae0ec7bb02aaa920f45f2cc30`.
Reused native executable: `d6f45a13a7b8ab8dc9b84ee432a832609f5af6ed`,
SHA256 `133375d57bdecf3f3effe5ecc13ec121e1257b90838f2cdb64fb91aa9a530d1b`.
This observes saved experimental Projects in the existing renderer. It does not
exercise the experimental planner through a native Arrange command.
The parent used the Computer skill and native Open dialog to import four exact
Project extractions, without editing or saving. Five screenshots record:
1. `01-two-container-boundary`: Fit102%, Left A→Right B and Left B→Right A
appear as separate straight horizontal connections. Both labels are readable
between containers, with no shared route or apparent endpoint ambiguity.
2. `02-two-container-scc`: same viewport/scale, prior SCC ordering. Routes
visually meet at the right container boundary and run alongside its border;
the apparent straight rows misleadingly suggest the opposite endpoint pairing.
This is a concrete improvement from the first image's reordered children.
3. `03-anchored-boundary`: authored anchors retain bent routes. The two label
backgrounds interrupt the right parent border; the label text remains readable
and does not obscure child names. The emitted two label/node intersections
should not be described as two unreadable labels or child-name occlusions.
4. `04-local-scc-boundary`: Fit55%, intact Y1/Y2 block above X1/X2, Z later.
Small text and multiple adjoining/reused strokes make tracing harder than
the simple two-edge example. A structurally correct block order is insufficient
to establish native usability for this case.
5. `05-local-scc-selected-lower-boundary`: selecting the lower source connection
highlights its path to X1 and displays Source B / X1 in Properties. Selection
helps resolve the route among neighboring strokes. No endpoint edit occurred.
The process was closed by Alt+F4. The immediate window list briefly retained the
closing window; a subsequent capture reported no foreground process. The owned
observer then returned exit0, empty stdout/stderr, unchanged immutable inputs,
and no running process. All six staged working JSONs remain unchanged (only four
were opened). No save, undo/redo, new planner invocation, API integration, general
accessibility acceptance, or whole-application acceptance is inferred.
Evidence includes stage/source extraction receipts, per-run process records,
five screenshot/metadata pairs, and the launcher. Package binaries are hash-bound
in the manifest rather than duplicated in the research archive. Windows native
inspection only; Linux remains excluded.
@@ -0,0 +1,41 @@
# Boundary-order native evidence review
Independent review, 2026-09-25. Inspected all five archived PNGs with `view_image`, their capture metadata, the staging/launch/close records, package and source attribution, and the private profile's recent-model list. No new GUI session, import, build, experimental Arrange invocation or source change. This review stops at the existing evidence as requested by the user.
**The simple boundary case is visibly easier to trace than its SCC control. Authored anchors retain a small label-background/container-border conflict, while the local-SCC overview still needs selection to disambiguate a boundary route. This is limited native observation of imported geometry, not acceptance of a production Arrange replacement.**
## Attribution and integrity
- Reused GUI source: `d6f45a13a7b8ab8dc9b84ee432a832609f5af6ed`; executable SHA256 `133375d57bdecf3f3effe5ecc13ec121e1257b90838f2cdb64fb91aa9a530d1b`; DLL SHA256 `aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a`.
- Imported candidate and paired SCC Projects were generated at `3e21c1bca245944ae0ec7bb02aaa920f45f2cc30`. The existing native renderer displays those raw Projects. The experimental boundary planner was not executed through the GUI's Auto-layout control.
- Independently rehashed 21 referenced records covering the manifest, launcher, source-run/child receipts and stdout, reused attribution, staged executable/DLL, six input Projects, launch preflight and native logs: no mismatch. All six working Project hashes agree between the recorded preflight and close inventories; no working-file change was recorded.
- Manifest SHA256 is `940a7605b5a83308261e1fde0ecd7291cc855614a515e87e084823c8fc4e9016`. Private `LOCALAPPDATA` and unrelated working directory are under `boundary-native-20260925/run01`.
- Start/close records identify PID 5492, observed exit code 0, no observer failure, unchanged immutable inputs and empty stdout/stderr. The parent reports closing with Alt+F4. The receipts independently establish observed clean process exit; they do not by themselves establish the particular close gesture or GUI quality.
- The private recent-model list corroborates four imports: simple boundary, simple SCC control, anchored boundary and local-SCC boundary. Two additional staged SCC controls were not observed natively and are not claimed here.
- Several capture JSON window-title fields lag the actual screenshot title, including the first capture's `Untitled mission` and the fourth capture's old two-container title. These fields alone do not identify the loaded Project. The image's visible title/status path and the recent-model entries provide consistent attribution. All capture metadata names the staged executable and the same window ID.
## Visual findings
**01 — Simple boundary, 102% zoom.** Left A and Left B remain in their canonical upper/lower order. The right children are Right B above Right A. Each connection is a separate horizontal line into its matching child. Both route labels are readable between the containers, and their association with the two separate lines is visually clear. This screenshot supports the intended local ordering improvement without a selection aid.
**02 — Paired simple SCC control, 102%.** Right A is above Right B, so the two connections take opposing vertical travel beside the right children. Their vertical portions occupy the same visible corridor near the right-container boundary; direction and connection identity are substantially harder to follow than in 01. The labels remain legible, so the defect should be described as route association/shared travel, not unreadable label text. No native selection trace of this control is archived; exact endpoints continue to be established by the input model and routed evidence.
**03 — Anchored boundary, 102%.** The improved child order remains, but the authored source/target port fractions produce short downward bends at the right side instead of straight connections. Both label strings remain readable. The white label backgrounds reach and interrupt the Right group's left border near the route corridors. This is a real local visual conflict, but describing it as text obscuring the Right child name, an unreadable label, or a blocked arrowhead would overstate what the image shows. The artifact is principally label-background occlusion of the parent outline. The screenshot supports retaining that limitation rather than promoting the metric's label/node count into an unqualified severe text-collision claim.
**04 — Local SCC boundary, Fit 55%.** The Y1/Y2 pair is grouped above the X1/X2 pair, with Z to the right. The grouping and rank structure are visible, but labels are small at this fitted scale and several routes run close together or merge visually. In particular, the unselected Lower boundary approaches the Y2 region before continuing down toward X1; an unaided quick reading could assign it to the wrong nearby node. Whole-diagram fit therefore preserves overview at a readability cost. This image does not support a general claim that coherent SCC blocks make all individual routes easy to trace.
**05 — Selected Lower boundary, 55%.** The highlighted route visibly runs from Source B, turns downward beside Y2 and ends at X1. The properties pane independently names `Lower boundary`, source `Source B · @source_b`, and target `X1 · @x1`. This confirms that the selected relation has the correct endpoint and that selection supplies a useful tracing aid for this witness. It does not eliminate the ambiguity of the unselected overview or establish the readability of every other local route.
## Scope of the result
The existing five observations support a narrow positive result for the simple two-container case, a modest remaining border/label-background conflict with authored anchors, and an unresolved overview/tracing cost for the local-SCC case. They do not test experimental command integration, Undo/Redo, routing edits, repeated Arrange in the GUI, automatic-side capacity cases, all frozen cases, or general accessibility/responsiveness. Existing numerical and conservation reviews remain separate evidence. No further native investigation is proposed as part of this completed checkpoint.
Screenshot SHA256:
| File | SHA256 |
| --- | --- |
| `01-two-container-boundary.png` | `bc4e28a0fcc37cdc4c904993b67e5b018c66a3a0a2ff7c2511fec324e03d5cd7` |
| `02-two-container-scc.png` | `e1c68d66a4eae12c2e2c056858a1d4fc6b5eec8c387ee39b19337abbce7f49cf` |
| `03-anchored-boundary.png` | `8038656c660d826426c36e059997eb955ef8e84db4bdc2d23bcc214f64580c1d` |
| `04-local-scc-boundary.png` | `677057c6870103daeeb31d48a11a5f9b8b8ebb604a7864e71a541a28d6024342` |
| `05-local-scc-selected-lower-boundary.png` | `732cc188a8e8fbe3632d3bd824f218560c5a40afac053d5f8936e62be2699861` |
@@ -0,0 +1,93 @@
# Incoming boundary order experiment
Issue32, following the SCC checkpoint f4fa0c11. Keep the full OA/SA product goal
and production/native acceptance requirements unchanged. This is one isolated
planner comparison with released routing, not a quality-selected parameter sweep.
## Question and fixed candidate
The SCC planner drops a connection from a sibling group's local graph when the
source is outside that group. Root SCC ranking knows which container is upstream,
but the children have no information for matching order across the boundary.
The existing two-container witness has164 shared units and one label/node
collision, while the old layered candidate's incoming-neighbor order has zero
for both. Preserve the SCC candidate's sparse40 structural improvement while
restoring this missing information.
Start from the same canonical SCC plan, before import. Never change its SCC
membership, condensation ranks, internal perimeter walks, node sizes, gaps or
root layout. In each nonroot same-rank band, bundle undirected-connected SCC
blocks as indivisible units with their existing internal order. Unanchored units
retain their ordinal slots. Reorder only anchored units among their old slots,
then repack by prefix sums of unchanged heights and gaps. Old absolute Y slots
cannot be reused for differently sized blocks. Envelopes are mathematically
invariant; finite arithmetic and exact final projection remain checked bounds.
An anchor is an oriented incoming projected edge whose target lies under the
current sibling group and whose source does not. One distinct visible source
placement contributes one vote per unit, independent of parallel relation count.
Scores are the mean of current planned absolute source-center Y coordinates,
summed in stable placement-ID order using f64. Break equal scores by original
unit order. Undirected external edges supply no invented direction or score.
This is a stated center-based heuristic, not a claim to match final port slots.
A group can change only when a band contains at least two anchored units.
Create dependencies from every such active group that owns an offset along an
external source placement's entire ancestor chain to the consuming group.
Include the immediate containing group; do not invent additional hierarchy arcs.
Condense this influence graph and process its SCC DAG deterministically. Before
each SCC, compose a complete absolute-position snapshot from current offsets.
All member groups calculate proposals from that snapshot before committing any
of them. Each group commits once. Cyclic influence therefore has one simultaneous
step, an explicit limitation rather than an unbounded convergence loop.
Recompose descendants through their ancestor offsets. Perform one final original-
to-final placement import, preserving the existing reset/hidden/retained-route
contract and conditional effective-minimum restoration. Exact final projection
and actual mandatory leads must pass; no size/gap/anchor repair is added.
Apply the existing graph, work and extent bounds to new dependency/snapshot work.
## Controls, falsifiers and acceptance
Retain all14 original cases, their SCC run02 outputs at2426d286 and the original,
Arrange-reset and old-layered controls. Flat/no-boundary outputs, particularly
sparse40 and both mixed-ID cases, must preserve complete Project, geometry and
metrics exactly (new diagnostics are separate). Existing SCC-mode and released
route-mode output must remain byte exact after adding the new observer mode.
The existing two-container witness requires Left A before Left B, Right B before
Right A, with actual route sharing/contact/label improvement assessed against
the old zero-sharing witness. Swapping both groups is not that success.
Add three independent topology falsifiers before execution:
1. Opposing parents: L.A→R.B, L.B→R.A, R.A→L.A, R.B→L.B. Contradictory order
demands must remain deterministic, bounded and explicit; zero crossings is
not an achievable requirement inferred from those demands.
2. Three-parent chain: L.A→M.B, L.B→M.A, M.B→R.A, M.A→R.B. Preserve upstream
L.A<L.B, obtain M.B<M.A and R.A<R.B, and preserve root ranks L<M<R.
Compare relation-ID reversal and a uniform authored subtree translation.
3. Two local two-node SCCs X/Y feeding a singleton Z in a later rank, with
external Source.A→Y1 and Source.B→X1. Order Y before X without splitting
either cycle or changing Z's rank/perimeter geometry.
Also run the existing two-container witness with authored source/target port
anchors. Use meaningful pure tests for heterogeneous-height prefix packing,
undirected bundle preservation and complete source-ancestor influence. These
tests supplement rather than replace actual projected Project cases.
Record complete before/after Projects, dependency graph and SCC batches, source
placement/edge hints, scores, before/after unit and block orders, final derived
ports, geometry and warnings. Reconstruct preservation independently, including
folded latent offsets, anchors, other views and eligible route resets. Check
same-input equality, JSON/source roundtrips and ten full repeated calls. Report
explicit refusals without treating a successful observer process as adoption.
Preserve crossings, all contact types, raw and edge-deduplicated shared intervals,
label/node/label/stroke conflicts, enclosure/penetration, route length and area.
Boundary improvement may worsen internal tracing; cyclic influence can retain
crossings; source centers may disagree with fixed or derived ports. Keep those
counterexamples. Stop this one comparison after independent source/result review.
Production command/API/history integration and native route tracing remain
required before accepting an Arrange replacement. Windows only; Linux remains
excluded, and the existing prerelease remains unchanged.
@@ -0,0 +1,53 @@
# Independent boundary-order result review
Primary `boundary-order-20260925/run01`, source3e21c1bca245944ae0ec7bb02aaa920f45f2cc30. Read-only audit of frozen records; no compiler, routing, engine or native execution. **The boundary-order hypothesis passes its exact simple tracing and propagation witnesses while preserving flat SCC results. It is not a monotonic quality improvement or an accepted Arrange implementation.**
## Integrity and all20 outcomes
Verified15 child receipts exit0/not timed out with matching source pin and stdout/stderr hashes; bound inputs exactly unchanged; capture/build/source agreement; eight control streams independently byte-identical to their frozen released/SCC controls. All20 candidate outcomes are supported. All20 recorded same-input comparisons, nine subsequent calls and JSON/source roundtrips are exact, with empty necessary lead diagnostics. These are recorded executable observations, not independently rerun model operations.
Ten actually flat cases preserve their complete candidate Project and full metrics exactly against the SCC baseline: flat_chain_4, chain_7_row_wrap, diamond, crossed_bipartite, authored_detour_and_label, fixed_ports, long_ordinary_labels, mixed_dispatch, mixed_dispatch_edge_ids_reversed and subsystems_40_sparse. Sparse's32-unit sharing and coherent SCC gains are therefore unchanged, as are mixed's known relation-ID sensitivity and other prior limitations.
The remaining ten outcomes are nested_cross_boundary (metrics unchanged), two_containers_reversed_children, both workshop cases, and six new structural fixtures described below. No failed/unsupported row was omitted. Full Project conservation beyond the flat exact comparisons, including folded latent geometry/anchor policy, is the parent's separate audit; this report does not replace it.
## Exact independent witnesses
- Existing two-container: LeftA<LeftB and RightB<RightA both hold in final projected centerY. Sharing164→0, contacts2→0, label/node1→0, route length788→460, area339852 unchanged. No new crossing, node penetration or warning. The result solves the declared ambiguous trace witness without swapping both groups.
- Three-parent chain and its translated/reidentified variants: LeftA<LeftB, MiddleB<MiddleA, RightA<RightB and rootX Left<Middle<Right all hold. Sharing328→0, contacts4→0, label/node3→0, length1492→836, area523604 unchanged. Complete projected node geometry is exact between the ordinary, translated-subtree and relation-ID-reversed variants. This supports propagation and absence of authored-parent-position dependence for these examples, not all graphs.
- Opposing parents: diagnostics correctly show one cyclic dependency component. One simultaneous snapshot changes the right order; the resulting aggregate quality remains baseline sharing68, contacts2, label/node2, length1028 and area336730. Repeated full calls are stable. The contradictory demands were not falsely asserted to be simultaneously satisfiable or zero-cost.
- Two local SCCs: independently reconstructed exact quotient SCCs/ranks remain intact. Y lies wholly above X and Z remains in a later X rank. This passes the structural criterion, but sharing270→278 and label/node1→3 regress; contacts14→9, label/stroke4→3 and length2956→2656 improve. Area1155248 remains unchanged. Correct order is not sufficient quality acceptance.
- Anchored two-container: expected orders pass, sharing111.200012→0 and contacts2→0; length788→565.599976, area unchanged. **Label/node increases1→2.** Preserve this counterexample to a blanket claim that anchoring plus correct order improves all presentation quality.
For all20 supported results, independently reconstructed sibling quotient SCC membership and condensation rank ordering agree with diagnostics. Independent interval sweeps reproduce all emitted raw pairwise sharing totals and also retain distinct-edge physical sharing. No contact/crossing numbers were independently recomputed in this pass; they are explicitly emitted observations. The inherited folded retrace/raw-sharing distinction remains visible rather than silently changing metric definitions.
For the six extra fixtures, independently verified all edge-hint tuples against original projected edges and recomputed21 unit scores from projected source-owner centerY. Applied dependency components in reported order, taking a common pre-update snapshot inside a cyclic component and updating descendants only after its scores. Every score agrees exactly, including chain scores366/202 followed by202/366 downstream. This verifies the concrete evidence chain for these tests; it is not a general proof of dependency scheduling correctness.
## Real workshop tradeoffs
| Metric | Expanded SCC→boundary | Folded SCC→boundary |
| --- | ---: | ---: |
| Proper crossings |6→7|8→6|
| Point contacts |16→15|28→28|
| Raw shared length |344→352|726.5→1077.5|
| Label/node |3→3|3→3|
| Label/stroke |1→1|2→1|
| Route length |7950→7794|8137→8137|
| Drawing area |1600772→1524784|1169964→1127988.592529|
Both retain zero emitted unrelated node penetration/overlap; expanded warnings remain0 and folded warnings remain the same four promoted-endpoint warnings. Expanded gains in length/area/contact count coexist with a new crossing and more sharing. Folded fewer crossings/label-stroke contacts coexist with a351-unit sharing increase. The real-case evidence therefore rules out unconditional quality adoption from the synthetic success alone.
## Decision and next boundary
Retain incoming boundary ordering as a useful mechanism and preserve the one-run evidence. It meets the declared two-container and chained-parent order/tracing targets without disturbing flat SCC geometry. Do not tune this run to remove the counterexamples, and do not describe20 supported/stable cases as20 improved layouts.
Before production integration, investigate the specific new label/node collisions in the anchored and local-SCC witnesses and the newly shared folded workshop routes. Any selection policy must preserve hard geometry/model constraints and make quality tradeoffs explicit; merely choosing the lowest crossing count would favor the folded result while hiding substantially more coincident routing. A local label-aware coordinate/route check or conditional order acceptance is a distinct future design decision, not validation supplied by this run. Native tracing, renderer glyph/header legibility, navigation cost, command/history integration and release acceptance remain outstanding.
No production source change or additional candidate execution was performed by this audit.
- .local\audit-boundary-order-20260925.py: SHA256 96bb938961255b59add3922f2cc8b30ddc7ec127d77ab1d7b61974e116930432.
- .local\audit-scc-placement-v3-20260925.py: SHA256 8b238f010eeb81720a59a0ad290544f87934acb8070e58a3fd25f9eda9f47a0d.
- .local\boundary-order-independent-audit-20260925.json: SHA256 914e39cf9297ab025927b9ba9bae02adee157e3dc7061058e67ee280cb6cb212.
- .local\boundary-order-20260925\run01\receipt.json: SHA256 9aeaeedd81d968d353c48fc32126c7644c452e3b0679ac67ab4fbad7f985ba49.
@@ -0,0 +1,65 @@
# Incoming boundary ordering: experiment results
**Incoming boundary ordering solves the simple two-container and chained-parent tracing witnesses while preserving the flat SCC results. It does not improve every view and is not an accepted replacement for Arrange.** The candidate remains isolated in the example probe; production commands and released routing are unchanged.
Tested source: `3e21c1bca245944ae0ec7bb02aaa920f45f2cc30`. The fixed candidate, scope and alternatives are in [plan](plan.md). See [source review](source-review.md), [independent result review](result-review.md), [conservation review](conservation-review.md), and [native observations](native-observation.md) for their separate evidence scopes.
## Question and method
The preceding SCC candidate made cyclic groups coherent but discarded external incoming-neighbor information when ordering children inside different parents. The new mechanism orders eligible sibling SCC blocks using those incoming sources, without changing condensation ranks, internal SCC walks, stored hierarchy or the router. Parent dependency components determine the processing order; cyclic components use one common snapshot. This is a single predeclared candidate, not a parameter sweep or fixed-point convergence claim.
The run contains15 child processes: released routing control, existing small controls, SCC small control, boundary small fixtures, six paired extra fixtures in one stream, and SCC/boundary pairs for five frozen corpus cases. All15 exit0 with unchanged bound inputs. Eight control streams are byte-identical to their previous released/SCC versions. Candidate outcomes are reported separately from process exit status.
All20 cases return candidates and record exact same-input reproduction, nine subsequent calls equal to the first result, and exact JSON/source roundtrips. Necessary lead diagnostics are empty. Independent analysis reconstructs SCC membership and condensation order and reproduces raw collinear-sharing totals; it also retains edge-deduplicated physical sharing so folded route retracing is not hidden. Twenty-one extra-fixture ordering scores and their edge-hint endpoints were independently checked against projected source positions.
## Outcomes against the SCC control
| Case or group | Observed result |
| --- | --- |
| Ten flat cases | Full candidate Project and full metrics exactly unchanged. Includes sparse40 and both mixed relation-ID variants. |
| Nested cross-boundary small fixture | Quality metrics unchanged. |
| Two containers, reversed children | Required LeftA<LeftB / RightB<RightA order; sharing164→0, contacts2→0, label/node1→0, length788→460; area unchanged. |
| Three-parent chain and its translated/reidentified variants | Required orders propagate through all three parents; sharing328→0, contacts4→0, label/node3→0, length1492→836; area unchanged. Projected node geometry is exact across all three variants. |
| Opposing parent dependencies | Stable bounded result under conflicting demands; aggregate quality unchanged: sharing68, contacts2, label/node2. No claim that all demands become simultaneously satisfiable. |
| Two local SCCs | Y precedes X without splitting SCCs or changing Z's later rank. Contacts14→9 and length2956→2656 improve; sharing270→278 and label/node1→3 worsen. |
| Anchored two-container variant | Required order and exact authored-anchor contract; sharing111.200012→0 and contacts2→0, but label/node1→2. |
| Expanded workshop | Crossings6→7, sharing344→352; contacts16→15, length7950→7794 and area1600772→1524784. Label/node3 and label/stroke1 remain. |
| Folded workshop | Crossings8→6 and label/stroke2→1; sharing726.5→1077.5, contacts28 unchanged. Four promoted-endpoint warnings remain. |
The ten flat cases are flat_chain_4, chain_7_row_wrap, diamond, crossed_bipartite, authored_detour_and_label, fixed_ports, long_ordinary_labels, mixed_dispatch, mixed_dispatch_edge_ids_reversed and subsystems_40_sparse. Their exact preservation retains both the preceding sparse improvement and its unresolved label issues, as well as mixed's existing ID-sensitive routing differences.
All candidates report zero unrelated node penetration and node overlap. This necessary geometric safety is not proof of label readability or easy tracing. The anchored/local-SCC label regressions and workshop sharing/crossing tradeoffs prevent a blanket quality-pass claim. Complete model conservation, dormant routing metadata and folded latent geometry are assessed separately in the linked conservation review.
## Native observation and limits
The parent's observation covers four Projects and five captures, including a selected lower boundary connection. It supports the improved simple-case trace appearance. In the anchored case, readable label text/backgrounds interrupt a parent border; the local-SCC traces remain difficult at55% zoom. These are bounded visual observations, not evidence that all labels or real workshop tasks pass. The linked native note records the exact artifacts/actions and is authoritative for those claims.
Compilation, successful candidate construction and repeated stability do not establish production readiness. The mechanism does not solve every conflict, and lower crossing count can coexist with more shared ink. No release replacement, issue closure, production command/history integration or general readability acceptance follows. Stop this frozen experiment; retain its counterexamples before selecting further label/connection placement work.
## Reproduction
Use the tested source pin and the recorded Windows native toolchain/environment. Focused gates29–31 pass15 example tests, strict Clippy and the optimized probe build:
```text
cargo test --locked --offline -p oa-core --example auto_layout_probe
cargo clippy --locked --offline -p oa-core --example auto_layout_probe -- -D warnings
cargo build --release --locked --offline -p oa-core --example auto_layout_probe
```
Earlier gates27–28 at `42f595a5d6df92432aaf6965194bf651cd9b8b6d` retain14 passing focused tests and strict Clippy. They are earlier-source evidence, not additional tests at the final pin. No broader test-suite or performance claim is made.
The portable probe interfaces used by the runner are:
```text
auto_layout_probe --route-corpus MANIFEST
auto_layout_probe
auto_layout_probe --scc-fixtures
auto_layout_probe --boundary-fixtures
auto_layout_probe --boundary-extra-fixtures
auto_layout_probe --scc-placement PROJECT_JSON DIAGRAM_UUID
auto_layout_probe --boundary-placement PROJECT_JSON DIAGRAM_UUID
```
The extra-fixture stream carries paired baseline/boundary records. Named corpus rows are associated with their runner case paths, not the generic external_case label. Each child has a90-second timeout; measured durations here are process receipts, not controlled latency benchmarks.
The [evidence manifest](evidence/manifest.json) binds all156 archive members: exact inputs, receipts/logs, audits, native captures and collectors. [Archive](evidence/boundary-order-3e21c1bc.zip):4,310,136bytes, SHA256 `bb6b896ff2401290869a904f7768ebb52b6f0ab36fada06badbe9abb301c37b8`. The [independent native review](native-review.md) bounds the visual claims and documents stale capture-title metadata. Reproduce the independent result audit with `audit-boundary-order-20260925.py RUN_ROOT UNIQUE_OUTPUT_JSON`; its explicit `audit-scc-placement-v3-20260925.py` helper must accompany it. Original controls and full candidate Projects/geometry must remain available; summary tables alone are insufficient to reproduce the comparison.
@@ -0,0 +1,62 @@
# Incoming boundary order source review
**Final source verdict at `3e21c1bca245944ae0ec7bb02aaa920f45f2cc30`: no unresolved material findings.** The complete-displacement precision defect found in the initial pin is repaired and independently re-reviewed below. This accepts the source for the bounded experiment, not layout quality, repeated-call stability, production integration or release readiness.
Independent source review of `42f595a5d6df92432aaf6965194bf651cd9b8b6d`, 2026-09-25. Inspected the clean pinned worktree, `harness/experiments/boundary-order-20260925/plan.md`, `crates/oa-core/examples/auto_layout_probe/condensed.rs`, its `condensed/boundary.rs` module, `boundary_fixtures.rs`, and the observer/CLI changes in `auto_layout_probe.rs`. No source edits, compiler, engine/router execution or GUI work. One read-only PowerShell single-precision arithmetic calculation confirms the finding below. Runtime gates belong to the parent and are not claimed by this review.
## Initial verdict at 42f595a5
The implementation follows the settled dependency-SCC ordering policy, with one bounded numerical preservation finding: the final member translation guard checks addition precision but does not check the precision lost while subtracting the old block origin. Fix or explicitly narrow that claimed bound before treating source review as complete. No semantic SCC, projected endpoint, dependency scheduling, undirected bundle or importer-boundary defect was found by this review.
## Resolved finding: guard the complete intended displacement
**P2, `condensed/boundary.rs:358` and `:73`.** `let delta = y - old` rounds the requested block-origin displacement to f32. `translate(value, delta)` then compares the actual addition against that already-rounded displacement. An exact addition can therefore pass even when the member no longer preserves its original offset from its block origin within the declared 0.001 bound.
Concrete single-precision witness:
| Quantity | Value |
| --- | ---: |
| Old block Y | 65536 |
| New block Y, f32 representation of 100.002 | 100.00199890136719 |
| Original member Y, block + 32 | 65568 |
| Computed f32 delta | -65435.99609375 |
| Returned member Y | 132.00390625 |
| Current translate-check error | 0 |
| Member-relative-offset error | 0.0019073486328125 |
These coordinates fit the planner's 100000 extent. A reachable prefix setup uses heights `[65404, 68, 100, 68.002]`, gap 32, original block origins `[0, 65436, 65536, 65668]`, and reversed order `[3,2,1,0]`. The original third block moves from 65536 to approximately 100.002. Every new starting prefix is small, so the packing cast bound does not independently eliminate the witness. The importer checks the resulting node plan against projection; it does not compare the members against their declared block-origin displacement, so that final guard is not a substitute.
Recommended narrow repair: give the translation helper old and new block origins and compare the final f32 member coordinate to `f64(value) + f64(new_origin) - f64(old_origin)`. Reject if the total displacement error exceeds 0.001. A direct regression should cover the witness, alongside the existing addition-rounding case. This is a correctness guard repair, not a layout-quality change or a reason to relax projection equality.
## Confirmed control flow and invariants
- Root isolation is structural: only `Some(parent)` groups are passed to the new module. Root offsets, sizes, semantic component membership, ranks, perimeter walks and gaps remain owned by the existing canonical planner.
- Units come from connected components of bidirectional same-band undirected arcs. The existing canonical BFS order is retained, and noncontiguous bundles are rejected. Sorting permutes whole units; unanchored unit identities retain ordinal slots. Flattening a reordered unit sequence retains each bundle's internal block order.
- Boundary membership uses projected edge endpoints and the same ancestry lift operation as the SCC planner. Only oriented edges entering the group from outside supply anchors. Deduplication uses visible source placement IDs in a BTreeSet, rather than relation IDs or unprojected semantic owners. Edge hints affect diagnostics only.
- `offset_owner` maps every direct child placement to its ordering group. Dependency walks begin at the source placement itself and inspect every ancestor, including the immediate containing group. Restricting graph vertices to groups with at least two anchored units is sound under fixed unanchored slots. No additional hierarchy arcs are invented.
- Dependency SCCs are condensed and processed in deterministic topological order. Every score for a complete SCC is materialized before any offset commits. Commits touch disjoint directly owned offsets; source center recomposition subsequently reads all current ancestor offsets. Cyclic SCCs therefore use the declared common snapshot without a hidden traversal-order preference.
- Center composition now follows the final plan's f32 child-to-root addition order, then adds the root origin and converts to f64 for half-height and mean computation. This resolves the preliminary review concern about scoring a different absolute-position arithmetic path.
- Packing uses unchanged dimensions and gaps, rebuilds prefix positions rather than reusing old heterogeneous slots, and checks canonical prefix consistency, cast precision and total extent. An unchanged order retains its original f32 origins. Mathematical envelope invariance is supported; the unresolved member-displacement finding above is distinct.
- Edge scanning, ancestry traversals, component discovery, dependency traversal, topological scans, source-center reconstruction and member commits charge the shared bounded work counter. The existing visible/stored graph bounds and final extent guard remain. This is a weighted work bound, not an instruction-count or elapsed-time guarantee.
- The module only mutates the local plan. `candidate_policy` imports once after all reordering; the existing exact reprojection, effective-minimum restoration, original-to-final route handling and final mandatory-lead check remain unchanged. A refusal cannot partially mutate the caller's Project.
- The original SCC mode takes the false policy branch. By source inspection its planner and emitted observer structure are unchanged; byte equivalence still requires the planned controls. The new extra-fixture CLI emits both baseline and boundary observations rather than presenting its process exit as candidate acceptance.
## Test and fixture assessment
The pinned source adds six module tests. The ancestor-dependency test deliberately gives the downstream parent a lower ID, so omitting the grandparent influence arc would produce a wrong downstream permutation; it exercises actual `reorder`, not merely center arithmetic. The undirected test exercises a whole bundle around an unanchored unit, heterogeneous prefix packing, and deduplicated source owners. Other tests cover anchored ties, ordinary heterogeneous swapping, ancestor coordinate composition, final-plan f32 evaluation order and addition precision rejection. These are meaningful mechanism checks by inspection; this review does not claim they have run.
Projected fixture additions cover opposing parents, a three-parent propagation chain, relation-ID reversal, authored subtree translation, two local SCCs with a downstream singleton, and authored endpoint anchors. They support the declared experiment. They do not establish general automatic-side capacity stability, dormant authored-route coverage, native readability, production command/history integration or release readiness.
The result review must retain cyclic conflicts, source-center versus attachment-order mismatch, internal-rank versus boundary preference conflict, exact repeated-call stability, semantic/route conservation, and the complete quality vector. The mathematical ordering properties alone do not establish those outcomes.
## Repair re-review at 3e21c1bc
Independently inspected the clean pinned worktree and the complete diff from `42f595a5d6df92432aaf6965194bf651cd9b8b6d` to `3e21c1bca245944ae0ec7bb02aaa920f45f2cc30`. The only source change is the intended precision repair and its regression. No source edits or compiler/engine execution were performed by this reviewer.
`translate` now receives the old and new block origins. It calculates `f64(value) + (f64(new_origin) - f64(old_origin))`, converts that complete intended coordinate to f32, and rejects if the final coordinate differs by more than 0.001. The commit site no longer constructs or adds a rounded f32 delta. This closes the demonstrated subtraction-rounding loophole without changing ordering, scores, sizes, gaps or projection rules.
The new `member_offset_survives_large_origin_subtraction` test uses the complete four-block prefix witness, reverses its order, and checks preservation of the third block member's 32-unit offset after the move. The earlier precision rejection and center-composition tests remain. There are now seven boundary module tests by source inspection. Their execution is parent-owned; this source review does not import earlier gate success from another commit as evidence for this pin.
Reviewed `condensed/boundary.rs` SHA256 at the repaired pin: `c6b17ac1e16bc1d12fe3625d4633c83891f8c0bd7716c96c31295cae0f8588da`.
The initial finding above is retained as evidence and is **resolved at 3e21c1bc**. No further material source issue was identified. The runtime/quality and coverage limits stated above remain unchanged.
@@ -0,0 +1,36 @@
# Independent reference-adapter review
2026-09-25. Static review only; no engine/compiler/router/GUI execution or source edits. Parent owns JavaScript review and execution. Reviewed local experiment plan, Python supervisor, Rust importer diff and adjacent baseline/prototype observation contracts. Read the JavaScript output-check interface only to establish where importer preconditions are enforced.
**Verdict: no blocking source defect found for the frozen five-case diagnostic run, subject to consuming structurally passing outputs and the explicit post-import checks below.** This is readiness for experiment execution, not adapter fidelity, native traceability, or production acceptance. Compilation remains unverified here.
Reviewed SHA256:
- Plan `.local/connection-layout-reference-plan-20260925.md`: `41a420db7ee039fa424f60b61097bddc6eff787e2705004e1c88b19f8b97c371`.
- Supervisor `.local/run-elk-reference-20260925.py`: `114d2fd4dbc9a55cd57c4b5175989686dc413863fc2a62fa4a71278792937066`.
- Importer `crates/oa-core/examples/auto_layout_probe.rs`: `95666ce866111d0626e964483fc954276e258bd0ef61a4f96b9857a0ceab468e`.
- Rehashed frozen released geometry: `9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2`, matching the parent's declared input.
## Concrete checks and result-consumption requirements
1. **Freeze pin improvement:** the supervisor asserts manifest and bundle pins and records all other bound hashes, including geometry, before/after. It does not assert the expected geometry SHA above. Add that single expected-input assertion before execution; otherwise a different preexisting geometry file can be consistently recorded without matching the intended frozen dataset. Current inspected bytes do match, so this is a narrow provenance improvement, not an observed wrong input. No generalized dependency framework is needed.
2. **Only import structurally passing output.** Rust `import_placement` rejects unsupported Scenario, schema mismatch, excess nodes/edges, missing/extra/duplicate IDs, nonfinite/nonpositive rectangles and translated nonfinite positions. It deliberately has no independent minimum-size/header/child-containment checks and no parent field in `PlacementPlan`; those gates are supplied by JavaScript inspection. Parent must require the per-case structural result and success receipt before extracting `{schema:1,nodes:[{id,position,size}]}`. Do not rank a transferred failed structural result as an ordinary candidate. Core validation is not a substitute for those geometric checks. Reprojected Rust bounds should also be compared with intended transferred bounds to detect core size normalization.
3. **Compare final physical ports, not only unchanged anchors.** Importer does not import ELK port positions; its final projected ports are therefore the right raw material for comparing owner/semantic-port identity and final intended tip to ELK's output. Unchanged authored fraction and unchanged ELK relative pixel offset can still diverge after compound resizing. Plan correctly declares this a transfer limitation requiring assessment. A candidate with such divergence is not evidence of faithful fixed-port optimization, even if both separate geometries validate.
4. **Use the matching baseline.** The existing `observe` result's `after` is released Layout without the new reset. The comparable baseline is `reset_only_control`, which clears effective routes after that Layout. The old prototype and importer clear using pre-operation eligibility, while the control's legacy helper uses post-Layout routed `!custom_suspended`. For the frozen unchanged-visibility cases this may agree, but verify actual eligible edge sets and resulting route records before attributing differences solely to placement. Do not relabel the old `after` metrics as reset-only.
5. **Conservation summary does not prove the route contract.** `conservation` masks routes and node geometry for broad semantic comparisons; `authored_routes_exact=false` is expected after reset. Independently compare complete per-edge records: entry/order, attachments, exact eligible reset, and retained `translated_routes` result. Roundtrip and conservation booleans are emitted observations, not asserted by the CLI; consuming analysis must inspect them. Exit0 alone does not pass them.
## Importer correctness within this scope
Eligibility is captured from the original projection before movement and requires actual owners equal projected endpoints with both visible. The importer clones the original, changes only selected-view node geometry, clears eligible pins/full labels, and applies the existing original-to-final `translated_routes` helper only to retained routes. Entries are updated in place; route order and endpoint attachments are preserved. Other views and semantic records remain untouched by construction.
The revised collapsed rule is appropriate: compare proposed size to the original compact projected size exactly, update position, preserve stored expanded size. Temporary unfolding is used only to recover core visual ancestry, including Allocation grouping; it is not returned or used to change visibility. Hidden nodes found under a visible collapsed ancestor receive that ancestor's translation, preserving their latent relative geometry. The ancestry walk is bounded and detects cycles/missing parents. This implementation does not establish a general policy for unrelated filtered descendants omitted even from the unfolded projection; the stated policy leaves unrelated omitted placements exact. Do not extrapolate beyond the frozen fixtures.
The importer cannot reverse semantic edges or accept replacement ports because neither exists in its plan schema. Its 256 stored-node /1024 visible-edge limits and Scenario refusal are explicit. Original-to-final positional deltas are calculated before retained-route translation; no intermediate Layout or independently validated Batch prefix is introduced. This remains an example-only geometry transfer, not a new production command or history implementation.
## Supervisor and attribution
The supervisor creates a fresh output directory and exclusive log files; each engine case has a separate subprocess with a90-second timeout. Python's `subprocess.run` timeout kills/waits for its child and the loop retains an explicit timeout/error receipt before proceeding. The reviewed contract uses the bundled engine in that Node process; this is not a general descendant-process supervisor. Before/after bindings cover Node, adapter script, geometry, manifest, bundle, dependency receipt, plan and supervisor. JavaScript receipts separately hash raw case/graph/mapping/result/observation files. Parent should retain both receipt layers.
The supervisor can exit0 even when individual cases fail or time out; its final record explicitly preserves those outcomes. Require every expected case receipt, no timeout, success plus structural checks before treating that case as transferable. Failed/unsupported cases stay visible in the comparison. Timing includes process work and is correctly disclaimed against earlier Rust route-only timings.
The plan correctly limits the claim to whether engine placement transfers usefully through released routing and label placement. Raw ELK routes/labels are diagnostic, never secretly turned into authored constraints. Estimated label extents, fixed-position port drift, prototype folded refusal and absent native trace acceptance remain real limitations. A failed placement transfer cannot reject ELK's complete coupled drawing architecture; a scalar gain cannot establish an engineer's correct trace or label association. No request is made for new fixtures, option sweeps, production dependencies or additional architecture before this bounded run.
@@ -0,0 +1,40 @@
'use strict';
const assert = require('node:assert/strict');
const fs = require('node:fs');
const crypto = require('node:crypto');
const {adapt, inspect} = require('./reference_probe.cjs');
const nodes = [
{id:'parent', element:'ep', visual_parent:null, collapsed:false, position:{x:100,y:200},size:{width:300,height:300}},
{id:'child', element:'ec', visual_parent:'parent', collapsed:false, position:{x:124,y:264},size:{width:100,height:80}},
{id:'sink', element:'es', visual_parent:null, collapsed:true, position:{x:600,y:264},size:{width:100,height:80}},
];
const ports = [
{owner:'child',element:'out',side:'Right',position:{x:224,y:304}},
{owner:'sink',element:'in',side:'Left',position:{x:600,y:304}},
];
const edges = ['one','two'].map(id=>({id,oriented:true,source:'child',target:'sink',source_port:'out',target_port:'in'}));
const row = {fixture:'synthetic',diagram:'d',before_project:{diagrams:{d:{nodes:Object.fromEntries(nodes.map(n=>[n.id,n]))}}},
before:{projected_nodes:nodes,projected_ports:ports,projected_edges:edges,
routed_edges:edges.map(e=>({id:e.id,label:{text:e.id,size:{width:30,height:24}}}))}};
const {graph,mapping} = adapt(row);
assert.equal(mapping.ports.length,2);
assert.equal(graph.edges[0].sources[0],graph.edges[1].sources[0]);
const result = inspect(graph,mapping);
assert.equal(result.structural_checks_passed,true);
assert.deepEqual(result.nodes.find(n=>n.id==='child').position,{x:124,y:264});
assert.deepEqual(result.ports.find(p=>p.owner==='child').position,{x:224,y:304});
const badSize=structuredClone(graph); badSize.children.find(n=>n.id==='sink').height+=1;
assert(inspect(badSize,mapping).checks.some(c=>c.name==='collapsed_compact_size_exact'&&!c.passed));
const underHeader=structuredClone(graph); underHeader.children[0].children[0].y=2;
assert(inspect(underHeader,mapping).checks.some(c=>c.name==='child_inside_parent_body'&&!c.passed));
const reversed=structuredClone(graph); reversed.edges[0].sources=['sink'];
assert(inspect(reversed,mapping).checks.some(c=>c.name==='edge_orientation_and_endpoints'&&!c.passed));
const missing=structuredClone(row); missing.before.projected_edges[0].source_port='unknown';
assert.throws(()=>adapt(missing),/Missing projected semantic port/);
const undirected=structuredClone(row); undirected.before.projected_edges[0].oriented=false;
assert.throws(()=>adapt(undirected),/Unsupported undirected/);
const duplicate=structuredClone(row); duplicate.before.projected_nodes.push(duplicate.before.projected_nodes[0]);
assert.throws(()=>adapt(duplicate),/duplicate/);
console.log(JSON.stringify({checks:'passed',scope:'synthetic adapter mapping only; engine not invoked',
checks_exercised:['nested coordinate roundtrip','shared physical port reuse','collapsed size rejection','header intrusion rejection','edge reversal rejection','missing semantic port rejection','undirected rejection','duplicate node rejection'],
adapter_sha256:crypto.createHash('sha256').update(fs.readFileSync(require.resolve('./reference_probe.cjs'))).digest('hex')}));
@@ -0,0 +1,56 @@
# Connection-aware arrangement: independent criteria and next experiment
Proposed engineering decision for issue32, 2026-09-25; not an accepted requirement, production adoption, or native acceptance. Read the frozen independent routing results, decision-review and adoption-rubric under `harness/experiments/routing-independent-20260925` at local auto-layout HEAD `ac5d7ef34a567f45b72adbd30d1a243f5811ba73`, and reset `crates/oa-core/src/session.rs::layout` at `956e33e568c6b799d0330803c74927e205977dfd`. No code, compiler, router or GUI execution in this review.
**Recommendation: run the bounded ELK placement-reference comparison on the existing frozen five-case corpus.** Compare current Arrange/reset placement, the existing native layered prototype, and ELK-derived node placement through the unchanged released Rust router and label placement. Freeze one ELK configuration and adapter policy before results. This tests a missing architectural choice; further J/L coefficient or lane tuning does not.
## What the existing evidence establishes
Current Layout orders roots from projected connections, but places roots in rows of four and stacks children vertically; it does not use routed conflicts or label extents when placing them. Reset removes eligible authored bends and labels, making a new route possible; it does not make those node positions connection/label-aware.
The routing-only results are useful counterexamples to a scalar objective. L reduces workshop shared length1042→602 while adding a label/node and label/stroke collision. Reversed mixed IDs change132→233.5999756 shared length; sparse reduces496→372 but proper crossings24→25. Timing screens pass, and these finite outcomes do not identify either J or L as a general improvement. The retained released router remains a controlled reference, not a quality oracle.
Raw contacts, shared intervals, crossings and collision identities locate potential reading problems. They do not measure whether an engineer follows the intended connection: a short ambiguous junction at a decision point can matter more than a long common-terminal stub; a correct readable crossing can be preferable to coincident edges. Pairwise shared length also counts pair multiplicity, not just unique occupied ink. Area, bends and length expose costs; none identifies correct label-to-edge association or legible arrowheads. Keep raw quantities and concrete identities, with no weighted quality-pass total.
## Architecture choices and falsifiers
| Choice | Useful hypothesis | Smallest decisive contrary observation |
| --- | --- | --- |
| Connection-aware placement, then released routing and label placement | Better sibling order, layering and space allocation remove the dominant conflicts without a new routing architecture. | A faithful placement improves graph order but the released routing/label stage repeatedly recreates the named ambiguity, with no trace-task gain. This falsifies sufficiency on these cases, not every possible placement algorithm. |
| Bounded placement/routing/label feedback | A small number of specific gap/order corrections can repair conflicts left by the first pass. | A repair relocates ambiguity to another required task, or repeated passes oscillate/expand the scene without eliminating the conflict. Do not start this loop before identifying a concrete failed constraint from the placement comparison. |
| Coupled external engine output, including routes and labels | Jointly reserving routes and label space achieves benefits lost by independent downstream routing. | Engine output cannot faithfully express fixed ports, compound geometry or projection semantics, or its apparent visual gain depends on violating them. A placement-only failure is insufficient evidence against this choice. |
ELK Layered is a relevant reference because it explicitly supports ports, labels and compound graphs; this is a capability basis for the experiment, not a predicted win. [ELK Layered](https://eclipse.dev/elk/reference/algorithms/org-eclipse-elk-layered.html)
## One bounded comparison
1. Keep the existing five input Projects and their manifest hashes. Reuse the declared source-to-target tasks, including companion fan-out branches and the fixed ID permutation. Do not add favorable graphs or change names/IDs after viewing outputs.
2. Use one common reset policy for all three placement arms: eligibility captured from the original staged projection; eligible stored pins/full label cleared; attachments retained. Apply existing `translated_routes` to retained routes using each arm's actual final deltas. Current Arrange/reset is the baseline. Comparing an unreset baseline with a reset candidate would confound placement with stale-constraint removal.
3. Freeze engine/version, options, seed, input ordering, dimensions and mapping policy. Run the existing native prototype unchanged. Its folded/omitted-node rejection is an unsupported result, not permission to unfold the Project or omit the case from the table. Report supported subsets explicitly.
4. Emit the final cloned Project plus real Rust projection/routes/labels for each supported arm, and the unchanged raw ELK input/output. Preserve ELK edge sections and label locations for diagnosis, but do not store them as authored Project bends/labels in the placement-only arm. Engine labels can influence spacing while the displayed Rust label lands elsewhere; such a result must not be described as successful label placement.
5. Audit adapter invariants before quality ranking. Reuse independent contact metrics; inspect every changed collision/warning identity. Run the same predeclared trace tasks against the actual rendered result for any candidate that advances beyond geometric screening. Keep all failures and unsupported outputs.
6. Stop after this fixed comparison and concrete adapter-defect repairs. No option sweep, per-case best seed or penalty tuning. A faithful ELK placement gain motivates a production-placement decision; a faithful failure localizes what placement alone did not solve. If raw ELK output looks better but Rust rerouting loses the benefit, the next bounded question is transferring or reproducing that coupling, not more node-order heuristics. Raw output is diagnostic evidence only until rendered and audited with equal constraints.
## Adapter gates that can invalidate the experiment
- **Placement identity and hierarchy:** map by placement identity, not semantic element alone; a view can place the same semantic entity more than once. Use actual projected visual parents and visible endpoints, while preserving the authored containment model. Convert every nested local coordinate to Project coordinates exactly once. ELK distinguishes child shapes and edge sections; preserve its raw coordinate representation for diagnosis. [ELK JSON format](https://eclipse.dev/elk/documentation/tooldevelopers/graphdatastructure/jsonformat.html)
- **Cross-container edges:** explicitly configure hierarchy handling. Root default behavior separates children, whereas `INCLUDE_CHILDREN` allows one run across hierarchy levels. A silently flattened graph or independently laid-out children would not test compound connection-aware arrangement. [ELK hierarchy handling](https://eclipse.dev/elk/reference/options/org-eclipse-elk-hierarchyHandling.html)
- **Port identity:** one adapter port per physical projected placement/semantic-port identity, reused by its multiple edges. Duplicating shared ports per edge makes fan-out artificially easy; merging distinct ports changes the problem. Keep direction and semantic edge identity through any engine cycle reversal; never write a reversed semantic source/target back to Project.
- **Port position and resizing:** preserve authored side/fraction and dormant explicit attachments. Compare final Rust physical port tips to the adapter's final intended tips, not to original global coordinates that should move with nodes. ELK exposes both `FIXED_RATIO` and `FIXED_POS`; select a verified policy rather than treating them as synonyms. Fixed original pixel offsets on a resized container can cease to match our fractional anchor. Either demonstrate final-size fraction mapping, or mark that case unsupported; post-correcting only Rust ports makes the optimizer's assumed geometry stale. [ELK port constraints](https://eclipse.dev/elk/reference/options/org-eclipse-elk-portConstraints.html)
- **Node sizes and occupied content:** preserve leaf minimum sizes, container body/header/footer clearances, port extents and State row geometry where applicable. Compound resizing is an explicit geometric output and must contain children below the header. ELK supports fixed size constraints, but these do not by themselves supply ARCADIA's content rules. [ELK node-size constraints](https://eclipse.dev/elk/reference/options/org-eclipse-elk-nodeSize-constraints.html)
- **Labels:** supply the same declared label text/dimension policy across arms; ELK generally expects label dimensions from its caller. Estimated rectangles remain screening evidence. Preserve full text and use actual rendered ink for readability acceptance. Do not promote ELK label coordinates into persisted authored overrides to improve this arm. [ELK JSON labels](https://eclipse.dev/elk/documentation/tooldevelopers/graphdatastructure/jsonformat.html)
- **Folded and dormant geometry:** use promoted visible endpoints for planning, but do not replace actual semantic ownership. Retain dormant route metadata with the existing translation rule, and preserve collapse/filter state. If moving/resizing a folded owner requires a hidden-placement transform the adapter cannot represent faithfully, report unsupported rather than shifting hidden geometry opportunistically. Other views remain exact.
An identity import/export without layout should recover the exact Project; only explicitly permitted geometry/reset fields may differ after layout. Validate Projects and independently audit output IDs, finite geometry, container containment, endpoints and anchors. Passing `validate_candidate` alone cannot prove geometric containment or adapter fidelity.
## Proposed acceptance gates
**Preservation is a hard gate.** Semantic elements, relations, endpoints, roles, authored ownership, aliases/text/source meaning, projection/filter/fold state, route entry order and attachment data remain exact. Only selected-view arrangement geometry and eligible pin/full-label reset change; ineligible pins follow existing translation rules, including the State boundary exception. Hidden placement handling follows the declared Layout scope, not a blanket “hidden never moves” rule. Missing actual owners, filtered edges and promoted endpoints are ineligible for reset. Other views stay exact. After integration, enclosing Batch remains one transaction; a valid pending property Apply is a separate history action; invalid drafts block Arrange; clean Undo/Redo and persistence/source round trips retain the established contract. This experiment does not change Process/Scenario path behavior.
**Geometric screening is identity-aware.** Reject new missing routes, nonfinite geometry, invalid containment, unrelated node/header penetrations, or new warnings absent a specifically documented unavoidable constraint. Retain existing failures per edge. Report actual new/resolved label collisions and contacts, not net totals. Do not require zero crossings on arbitrary graphs or count intended ancestor-body containment as an obstacle defect.
**Traceability is the adoption gate.** For every frozen named task, the reviewer must identify the correct source, target, direction and associated connection label in the rendered diagram. Include both branches of shared ports and both distinct ports; inspect actual arrowheads and text. Record wrong turns, ambiguity, selections, pan/zoom and completion time. Normal selection is allowed but record whether unselected geometry was ambiguous and whether selection repaired it. Use the same declared readable scale and viewport, plus Fit for overview; unlimited zoom must not hide unusable navigation cost. Require an observed improvement in a declared task or correction of a baseline failure, with no new failed/ambiguous task. If both layouts already complete every task cleanly, do not manufacture a correctness win from a smaller scalar score; report clarity/action costs descriptively.
**Robustness and cost are separate.** Same-input repeats must be deterministic; ten repeated Arrange applications should settle rather than ratchet size or oscillate. The fixed edge-ID permutation must preserve semantics and task correctness; pixel-identical output for every graph symmetry is not required. Timing must cover placement plus Rust routing/label work, and report engine startup/serialization separately and as end-to-end cost. Existing route-only timing ceilings do not establish acceptable total Arrange latency. Declare any new end-to-end budget before timing; disclose unsupported cases and censored runs.
This comparison can reject an architecture assumption or justify one next prototype. It cannot establish universal optimality, all-Unicode label measurement, arbitrary graph scalability, or native usability from screenshots/metrics alone. It requires no production dependency on JavaScript and makes no recommendation to ship ELK before the adapter and trace evidence exist.
@@ -0,0 +1,32 @@
{
"package": "elkjs",
"version": "0.12.0",
"registry_url": "https://registry.npmjs.org/elkjs/0.12.0",
"tarball_url": "https://registry.npmjs.org/elkjs/-/elkjs-0.12.0.tgz",
"integrity": "sha512-YZcKynxVxYoKIOEpywEPwCFdg+BTbxQRNf3pbwdDCvc8O3kQD8bmIwSxKU1eOTVc4Xo+VG9Te+575mlfvOrhEQ==",
"tarball_sha256": "c1d7719723e020b10724e3ccbc935696a2884f1e78d361cdd03766309e8e8e2a",
"license": "EPL-2.0 OR GPL-3.0-or-later",
"members": [
{
"path": "lib/elk.bundled.js",
"bytes": 1609707,
"sha256": "1222e44f953ce7746af23801e723708f8e6f436b8b377a6a5fc7552f34a307b3"
},
{
"path": "package.json",
"bytes": 1687,
"sha256": "4614a8db12f1c46a1d988d55e92012286c5a25dde3ea69be7695013f4d23cf02"
},
{
"path": "LICENSE.md",
"bytes": 14443,
"sha256": "637e81f4a1b6b4079535c499fca05e238cf7605c1ff5b76d60d7da7ce96700c9"
},
{
"path": "README.md",
"bytes": 15957,
"sha256": "a83dbb420b0b4f335f4b9d2ca65c335be3fdcf83248bff49f81582b9c0c30712"
}
],
"scope": "Isolated reference experiment; no install scripts or production dependency."
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,9 @@
# Final connection-layout claim review
Read-only review; no material blocker to archiving the bounded research report. Reviewed `.local/connection-layout-results-20260925.md` SHA256 `ddf74fe85c9764f6b5162562d0de5b51489b29ef1e765337ed59da01871bc669` against frozen transfer audit `18274aff78240bed1ccfbbe49491e49465156db6cca6a934149a699e603459e4`, geometry result review, and sparse diagnosis `44d30974fe30183459412e177acc3729afeb448cf69ea05097afe037ecc1d93d`.
The report accurately separates final fc5c22c9 observer from initial8a2010d8, released routing from experimental placement, and independent Arrange-reset work. Counts, preserved identity correction, automatic-port drift, explicit anchored-port fidelity and pure-transform limitations agree with my readback. The width1 failed negative expectation is preserved; the separate height1 rejection is accurately described. Final strict-Clippy receipt was inspected. This is not full-workspace, native readability, production adoption, or publication acceptance.
The clearance diagnosis appropriately supersedes the earlier narrower uninflated-corridor inference. The result does not claim that raw ELK is feasible under core18-unit leads/12-unit clearance, or that increasing search budgets would repair a rejected terminal pair. Necessary30-unit separation is explicitly not sufficient for an entire route. Both unsupported workshop cases remain coverage refusals, not engine failures or compound successes.
Two nonblocking wording improvements were sent to parent: say “10 of25 total port positions change, all automatic” because the denominator includes six authored ports; say “policy-aware conservation” rather than implying every raw conservation boolean is true (mixed authored_routes_exact is intentionally false after reset). No report edits by reviewer. The artifact is ready for bounded local archival with existing failed attempts and limitations retained; no reruns performed.
@@ -0,0 +1,7 @@
# Identity transfer correction after first run
The initial source8a2010d8 importer wrote every expanded node's projected size to its stored size. Independent audit of five identity plans showed unwanted source normalization:3 nodes in workshop original,2 in folded,10 in each mixed case and40 in sparse. Projection minimum sizing had made those effective rectangles larger than stored authored sizes. Positions, effective geometry, semantics, route policy and collapsed stored size were not implicated, but a no-layout identity transfer did not recover the original Project apart from eligible reset.
Correct the adapter by preserving stored size whenever the planned rectangle equals the original projected rectangle. Only an actual effective size change is imported. Keep collapsed compact-size equality mandatory and never replace its stored expanded size. After transfer, reproject and require the entire intended node ID/position/size map to match exactly, rejecting a requested rectangle that Rust would renormalize. Preserve first-run receipts and outputs; rerun the identical Rust control/import/negative cases against the corrected source without rerunning or tuning ELK.
This is an example-only adapter repair, not a production layout change. It cannot resolve the independently observed automatic-port drift:10/25 ports in each mixed case and48/110 in sparse differ materially from the engine's assumed endpoints, with7/32 side changes respectively. All six authored anchors in each mixed case remain exact. Geometry comparisons remain diagnostic until that mapping limitation is addressed.
@@ -0,0 +1,11 @@
# Parent observations for the placement comparison
Parent read complete JavaScript adapter and Rust importer source before execution; independent source review covered importer and supervisor. Synthetic Node checks executed with exit0 against adapter SHA2569cc91aa45deb86bfc0c4b786eb0d5e89336dd3e3bfef1adac5560b840ccc8b4a: nested coordinate roundtrip, shared physical port reuse, collapsed size change/header intrusion/edge reversal/missing semantic port/undirected/duplicate-node rejection. Engine was not invoked by those checks. This paragraph transcribes the observed tool result; it is not an independently signed process receipt.
One official pinned elkjs0.12.0 configuration ran across all five frozen cases. Three flat cases passed structural checks; both workshop cases refused the declared unsupported undirected edge before any engine call. Failed case receipts remain. No configuration changed after observing geometry.
Rust comparison supervisor first stopped before any child invocation due Python's copied Windows environment using uppercase SYSTEMROOT. Original package capture and failed script were retained in rust-run01; correcting case lookup produced rust-run02. Fourteen children completed with their expected outcomes. This is a tooling failure, not an application crash.
The parent inspected same-scale offline schematics for mixed dispatch reset and imported ELK placement. The imported arrangement makes the main sequence more continuous, with a long feedback path around it and a wider drawing. The reset arrangement wraps the flow across three rows with several crossing/shared paths. These images show boxes/lines and estimated label rectangles, not native glyphs or successful trace tasks. No GUI or native workflow was executed for this reference experiment.
Independent review found two distinct issues: unwanted identity size normalization, corrected in an example-only follow-up; and automatic-port divergence from ELK assumptions, retained as a hard limitation. The sparse imported drawing also produces a NoClearPath and an unrelated-node penetration. Source and model validity do not override these findings. No engine adoption, production change, issue closure or publish success is claimed.
@@ -0,0 +1,33 @@
# Connection-aware placement reference experiment
Prepared before reference-engine outputs. Owned scope remains issue32 under Codex-ytr83r/root. Gitea writes are currently failing; this plan and future results remain local-only until normal publication succeeds. No Linux checks or prerelease change.
## Question and decision
Can a mature port/hierarchy/label-aware placement engine produce node positions that materially improve the unchanged released Rust router's final drawing on the already frozen five-case corpus? Compare the old Rust layered prototype, reset-only released placement, and this external placement reference. This is a diagnostic comparison, not adoption of JavaScript into the product and not a test of ELK's complete drawing quality: returned ELK edge sections and label coordinates are deliberately not applied to the Project. Failure may show that placement and routing must stay coupled, or that this adapter is inadequate; it does not establish that ELK itself is poor.
The previous turn completed a verified explicit route-reset contribution. Prior J/P/PL/L router tuning stopped with realistic ID-order/label tradeoffs. Root cause inspection shows production Layout topologically orders roots then packs four per row; nested children are ordered by ID and stacked. Its isolated layered prototype uses neighbor node centers, ignoring fixed port order, and one diagram-wide maximum label gap. Repeating penalty tuning is not the next experiment.
Primary sources: [ELK Layered](https://eclipse.dev/elk/reference/algorithms/org-eclipse-elk-layered.html) supports ports, labels and compound graphs; [Schulze et al.](https://rtsys.informatik.uni-kiel.de/~biblio/downloads/papers/jvlc13.pdf) explains that crossing reduction depends on port order as well as node order. [ELK JSON](https://eclipse.dev/elk/documentation/tooldevelopers/graphdatastructure/jsonformat.html) defines nested nodes/ports and requires supplied label dimensions. [Official elkjs](https://github.com/kieler/elkjs) exposes the layout algorithms in JavaScript. These motivate a reference comparison, not an inferred implementation guarantee.
## Frozen inputs and engine
Use every existing case in `harness/experiments/routing-independent-20260925/corpus/manifest.json` at research commitac5d7ef3: workshop expanded/folded, mixed dispatch, its fixed edge-ID permutation, sparse40. Do not edit fixtures, select favorable routes or add new tuning cases after results. Manifest SHA256 `a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717`. Reuse named trace tasks and report every case, including unsupported/error outcomes.
Reference engine elkjs0.12.0, official npm tarball SHA256 `c1d7719723e020b10724e3ccbc935696a2884f1e78d361cdd03766309e8e8e2a`, bundle SHA256 `1222e44f953ce7746af23801e723708f8e6f436b8b377a6a5fc7552f34a307b3`. Registry SHA512 integrity was verified. Isolated bundle extraction runs no npm lifecycle scripts. Dependency receipt and license retained. No application dependency or packaging decision follows.
One declared configuration: layered, RIGHT, orthogonal, hierarchy INCLUDE_CHILDREN, seed1, no edge/hierarchy merging. Projected visible hierarchy and dimensions; semantic port identities shared exactly where projection shares them. Ports use observed owner-relative coordinates, side and FIXED_POS. Compound header64/top padding and24 side/bottom padding reflect these architecture fixtures; they are not general State metrics. Current core-estimated edge label dimensions are supplied. Save complete input graph before calling the engine. Unsupported direction/port references fail explicitly. Record all output coordinates, sections and labels even though only node geometry is transferable.
## Adapter gates and attribution
Return exactly one finite positive node rectangle for each input projected node, with unchanged IDs and hierarchy. Detect extra/missing/duplicate nodes, changed identity, invalid fields, shrinkage and header/containment collisions. Do not change semantic endpoints, port anchors, relation direction, node visibility/collapse, authored endpoint attachments, or other views to fit the engine. Output port coordinates relative to resized containers must be audited: FIXED_POS can diverge from our final-size anchored fractions. Report that divergence; do not silently accept it as matching a fixed-fraction constraint or repair anchors. Reproject the imported Project through Rust to establish its actual final endpoints.
The placement importer starts from the original Project and replaces only returned visible node geometry. A visible collapsed node has a compact projected footprint distinct from stored expanded size: require the returned size to equal that compact footprint, apply only position, and preserve stored expanded size. A resized collapsed footprint is rejected in this first adapter, not silently written into expanded geometry. For a hidden placement under a visible collapsed ancestor, translate its original position by the nearest visible collapsed ancestor's delta, preserving latent relative geometry; unrelated out-of-projection nodes stay exact. This is an explicit reference-adapter policy, not a production amendment. Use existing actual-owner translation for retained routes; clear only pre-operation eligible visible actual-owner pins and full labels, preserving entries/order and attachments as in the verified reset contract. Validate the final Project, source roundtrip and conservation before geometric comparison. Scenario is excluded explicitly. The old prototype's folded refusal remains a failure to support that case, not a zero-score row.
## Observations and stopping rule
Parent bounds each engine process at90seconds; retain timed-out/missing output as failure. Engine timing is diagnostic startup+layout timing and is not directly compared to prior isolated Rust route-only timings. Freeze binaries/scripts/config/source before calls; verify input and tool hashes afterward. No concurrent compiler writes to shared target. Once compiled, preserve the observer executable before further worktree edits.
Report the existing full vector: proper crossings, all raw T/bend/endpoint contacts, pairwise and nonterminal shared length, node/header penetration, node and estimated-label collisions, unrelated label/stroke intersections, per-edge warnings, bends, length and area. No weighted aggregate pass. Compare each candidate to the same source/reset control; distinguish node positions from final routed geometry. Preserve source inputs and raw outputs. ID-permutation pair must stay explicit.
This finite experiment answers whether further native Rust placement design or an external-engine integration spike has stronger evidence. A simpler Rust candidate remains preferred if comparable. Reject a transfer as acceptable if it loses constraints, changes semantic records, produces invalid geometry or introduces new trace ambiguity. Scalar improvements alone cannot establish native traceability or shipped usability. Follow native inspection only for a candidate with a defensible full quality vector and faithful adapter; no automatic production adoption. Stop after this single configuration and analysis; repair concrete adapter defects with preserved failures, but do not tune options after viewing quality results.
@@ -0,0 +1,37 @@
"""Fetch pinned official reference engine, without install scripts or production changes."""
from pathlib import Path
import base64, hashlib, io, json, tarfile, urllib.request
root = Path(__file__).resolve().parent / 'elk-reference-20260925'
root.mkdir(exist_ok=False)
url = 'https://registry.npmjs.org/elkjs/0.12.0'
metadata_raw = urllib.request.urlopen(url, timeout=30).read()
metadata = json.loads(metadata_raw)
assert metadata['name'] == 'elkjs' and metadata['version'] == '0.12.0'
tar_url = metadata['dist']['tarball']
assert tar_url == 'https://registry.npmjs.org/elkjs/-/elkjs-0.12.0.tgz'
raw = urllib.request.urlopen(tar_url, timeout=30).read()
expected = 'sha512-YZcKynxVxYoKIOEpywEPwCFdg+BTbxQRNf3pbwdDCvc8O3kQD8bmIwSxKU1eOTVc4Xo+VG9Te+575mlfvOrhEQ=='
actual = 'sha512-' + base64.b64encode(hashlib.sha512(raw).digest()).decode()
assert actual == expected == metadata['dist']['integrity']
(root / 'registry-metadata.json').write_bytes(metadata_raw)
(root / 'elkjs-0.12.0.tgz').write_bytes(raw)
allowed = {'package/lib/elk.bundled.js', 'package/package.json', 'package/LICENSE.md', 'package/README.md'}
members = []
with tarfile.open(fileobj=io.BytesIO(raw), mode='r:gz') as archive:
for member in archive.getmembers():
if member.name not in allowed:
continue
assert member.isfile()
data = archive.extractfile(member).read()
relative = Path(member.name).relative_to('package')
destination = root / relative
destination.parent.mkdir(exist_ok=True)
destination.write_bytes(data)
members.append({'path': relative.as_posix(), 'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()})
assert len(members) == len(allowed)
receipt = {'package': 'elkjs', 'version': '0.12.0', 'registry_url': url, 'tarball_url': tar_url,
'integrity': actual, 'tarball_sha256': hashlib.sha256(raw).hexdigest(),
'license': metadata['license'], 'members': members, 'scope': 'Isolated reference experiment; no install scripts or production dependency.'}
(root / 'dependency-receipt.json').write_text(json.dumps(receipt, indent=2)+'\n', encoding='utf-8')
print(json.dumps(receipt))
@@ -0,0 +1,239 @@
'use strict';
// Isolated placement reference. No Project mutation or ELK route/label adoption.
const fs = require('node:fs');
const path = require('node:path');
const crypto = require('node:crypto');
const REFERENCE_DIR = __dirname;
const SOURCE = path.resolve(REFERENCE_DIR, '../routing-corpus-runs-20260925/geometry-released/stdout.jsonl');
const SOURCE_SHA256 = '9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2';
const BUNDLE_SHA256 = '1222e44f953ce7746af23801e723708f8e6f436b8b377a6a5fc7552f34a307b3';
const sha = bytes => crypto.createHash('sha256').update(bytes).digest('hex');
const binding = file => { const b = fs.readFileSync(file); return {path: file, bytes: b.length, sha256: sha(b)}; };
const write = (dir, name, value) => fs.writeFileSync(path.join(dir, name), JSON.stringify(value, null, 2) + '\n', {flag: 'wx'});
const requireThat = (ok, message) => { if (!ok) throw new Error(message); };
const finite = (...values) => values.every(Number.isFinite);
const unique = (values, key, label) => {
const result = new Map();
for (const value of values) {
requireThat(typeof value[key] === 'string' && !result.has(value[key]), `Missing/duplicate ${label} identity`);
result.set(value[key], value);
}
return result;
};
const portId = (owner, element) => `port:${owner}:${element}`;
const SIDES = {Left: 'WEST', Right: 'EAST', Top: 'NORTH', Bottom: 'SOUTH'};
const CONFIG = {
'elk.algorithm': 'layered', 'elk.direction': 'RIGHT',
'elk.edgeRouting': 'ORTHOGONAL', 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
'elk.randomSeed': '1', 'elk.layered.mergeEdges': 'false',
'elk.layered.mergeHierarchyEdges': 'false',
};
function adapt(row) {
const metrics = row.before;
const nodes = unique(metrics.projected_nodes, 'id', 'node');
const definitions = unique(metrics.projected_edges, 'id', 'edge');
const routed = unique(metrics.routed_edges, 'id', 'routed edge');
const graph = {id: 'reference-root', layoutOptions: {...CONFIG}, children: [], edges: []};
const objects = new Map();
const mapping = {case: row.fixture, diagram: row.diagram, nodes: [], ports: [], edges: [],
excluded_source_placements: [], configuration: CONFIG,
scope: 'Transferable projected placement only. ELK routes/label positions are diagnostic and never applied to Project.',
port_policy: 'Zero-size FIXED_POS anchors at observed node-relative physical port positions. Drift and resizing require explicit assessment.',
compound_policy: 'Input size is minimum; top padding64, other padding24. Leaves retain input dimensions.'};
for (const node of nodes.values()) {
const parent = node.visual_parent === null ? null : nodes.get(node.visual_parent);
requireThat(node.visual_parent === null || parent, `Missing parent of ${node.id}`);
const seen = new Set([node.id]);
for (let p = parent; p; p = p.visual_parent === null ? null : nodes.get(p.visual_parent)) {
requireThat(!seen.has(p.id), `Hierarchy cycle at ${node.id}`); seen.add(p.id);
}
requireThat(finite(node.position.x, node.position.y, node.size.width, node.size.height)
&& node.size.width > 0 && node.size.height > 0, `Invalid node geometry ${node.id}`);
const object = {id: node.id, x: node.position.x - (parent?.position.x || 0),
y: node.position.y - (parent?.position.y || 0), width: node.size.width, height: node.size.height,
layoutOptions: {'elk.portConstraints': 'FIXED_POS'}, ports: [], children: []};
objects.set(node.id, object);
mapping.nodes.push({id: node.id, element: node.element, parent: node.visual_parent,
collapsed: node.collapsed, input_world: node.position, input_size: node.size});
}
for (const node of nodes.values()) {
const object = objects.get(node.id);
(node.visual_parent === null ? graph : objects.get(node.visual_parent)).children.push(object);
}
for (const object of objects.values()) {
if (object.children.length) Object.assign(object.layoutOptions, {
'elk.padding': '[top=64,left=24,bottom=24,right=24]',
'elk.nodeSize.constraints': '[MINIMUM_SIZE]',
'elk.nodeSize.minimum': `(${object.width},${object.height})`,
});
else object.layoutOptions['elk.nodeSize.constraints'] = '[]';
}
const portMap = new Map();
for (const port of metrics.projected_ports) {
const owner = nodes.get(port.owner), id = portId(port.owner, port.element);
requireThat(owner && !portMap.has(id) && SIDES[port.side], `Invalid/duplicate port ${id}`);
requireThat(finite(port.position.x, port.position.y), `Invalid port coordinates ${id}`);
const object = {id, x: port.position.x - owner.position.x, y: port.position.y - owner.position.y,
width: 0, height: 0, layoutOptions: {'elk.port.side': SIDES[port.side]}};
portMap.set(id, object); objects.get(port.owner).ports.push(object);
mapping.ports.push({id, owner: port.owner, element: port.element, side: port.side,
input_world: port.position, input_relative: {x: object.x, y: object.y}});
}
for (const edge of definitions.values()) {
requireThat(edge.oriented === true, `Unsupported undirected edge ${edge.id}`);
const endpoint = end => {
requireThat(nodes.has(edge[end]), `Missing ${end} node for ${edge.id}`);
const semantic = edge[`${end}_port`];
if (semantic === null) return edge[end]; // Explicit automatic node endpoint; never invent a port.
const id = portId(edge[end], semantic);
requireThat(portMap.has(id), `Missing projected semantic port ${id} for ${edge.id}`);
return id;
};
const source = endpoint('source'), target = endpoint('target');
const observed = routed.get(edge.id);
requireThat(observed && observed.label && finite(observed.label.size.width, observed.label.size.height)
&& observed.label.size.width >= 0 && observed.label.size.height >= 0, `Missing/invalid label ${edge.id}`);
const object = {id: edge.id, sources: [source], targets: [target], labels: [{id: `label:${edge.id}`,
text: observed.label.text, width: observed.label.size.width, height: observed.label.size.height}]};
graph.edges.push(object);
mapping.edges.push({id: edge.id, projected: edge, elk_sources: [source], elk_targets: [target],
observed_route: observed, label_measurement: 'Existing core estimated rectangle; no renderer measurement'});
}
requireThat(definitions.size === routed.size, 'Projected/routed edge inventory differs');
for (const node of Object.values(row.before_project.diagrams[row.diagram].nodes)) {
if (!nodes.has(node.id)) mapping.excluded_source_placements.push(node);
}
return {graph, mapping};
}
function inspect(result, mapping) {
const nodes = [], ports = [], edges = [], checks = [];
const add = (name, passed, detail) => checks.push({name, passed: Boolean(passed), detail});
function finiteTree(value) {
if (typeof value === 'number') return Number.isFinite(value);
if (Array.isArray(value)) return value.every(finiteTree);
if (value && typeof value === 'object') return Object.values(value).every(finiteTree);
return true;
}
add('all_engine_numeric_fields_finite', finiteTree(result));
function walk(container, ox, oy, parent) {
for (const node of container.children || []) {
const x = ox + node.x, y = oy + node.y;
nodes.push({id: node.id, parent, position: {x, y}, size: {width: node.width, height: node.height}});
add('finite_positive_node', finite(x, y, node.width, node.height) && node.width > 0 && node.height > 0, node.id);
for (const port of node.ports || []) {
ports.push({id: port.id, owner: node.id, position: {x: x + port.x, y: y + port.y},
relative: {x: port.x, y: port.y}, size: {width: port.width, height: port.height}});
add('finite_zero_size_port', finite(port.x, port.y, port.width, port.height)
&& port.width === 0 && port.height === 0, port.id);
}
walk(node, x, y, node.id);
}
edges.push(...(container.edges || []));
}
walk(result, 0, 0, null);
const actualNodes = unique(nodes, 'id', 'result node'), actualPorts = unique(ports, 'id', 'result port');
const actualEdges = unique(edges, 'id', 'result edge');
const sameIds = (actual, expected) => actual.size === expected.length && expected.every(v => actual.has(v.id));
add('node_inventory', sameIds(actualNodes, mapping.nodes));
add('port_inventory', sameIds(actualPorts, mapping.ports));
add('edge_inventory', sameIds(actualEdges, mapping.edges));
const resizing = [], portDrift = [];
for (const input of mapping.nodes) {
const output = actualNodes.get(input.id); if (!output) continue;
add('parent_identity', output.parent === input.parent, input.id);
const compound = mapping.nodes.some(n => n.parent === input.id);
const dx = output.size.width - input.input_size.width, dy = output.size.height - input.input_size.height;
resizing.push({id: input.id, compound, width_delta: dx, height_delta: dy});
add(compound ? 'compound_minimum_size' : 'leaf_size_exact', compound ? dx >= -1e-6 && dy >= -1e-6 : dx === 0 && dy === 0, input.id);
if (input.collapsed) add('collapsed_compact_size_exact', dx === 0 && dy === 0, input.id);
if (input.parent !== null) {
const parent = actualNodes.get(input.parent);
add('child_inside_parent_body', parent
&& output.position.x >= parent.position.x + 24 - 1e-6
&& output.position.y >= parent.position.y + 64 - 1e-6
&& output.position.x + output.size.width <= parent.position.x + parent.size.width - 24 + 1e-6
&& output.position.y + output.size.height <= parent.position.y + parent.size.height - 24 + 1e-6, input.id);
}
}
for (const input of mapping.ports) {
const output = actualPorts.get(input.id); if (!output) continue;
add('port_owner_identity', output.owner === input.owner, input.id);
portDrift.push({id: input.id, before: input.input_relative, after: output.relative,
dx: output.relative.x - input.input_relative.x, dy: output.relative.y - input.input_relative.y});
}
for (const input of mapping.edges) {
const output = actualEdges.get(input.id); if (!output) continue;
add('edge_orientation_and_endpoints', JSON.stringify(output.sources) === JSON.stringify(input.elk_sources)
&& JSON.stringify(output.targets) === JSON.stringify(input.elk_targets), input.id);
}
return {nodes, ports, checks, resizing, port_relative_drift: portDrift,
structural_checks_passed: checks.every(c => c.passed), adoption_accepted: false,
limitation: 'ELK sections/labels are only in raw result. Compound resize and fixed-port drift are measurements requiring explicit transfer review, not automatic acceptance.'};
}
async function main() {
const [caseName, destination, sourceArgument, bundleArgument, ...extra] = process.argv.slice(2);
requireThat(caseName && destination && extra.length === 0,
'Usage: node reference_probe.cjs CASE_NAME OUTPUT_NEW_DIR [SOURCE_JSONL [ELK_BUNDLE]]');
const sourcePath = sourceArgument ? path.resolve(sourceArgument) : SOURCE;
const bundlePath = bundleArgument ? path.resolve(bundleArgument) : path.join(REFERENCE_DIR, 'lib/elk.bundled.js');
const out = path.resolve(destination);
fs.mkdirSync(out, {recursive: false}); // Refuse overwrite, including any existing directory.
const receipt = {case: caseName, success: false, adoption_accepted: false,
started: new Date().toISOString(), timeout_policy: 'Parent supervisor supplies90s process limit; no in-process hard timeout.'};
try {
receipt.script = binding(__filename); receipt.input = binding(sourcePath);
receipt.engine = {package: 'elkjs', version: '0.12.0', ...binding(bundlePath)};
requireThat(receipt.input.sha256 === SOURCE_SHA256, 'Frozen source JSONL hash mismatch');
requireThat(receipt.engine.sha256 === BUNDLE_SHA256, 'Pinned elkjs0.12.0 bundle hash mismatch');
if (!bundleArgument) {
const dependencyPath = path.join(REFERENCE_DIR, 'dependency-receipt.json');
receipt.dependency_receipt = binding(dependencyPath);
const dependency = JSON.parse(fs.readFileSync(dependencyPath, 'utf8'));
requireThat(dependency.package === 'elkjs' && dependency.version === '0.12.0', 'Wrong dependency pin');
for (const member of dependency.members) {
const actual = binding(path.join(REFERENCE_DIR, member.path));
requireThat(actual.sha256 === member.sha256 && actual.bytes === member.bytes, `Dependency mismatch ${member.path}`);
}
} else {
receipt.dependency_receipt = null;
receipt.dependency_policy = 'External bundle admitted by exact pinned bundle SHA256; local extraction receipt not required.';
}
const rows = fs.readFileSync(sourcePath, 'utf8').trim().split(/\r?\n/).map(JSON.parse);
const cases = rows.filter(row => typeof row.fixture === 'string');
receipt.available_cases = cases.map(row => row.fixture);
requireThat(cases.length === 5 && new Set(receipt.available_cases).size === 5, 'Expected five distinct frozen cases');
const row = cases.find(value => value.fixture === caseName);
requireThat(row, `Unknown case ${caseName}`);
write(out, 'source-case.json', row);
const {graph, mapping} = adapt(row);
write(out, 'input-graph.json', graph); write(out, 'adapter-mapping.json', mapping);
receipt.input_graph = binding(path.join(out, 'input-graph.json'));
receipt.adapter_mapping = binding(path.join(out, 'adapter-mapping.json'));
const ELK = require(bundlePath);
const elk = new ELK();
const started = process.hrtime.bigint();
const result = await elk.layout(graph, {layoutOptions: CONFIG});
receipt.engine_elapsed_ns = (process.hrtime.bigint() - started).toString();
write(out, 'elk-result.json', result);
const observed = inspect(result, mapping);
write(out, 'placement-observation.json', observed);
receipt.success = observed.structural_checks_passed;
receipt.outputs = ['source-case.json','input-graph.json','adapter-mapping.json','elk-result.json','placement-observation.json'].map(name => binding(path.join(out, name)));
receipt.input_unchanged = binding(sourcePath).sha256 === receipt.input.sha256;
receipt.engine_unchanged = binding(bundlePath).sha256 === receipt.engine.sha256;
requireThat(receipt.input_unchanged, 'Frozen input changed during engine call');
requireThat(receipt.engine_unchanged, 'Pinned bundle changed during engine call');
if (!receipt.success) process.exitCode = 1;
} catch (error) {
receipt.success = false; receipt.error = {message: error.message, stack: error.stack}; process.exitCode = 1;
} finally {
receipt.finished = new Date().toISOString(); write(out, 'receipt.json', receipt);
}
}
module.exports = {adapt, inspect, CONFIG}; // Parent can exercise synthetic adapter cases without invoking ELK.
if (require.main === module) {
main().catch(error => { console.error(error.stack || error); process.exitCode = 1; });
}
@@ -0,0 +1,55 @@
# Independent geometry review of the placement reference
2026-09-25. Reviewed recorded `elk-reference-20260925/rust-run02` results at source `8a2010d8a6033201d6efd742134dae9f3d235632`, plus original `run01` engine receipts and selected raw ELK geometry. No compiler, router, engine or GUI rerun. Only read-only arithmetic on recorded points/rectangles was executed. Port/Project conservation is the separate gate reviewer's responsibility; this report does not substitute for that audit.
**Decision: the imported ELK placement provides a real hypothesis for further connection-aware arrangement, but this output is not adoptable.** The mixed cases improve several independent geometric problems through the unchanged Rust router. Sparse40 introduces a new unrelated-node penetration and `NoClearPath`, and uses substantially more area and total route length. Both compound workshop cases were rejected by the adapter before the engine ran, so this experiment supplies no external-engine compound-layout result. There is no scalar winner or native traceability claim.
## Complete case accounting
Values in each cell are reset-only control / old native layered prototype / imported ELK placement. Shared length retains raw pairwise multiplicity, including common-terminal intervals. All numbers are recorded geometry, not readable-ink guarantees.
| Case | Proper crossings | Raw point contacts | Shared length | Label/node collisions | Result limitation |
| --- | --- | --- | --- | --- | --- |
| Workshop original |6 /7 /unsupported|27 /20 /unsupported|1832 /1467 /unsupported|1 /1 /unsupported|ELK adapter refused undirected edge before engine call. Native uses more area and route length despite fewer shared units.|
| Workshop folded |7 /unsupported /unsupported|19 /unsupported /unsupported|1194 /unsupported /unsupported|0 /unsupported /unsupported|Native refuses folded/omitted topology; ELK adapter refuses the same undirected edge.|
| Mixed dispatch |10 /7 /1|25 /24 /7|716.39998 /4228 /238|0 /0 /0|ELK gains require larger area; native exchanges crossings for extensive shared runs.|
| Mixed reversed IDs |9 /7 /1|26 /24 /7|512.39998 /4228 /238|0 /0 /0|ELK aggregate metrics match the original mixed case; this alone does not prove all corresponding routes identical.|
| Sparse40 |94 /17 /20|158 /83 /55|1990 /40522 /666|14 /1 /0|ELK introduces one unrelated-node penetration and one NoClearPath.|
The baseline here is explicitly `reset_only_control`, not the unreset `after`. In mixed dispatch, unreset Layout reports7 crossings whereas the reset control reports10/9; substituting the former would hide the reset/placement distinction. Original authored input is also not the Arrange baseline: original mixed has0 crossings/shared132, and original sparse has24 crossings/shared496 but70 estimated label/node collisions. Therefore “better than current Arrange” must not be shortened to “better than the authored input in every respect.”
The native prototype reports exact same-input repeats, idempotence, and equality to its first result for passes2–10 in all four supported cases. Folded remains unsupported, not stable by omission. Stability does not redeem its shared-run costs: mixed4228 and sparse40522 are real recorded totals, not nondeterministic noise. This run does not establish repeated-ELK-Arrange idempotence.
## Actual gains and costs
For either mixed ordering, ELK reduces bends39→20 and total route length10618.60→9361.00. Estimated label/node, label/label and unrelated label/stroke collisions remain zero; no node penetration or warning is emitted. Area grows1139880→1808460, about59%. This is a plausible improvement in connection tracing with a navigation/overview cost still requiring native inspection. It shows that changing placement alone can help this graph through the released router; it does not require adopting external edge sections to obtain every benefit.
Sparse ELK reduces bends152→80; estimated label/node14→0, label/label1→0 and label/stroke31→0. These are substantial geometric improvements. However, route length rises39660→64223 and drawing area3804920→12840450, about3.37 times the baseline. The emitted bounds are8735 by1470 diagram units. Any later readable-scale trace test must account for the resulting navigation, rather than declaring readability from an uncluttered thumbnail. Native layered uses area6020910 and length54282, with fewer proper crossings17, but shared length40522 is much worse. Neither dominates the full vector.
Workshop original native reduces sharing1832→1467 and contacts27→20, but adds a crossing6→7, length8480→9251 and area886464→1125534. Its label/node count stays1 and label/stroke stays0. Folded reset retains four promoted-endpoint warnings and eliminates the original NoClearPath (original warning total5→reset4); neither alternative supplies a folded result. The failed ELK case receipts identify undirected edge `22c7011d-b559-5df8-aadd-851002904ba0`; this is an adapter coverage refusal, not evidence that ELK failed to solve those compounds.
## Independently checked geometry
Reused the independent axis-interval mathematics in `audit-routing-corpus-contacts-20260925.py`, without its route-only CLI or any routing call. Applied it to all12 available reset/native/ELK scenes. All48 comparisons agree within0.001: unique pairwise point contacts, proper crossings, common physical-terminal point contacts, and positive pairwise shared length. The arithmetic retains raw sharing; a zero common-terminal point-contact count does not mean shared terminal intervals are absent.
Independent classification for imported mixed is1 proper +2 T +4 bend contacts =7; sparse is20 proper +28 T +7 bend contacts =55. Thus most remaining sparse contacts are not proper crossings. They cannot be erased from interpretation by quoting only20 crossings.
For all nine flat mixed/sparse scenes, independently intersected emitted label rectangles with node rectangles, label rectangles with each other, and unrelated orthogonal strokes with label interiors. All27 collision-count comparisons agree. These checks concern the supplied estimated rectangles; they do not measure actual glyphs, port labels, selection hit behavior or arrowheads. Compound ancestor exclusions were not independently recomputed here.
**Confirmed sparse blocker:** relation `flow_45`, “Assessment Decide handoff to Planning Aggregate,” ID `00000000-0000-0000-0000-00000003347d`, passes through unrelated “Assessment Package” placement `00000000-0000-0000-0000-000000030dd1`. The node occupies x4522..4746, y660..820. The Rust route has a vertical segment x4634, y495..822, crossing160 units of its interior (Rust's epsilon-inset metric reports159.9998). Its actual source/target owners are different placements, so this is not endpoint or ancestor-body containment. The same edge emits `NoClearPath`; reset/native sparse have zero such penetrations and warnings.
The raw ELK section for that same edge has identical tips (4120,477)→(4634,840), but follows bends (4120,498), (4502,498), (4502,830), (4634,830). It goes left of the identified obstacle and then below it, avoiding that particular node. This supplies a concrete local witness that the placement had an avoidance corridor which the released routing result did not use. It does not prove that the raw ELK route avoids every other obstacle or that full raw ELK routing/labels pass our entire rubric.
## Implication and bounded next decision
Do not adopt this placement-only transfer while the sparse hard failure remains, and do not conclude that all improvement requires a coupled engine: mixed supplies the contrary positive example. The sparse witness makes a targeted compatibility investigation worthwhile. Compare that one fixed scene/edge's released-router search/fallback constraints against the recorded feasible ELK corridor. Determine whether the lost route is a bounded router limitation or an incompatible spacing/clearance assumption before choosing a broader coupled-route integration. Preserve the frozen outputs; do not sweep ELK parameters to hide the blocker. Compound reference coverage still requires an explicit undirected-edge policy before any claim about hierarchy-aware arrangement can be tested.
No native task was performed in this review. No renderer-based legibility, timing winner, semantic-port fidelity, full conservation or production acceptance follows from the arithmetic. Those remain separate gates.
Evidence hashes, SHA256:
- `rust-run02/arrange-corpus/stdout.jsonl`: `f924af4038ade0de2e0f44988fa28d2566019d8c4bc2bde70e61fe4813364d40`.
- `rust-run02/mixed_dispatch-elk/stdout.jsonl`: `9308079aa4804d6a61fae724fc4fe44807528fc20b03e213ad08d5b4314c2d89`.
- `rust-run02/mixed_dispatch_edge_ids_reversed-elk/stdout.jsonl`: `567ef210022639083654e43c900ad82c7ba529597d437386c7b27baac2d4e58f`.
- `rust-run02/subsystems_40_sparse-elk/stdout.jsonl`: `37ef8db5a920a50a1ed12eba08913fee810d02226d920fc9018088c9e7b14c3a`.
- `run01/subsystems_40_sparse/elk-result.json`: `9763cda98e744040e1f2e9ad63662cf6e699e8fbdc7e77b388d60ab4303a4282`.
@@ -0,0 +1,64 @@
# Connection-aware placement reference: result and decision
**Do not adopt either placement candidate from this experiment.** The external reference gives a useful mixed-network placement hypothesis, but it assumes port positions that Rust later recomputes and produces an incompatible sparse placement. The native prototype also has large shared-route regressions. The next design must account for automatic-port selection and mandatory exit/obstacle clearance during placement. Increasing routing search limits does not address the diagnosed failure.
This is branch-specific research for issue32, not a production change or an integrated release. Tested final observer source `fc5c22c903c70b53102fa65e1b8cfdc971f877f1`; first observer source `8a2010d8a6033201d6efd742134dae9f3d235632`. Production routing remains byte-identical to released715036e. The separately verified Arrange-reset candidate is on its own branch. Gitea publication is blocked by the recorded remote disk-full/write errors; all new comparison records are local-only at this checkpoint.
## Experiment and complete accounting
The [plan](plan.md) and [independent criteria](criteria.md) were frozen before engine outputs. Use all five existing corpus cases, fixed engine/options and the released Rust router. elkjs0.12.0 supplies node positions only; its paths and label positions are retained diagnostically and never persisted as authored overrides. Current core-estimated label dimensions are supplied, not measured glyph bounds. This cannot rank ELK's complete drawing quality.
| Case | Reset / native / ELK+Rust proper crossings | Reset / native / ELK+Rust shared length | Outcome |
| --- | --- | --- | --- |
| Workshop original | 6 / 7 / unsupported | 1832 / 1467 / unsupported | Native reduces sharing but adds a crossing and area. |
| Workshop folded | 7 / unsupported / unsupported | 1194 / unsupported / unsupported | Old native prototype rejects folding; ELK adapter rejects an undirected connection before engine invocation. |
| Mixed dispatch | 10 / 7 / 1 | 716.39998 / 4228 / 238 | External placement improves several metrics, with wider bounds and incompatible automatic-port assumptions. |
| Mixed, reversed edge IDs | 9 / 7 / 1 | 512.39998 / 4228 / 238 | Same external scalar vector; semantic ID permutation remains recorded. |
| Sparse40 | 94 / 17 / 20 | 1990 / 40522 / 666 | External transfer adds a NoClearPath and unrelated-node penetration. |
Both workshop ELK attempts stop on undirected edge `22c7011d-b559-5df8-aadd-851002904ba0`; neither is an engine failure or a successful compound-layout comparison. Do not infer compound compatibility from the three flat successes. The four supported native prototype cases are deterministic, idempotent and equal to their first results through ten calls, but stability does not establish quality.
For mixed dispatch, external placement reduces bends39→20 and length10618.60→9361.00 versus current Arrange/reset; estimated label collisions remain zero. Drawing area increases1139880→1808460, about59%. The original authored input already had zero proper crossings and only132 shared units, so improvement over Arrange is not improvement over every original quality dimension. Offline schematics show a more continuous sequence and long feedback paths, but no native trace task was performed.
Sparse external placement eliminates the reset control's estimated label/node14, label/label1 and label/stroke31 collisions. However, length increases39660→64223 and area3804920→12840450, about3.37×. Final bounds8735×1470 imply navigation costs that a thumbnail cannot assess. Its20 proper crossings coexist with28 T and7 bend contacts. The native prototype has shared length40522 despite only17 proper crossings. No weighted scalar winner is appropriate.
## Two interface failures and one repaired observer defect
**Automatic ports are part of placement, not fixed input geometry.** All three final Rust node maps exactly match their imported plans, but mixed and reversed mixed each have10 of25 total port positions changed, including7 side changes. Sparse has48 of110 positions changed and32 side changes. All changed positions belong to automatic ports. Maximum discrepancy224 units; these are not rounding differences. All six authored anchored ports in each mixed case remain exact. The engine's FIXED_POS assumptions therefore do not describe the final Rust drawing. This is a placement/projection interface limitation, not loss of stored anchor metadata.
**The sparse penetration is caused before path search.** Edge `flow_45` (`…03347d`) has target top tip(4634,840), requiring an18-unit outward stub at(4634,822). Unrelated Assessment Package occupies x4522..4746,y660..820; core12-unit inflation reaches y832. The mandatory target lead intersects that obstacle, so the sole semantic-port pair is rejected before cheap/grid search. The fallback reports NoClearPath and penetrates159.9998 units of the actual node interior. No search-budget exhaustion is involved.
Raw ELK avoids actual node interiors for this edge, but its10-unit final lead and10-unit obstacle clearance violate the core18/12 geometry contract. A local necessary separation is30 units rather than the observed20; that is not a proof a complete route exists at30, nor permission to blindly enlarge every gap. The [fixed-scene diagnosis](sparse-routing-diagnosis.md) checks every raw segment against all40 nodes and the relevant inflation/endpoint exemptions. It corrects the initial, narrower observation that an uninflated avoidance corridor existed.
**Identity transfer initially normalized stored sizes.** Source8a2010d8 wrote effective projected minima into authored node sizes even for an unchanged plan. Sourcefc5c22c9 preserves stored size when effective size is unchanged and verifies final reprojection against the exact intended map. All five identity imports now equal independently reconstructed reset-only Projects, preserving stored expanded sizes. The eight import metric/geometry objects and final ports remain exactly equal to the first run, so this repair does not hide either interface failure. [Finding and correction](identity-transfer-finding.md).
## Validation and limits
Windows x86_64-pc-windows-gnullvm, Rust1.98.1, LLVM-MinGW20260908, one Cargo job, offline cached dependencies. Both observer source pins built successfully in release mode and passed strict example Clippy. Final commands, from the repository root:
```text
cargo build --release --locked --offline -p oa-core --example auto_layout_probe
cargo clippy --locked --offline -p oa-core --example auto_layout_probe -- -D warnings
target/release/examples/auto_layout_probe.exe --arrange-corpus harness/experiments/routing-independent-20260925/corpus/manifest.json
target/release/examples/auto_layout_probe.exe --import-placement PROJECT_JSON DIAGRAM_UUID PLAN_JSON
```
Plan JSON is `{ "schema":1, "nodes":[{ "id":"UUID", "position":{"x":0,"y":0}, "size":{"width":224,"height":132} }] }`, containing every visible projected placement exactly once. Import does not apply an intermediate Layout. Collapsed compact dimensions must remain exact while stored expanded dimensions stay intact. Hidden descendants follow their nearest visible collapsed ancestor's translation; unrelated omitted nodes remain unchanged. Nonzero hidden translation and nonempty dormant route translation are source-reviewed, not exercised by this corpus's failed compound reference cases.
Five control cases report exact Undo/Redo and source/JSON round trips. Eight successful final imports (five identity and three external) pass policy-aware whole-Project conservation and round-trip checks under independent review: eligible route resets are expected differences, so the raw `authored_routes_exact` flag is intentionally false for mixed cases. These are pure transformation checks, not native GUI/history tests of an integrated external engine. Six meaningful malformed-plan cases reject: missing, duplicate, unknown placement, zero dimension, changed collapsed footprint and final reprojection mismatch from an actually constrained height. An added width1 negative unexpectedly succeeded because that fixture has no such minimum-width constraint; its failed expectation is preserved, not relabeled. A separate height1 case correctly exercises the vertical-port minimum and exits101 with the expected reprojection error.
The first Python supervisor failed on Windows environment key casing before launching a child; corrected run and original failed script/capture remain. Original identity-normalizing run02 remains alongside corrected run03. All successful process stderr is empty; expected negative cases retain their errors. Final Clippy passed. No Linux, full workspace-suite or native readability acceptance is claimed.
The JavaScript adapter's eight synthetic checks cover nested coordinate conversion, shared physical-port reuse and key rejection paths. One fixed ELK run completed three flat cases in roughly307–624ms engine time, with process times roughly595–913ms; both unsupported cases exit before the engine. No timeout occurred. These are single diagnostic timings, not a native responsiveness bound or comparable Rust route-only benchmark.
Independent [transfer audit](transfer-audit.md) checks complete Project differences, route policy, exact node maps, port drift and receipts. The [geometry review](result-review.md) independently matches48 contact/shared-length comparisons and27 flat label collision counts. It confirms the sparse penetration. [Source audit](source-audit.md), [adapter review](adapter-review.md) and parent observations are retained. Actual glyphs, port labels, arrowheads and named trace tasks remain unverified; no adoption follows from these metrics.
## Reproduction and next decision
Frozen corpus manifest SHA256 `a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717`. External adapter accepts `node reference_probe.cjs CASE_NAME NEW_OUTPUT_DIRECTORY SOURCE_JSONL ELK_BUNDLE`. The exact original source JSONL is archived; SHA256 `9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2`. Fetch the pinned official npm elkjs0.12.0 using the recorded preparation helper/metadata and verify bundle SHA256 `1222e44f953ce7746af23801e723708f8e6f436b8b377a6a5fc7552f34a307b3`. Supervise every engine/observer process with the recorded90-second cap. Convert only structurally passing observations to the narrow plan schema, preserving all original results. Machine-specific runner paths in receipts are provenance; use the pinned commit and your own runtime paths.
Stop this configuration comparison. The next bounded work is a placement-compatibility model that evaluates final automatic-port choices and mandatory port leads against inflated obstacles, with explicit undirected/compound policy. First characterize the exact infeasible lead from this scene; then test whether candidate placement can satisfy those constraints without changing authored anchors or routing contracts. Do not pursue search-budget increases, option sweeps or a production engine dependency on the present evidence. Issue32 and the full application objective remain incomplete.
## Evidence archive
[ZIP](evidence/connection-layout-reference-fc5c22c9.zip) and [member manifest](evidence/manifest.json): 250 files, 3887968 bytes, SHA256 `e68628c8558bb9a1104ed4ca0a0ce612bd0522a1cbce0b9d5c7a8092a7dfeb00`. All member bytes, SHA256 and CRC were reread. Includes all failed/corrected attempts, four successful build/lint gates, raw engine/import outputs, independent reviews, source/driver bindings and17 offline geometry images. Binary payloads are excluded; their hashes and official engine retrieval metadata are retained. [Final claim review](final-review.md) and [parent observations](parent-observations.md) define the acceptance limits.
@@ -0,0 +1,52 @@
"""Bound each frozen reference case in a separate process and preserve all outcomes."""
from pathlib import Path
import datetime, hashlib, json, subprocess, sys, time
local = Path(__file__).resolve().parent
root = local / 'elk-reference-20260925'
node = Path('C:/Users/User/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node.exe')
script = root / 'reference_probe.cjs'
source = local / 'routing-corpus-runs-20260925/geometry-released/stdout.jsonl'
manifest = local / 'auto-layout-20260925/harness/experiments/routing-independent-20260925/corpus/manifest.json'
output = root / sys.argv[1]
assert output.parent == root and output.name == sys.argv[1]
output.mkdir(exist_ok=False)
def record(path):
return {'path':str(path), 'bytes':path.stat().st_size,
'sha256':hashlib.sha256(path.read_bytes()).hexdigest()}
bound = [node, script, source, manifest, root/'lib/elk.bundled.js', root/'dependency-receipt.json',
local/'connection-layout-reference-plan-20260925.md', Path(__file__)]
before = [record(p) for p in bound]
assert before[2]['sha256'] == '9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2'
assert before[3]['sha256'] == 'a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717'
assert before[4]['sha256'] == '1222e44f953ce7746af23801e723708f8e6f436b8b377a6a5fc7552f34a307b3'
cases = [c['name'] for c in json.loads(manifest.read_text())['cases']]
receipts = []
for case in cases:
case_output = output / case
stdout = output / (case+'.stdout.log')
stderr = output / (case+'.stderr.log')
argv = [str(node), str(script), case, str(case_output)]
started = datetime.datetime.now(datetime.timezone.utc).isoformat()
start = time.perf_counter()
timed_out = False
with stdout.open('xb') as out, stderr.open('xb') as err:
try:
completed = subprocess.run(argv, cwd=root, stdout=out, stderr=err, timeout=90)
code = completed.returncode
except subprocess.TimeoutExpired:
timed_out = True
code = None
receipt = {'case':case, 'argv':argv, 'started_utc':started,
'elapsed_seconds':time.perf_counter()-start, 'timeout_seconds':90,
'timed_out':timed_out, 'exit_code':code, 'stdout':record(stdout), 'stderr':record(stderr)}
receipts.append(receipt)
(output/(case+'.receipt.json')).write_text(json.dumps(receipt,indent=2)+'\n')
print(json.dumps(receipt), flush=True)
after = [record(p) for p in bound]
receipt = {'inputs_before':before, 'inputs_after':after, 'inputs_unchanged':before==after,
'cases':receipts, 'scope':'Reference-engine adapter execution; exit0 is not geometry or production acceptance.'}
(output/'receipt.json').write_text(json.dumps(receipt,indent=2)+'\n')
assert before == after, 'Bound inputs changed during experiment'
@@ -0,0 +1,73 @@
# #32 connection-aware placement: source audit and next design
Read-only audit at reset checkout HEAD `956e33e568c6b799d0330803c74927e205977dfd`; line references below are repository-relative at that pin. No source edits, compilation, routing execution or GUI actions. The finished reset behavior is separate from this proposal; neither the old layered prototype nor J/L routing experiments are adopted here.
## What current placement considers—and omits
| Source | Observed behavior | Consequence for #32 |
| --- | --- | --- |
| `crates/oa-core/src/session.rs:970–974` | Children come from the projection-parent forest into vectors in ordered-map traversal order. | Nested siblings remain placement-ID ordered; no internal exchange order or boundary-neighbor order is considered. |
| `session.rs:986–1012` | Port-aware minimum node size, State header/content sizing, then one vertical child column with48 horizontal padding and16 sibling gap; authored size remains a lower bound. | Valid enclosure scaffolding exists, but neither connection demand nor edge label dimensions affect child spacing or container aspect ratio. |
| `session.rs:1017–1040` | Every child starts at parent x+24, stacked beneath the header. | Reversed children in adjacent containers can force intersecting/shared routes even when a sibling permutation would separate them. |
| `session.rs:1052–1070` | Every visible edge is lifted to the two outermost roots; same-root edges disappear; duplicate root pairs collapse into a set. `edge.oriented` is not checked. | Some connectivity is used, but internal demands, multiplicity, ports and labels are discarded. Undirected serialized endpoint order also influences rank-like root ordering. |
| `session.rs:1072–1089` | Choose a remaining root with no remaining predecessor, tie by semantic alias/ID; if none, choose alias/ID anyway. | Deterministic cycle fallback exists, but this is a total topological order, not explicit layers or crossing minimization. |
| `session.rs:1111–1129` | Lay roots left-to-right with240 gaps; wrap after every fourth root with60 row gap. | A seven-node flow is broken into rows regardless of connections. Disconnected graphs and dense bipartite graphs receive the same packing policy. |
| `session.rs:1131–1159` | Apply final placement deltas, existing route translation, and pre-frozen eligible reset. | Useful commit boundary already exists; a better placement planner can replace candidate positions/sizes without redesigning history or route persistence. |
No call inside Layout computes edge-label geometry or scores its proposed final routed result. `routing.rs:1363–1395` derives visible text and estimates label width as7 per scalar plus16, height24; `1410+` tries automatic locations only after paths exist. Therefore source alone confirms that node arrangement is not label-aware. Core estimates must not be advertised as rendered glyph bounds; the independent #36 label work needs explicit reconciliation when integrated.
## Evidence that narrows the choice
The first prototype report, `harness/experiments/auto-layout-20260925/results-01.md` at the separate experiment checkout, documents useful placement effects: reversed children shared length148→0 and label/node collisions1→0; seven-node chain length2560→492 with8→0 bends; long-label collisions2→0. But diamond and bipartite shared strokes worsened. Its nine fixtures omitted folded/filtered topology, Allocation/State, cycles/undirected graphs and genuine other-view conservation. It explicitly rejected omitted/folded nodes, so it cannot be dropped into production Layout.
`harness/experiments/routing-independent-20260925/decision-review.md` retains the released router: J/L pass the finite timing guardrails but expose label and ID-order regressions, and native trace tasks were not met. The next placement experiment should therefore keep the released router fixed. Improving a routing penalty again would obscure whether ordering/space allocation solves the actual placement defect.
## Material alternatives
| Approach | Scope and tradeoff | Decision criterion |
| --- | --- | --- |
| Hierarchical sibling layers and boundary order | Replace vertical/4-per-row packing with connection-informed order, ranks and local corridor sizing, retaining current sizing/transaction machinery. Native Rust and bounded; compound boundary constraints are the real complexity. | Preferred first experiment: improves known nested ordering/label fixtures without corrupting latent folded geometry or worsening named trace tasks. |
| Bounded local improvement of existing positions | Treat current arranged boxes as a baseline; evaluate a small fixed set of sibling swaps, row breaks or gap changes using actual routed results. Preserves more organization and avoids a full layering engine. | Useful control, but reject as primary if it cannot discover the two-container sibling swap without excessive route evaluations or gets trapped by a needed rank change. |
| Compound layout engine adapter | Feed ports, nesting and label rectangles to a mature engine such as ELK via elkjs; validate and commit returned geometry. | Reopen only if native bounded candidates fail concrete compound cases. Additional runtime and mapping cost remain, and the app must still define folded/hidden scope, fixed anchors, measurement and transaction semantics. No engine adoption justified by these results alone. |
These differ in geometry construction/search strategy, not just router coefficients. Do not spend another iteration rebuilding the prototype's known unsupported scope without resolving it.
## Minimal proposed architecture
Keep one pure candidate computation inside the existing core Layout transaction. Inputs are the staged Project, target Diagram, actual projection-parent forest, visible projected connectivity, and deterministic core text-size estimates. Outputs are target-diagram positions/sizes; existing final route translation/reset remains authoritative. Do not call desktop font APIs from core commands or give GUI/API different layouts for identical inputs.
Use two views of the **same** forest: full stored placement ancestry for latent geometry/conservation, and visible connectivity for current arrangement goals. Reuse `projection::parents` (`projection.rs:81+`), which includes Allocation-specific allocation grouping, rather than substituting semantic parent fields. Folded rendering hides descendants and substitutes compact outer heights (`projection.rs:303–335`); that compact footprint is not permission to shrink/delete stored descendants. Preserve descendants' relative geometry when treating a collapsed subtree as one visible box, translating its latent members with the box. This is a proposed improvement over today's rearrangement of hidden descendants and requires an explicit contract choice before implementation. An alternative is retaining today's hidden-descendant reflow with full stored enclosure; it is simpler but may waste visible space. Do not silently mix these policies.
For each sibling group, lift visible edges to the two direct child subtrees at their lowest common ancestor. Use oriented edges for layer direction; undirected edges influence proximity/order only. Keep parallel demands and port-side/order information rather than reducing them to a set. External boundary connections should provide order constraints for the local children too: lifting only at the common ancestor would still miss the reversed-child case. Separate these boundary-order hints from rank constraints to avoid counting one edge as an independent rank demand at every ancestor. Use deterministic SCC handling for cycles, canonical ties, and explicit self-loop space.
Start with a fixed number of sibling order sweeps and one coordinate assignment. Compute container sizes bottom-up from frozen node minima plus content/header/footer/padding, using max constraints instead of repeatedly adding clearance to already enlarged sizes. Reserve corridor width/height using relevant visible label rectangles and edge demand per cut/group, not one global longest label inflated into every gap. Real fixed port anchors are hard constraints; automatic port choices remain derived and must be reprojected after placement, because their side/order and node capacity depend on new peer geometry (`projection/port_layout.rs:156+`). A final reprojection/enclosure check is mandatory before scoring.
Route only a small fixed number of complete candidates with the released router: baseline plus one main layered candidate, optionally one local-swap control. Keep actual path/label metrics and identity-preserving invariants, rather than accepting by straight-line crossing proxies alone. Bound topology preprocessing and routing work globally; on exhaustion return the declared baseline or fail atomically, never partially apply geometry. Selecting a baseline is a fallback outcome, not proof the new layout succeeded. Avoid a weighted scalar that hides new label collisions behind shorter paths.
## Non-negotiable invariants and evaluator changes
- Freeze reset eligibility before placement (`session.rs:955–969`). Route entry/order, attachments and port anchors follow the accepted reset contract; filtered/promoted metadata keeps existing actual-owner translation and State boundary rules. Other diagrams and all semantics remain exact. Generated elbows stay derived.
- Preserve staged Batch semantics and enclosing history. Apply one complete candidate with final validation; no new intermediate validation or hidden history entries. Keep Scenario's existing rejection (`session.rs:950–953`) and do not claim Process support from this work.
- Reuse reset tests in `tests/release_routing.rs:652+`, especially filtered/missing routes792+, folding864+, staged Batch930+. Add independent known-order witnesses for sibling crossing separation, seven-node flow without arbitrary wrapping, local long-label clearance, undirected endpoint reversal, cycle/self-loop, distinct/fixed/shared ports and disconnected components.
- Extend the placement evaluator with the frozen real workshop Allocation views, fold→Arrange→expand, hidden-edge sentinel and untouched other view. Record latent descendants as well as visible nodes; reject node/header penetration and lost port constraints. A visible-only geometry check misses broken expansion.
- Require exact repeat-input determinism and ten-call stability across save/reparse, including periods2 and cumulative container growth. Compare against current baseline and reset-only at the same router pin. Retain pairwise shared intervals, proper/T/bend contacts, label conflicts, warnings, area, route length and workload individually.
- Geometry remains a screen for failures. Parent must verify predeclared connection-tracing tasks and readable labels at normal zoom, then actual Arrange/Undo/Redo/Save/reopen. Current core text estimates and previous offline images do not establish these outcomes.
Recommendation: settle the folded latent-geometry policy, then prototype sibling ordering/layers with boundary hints and local label corridor space. Keep the reset candidate and released router intact until that experiment meets the larger scope. The first milestone is a falsifiable placement result, not a new framework or a claim that #32 is complete.
## Bounded ELK reference comparison: recommended now, dependency decision deferred
An external layout-only reference is feasible and worthwhile before another bespoke placement iteration. This does not contradict deferring a production compound-engine dependency: the comparison buys evidence about ordering and space allocation without committing the application to a JavaScript runtime. Pin elkjs 0.12.0, package integrity, Node executable and adapter/options; retain exact input/output. No ELK execution was performed in this audit.
Verified official capabilities: [ELK Layered](https://eclipse.dev/elk/reference/algorithms/org-eclipse-elk-layered.html) supports ports, labels, compound graphs and cross-hierarchy layout with the appropriate option. [JSON input](https://eclipse.dev/elk/documentation/tooldevelopers/graphdatastructure/jsonformat.html) supports nested children and explicit port references; callers supply label dimensions. [Port constraints](https://eclipse.dev/elk/reference/options/org-eclipse-elk-portConstraints.html) are node-level, including FIXED_POS and FIXED_RATIO. [Coordinate conventions](https://eclipse.dev/elk/documentation/tooldevelopers/graphdatastructure/coordinatesystem.html) default shapes to parent-relative coordinates; recursively flatten returned nodes before transfer. These capabilities do not establish adapter correctness or resulting Rust-route quality.
The frozen geometry rows have sufficient visible inputs: `before.projected_nodes` carries placement IDs, visual_parent, collapsed and allocation_summary; `projected_ports` carries semantic element plus owner placement, side and world position; `projected_edges` carries oriented, source/target placements and optional semantic ports; `routed_edges` supplies existing approximate label dimensions. Full `before_project` supplies authored anchor and dormant geometry records. Use `(owner placement, semantic port)` adapter identities, not semantic element ID alone. Shared ports must remain shared, not be cloned per edge. Use projected ancestry, not semantic parents (Allocation summaries are material here).
Proposed first reference: one fixed Layered configuration, compound hierarchy enabled, explicit direction and seed, fixed visible leaf dimensions, actual header padding for containers, existing label rectangle dimensions. For the initial diagnostic, fixing all imported port positions is an explicit overconstraint: automatic port choices will be recomputed by Rust after placement, and resized containers complicate absolute versus ratio anchors. Keep authored anchor records exact and report final per-port drift from the engine assumptions. Do not persist returned port coordinates to manufacture agreement. A mixed node containing manual and automatic anchors cannot be naively represented by one node-level FREE constraint. Reject unsupported mappings or document the stronger constraint before comparison.
Folded nodes are opaque visible boxes. Their compact projected height must never overwrite stored expanded size. Require planned compact size unchanged, move only their stored position, and translate hidden descendants with the nearest visible collapsed ancestor using full visual ancestry. Other omitted placements remain exact. This is an explicit experiment policy, not automatic adoption of new production folding semantics. Reprojection can enlarge expanded containers or move derived ports; record that difference, since it means the final Rust geometry differs from the engine's output assumptions.
Import only flattened node geometry into the original Project clone, without an initial Layout. Apply the same pre-operation visible/unpromoted actual-owner reset predicate to existing route entries; preserve attachments/order and use original-to-final translation for retained routes. Ignore ELK path sections and label positions. Therefore the result measures ELK-informed placement followed by released Rust routing, not full ELK routing quality; labels reserved by ELK may still collide when the Rust router selects different corridors.
Compare raw authored input, existing Layout/reset control, old layered candidate (unsupported rows explicit), and ELK placement with equivalent reset scope. Do not rank omitted folded rows as successes. Evaluate complete Project conservation with geometry/reset exceptions, compact and expanded containment, fixed anchors, final projected ports, actual Rust routes/labels, named trace tasks, and ID permutation sensitivity. One frozen-input repeated run establishes deterministic transfer only; repeated arrange/reproject feedback is a separate idempotence check. Reject nonfinite/missing/duplicate/out-of-scope nodes and invalid dimensions before any model mutation. A five-case benchmark can justify the next experiment, not production adoption.
@@ -0,0 +1,45 @@
# Sparse placement / released-router compatibility diagnosis
Read-only arithmetic and source inspection; no routing, compiler, GUI or ELK invocation. Source: research worktree `crates/oa-core/src/routing.rs`, released implementation. Frozen imported scene: `elk-reference-20260925/rust-run02/subsystems_40_sparse-elk/stdout.jsonl`; raw engine output: `run01/subsystems_40_sparse/elk-result.json`.
## Finding
**The raw ELK route is clear of all forty actual node interiors but is not feasible under the core clearance and terminal-stub contract. The recorded NoClearPath is caused before bounded search, not by search exhaustion.** No inference about global engine superiority or a missing grid lane follows from this witness.
Edge `00000000-0000-0000-0000-00000003347d`, flow_45, connects Assessment Decide placement `...030dcf` to Planning Aggregate `...030ddd`. Both are semantic ports, so `endpoints` (routing.rs:387–409) returns one fixed endpoint pair. Source bottom tip is (4120,477), mandatory stub (4120,495). Target top tip is (4634,840), mandatory stub (4634,822). Constants are PORT_STUB18 and CLEARANCE12 (lines14–15).
Assessment Package `...030dd1` occupies [4522,4746]×[660,820]. `edge_obstacles` (662–680) inflates it to [4510,4758]×[648,832]. The target stub is strictly inside this unrelated obstacle. The target lead from y840 to822 intersects its interior over y822..832. `route_edge` (830–840) skips the sole pair because its terminal lead crosses an unrelated inflated obstacle. Both cheap and grid passes therefore skip it; neither search is entered for this edge. No exhausted flag is set. Fallback (898–938) retains the mandatory leads and selects the lesser-obstacle-count L path, yielding the recorded vertical x4634 segment through Assessment Package. Its warning is consequently NoClearPath rather than SearchBudgetExhausted. Increasing search limits or adding candidate axes cannot repair this terminal incompatibility.
All forty nodes have visual_parent=None. There are no ancestor-header exemptions to reconstruct. The original imported full Project has no authored route pins for this edge; this is an automatic route with semantic endpoints.
## Raw ELK witness checked against every node
Recorded points: (4120,477), (4120,498), (4502,498), (4502,830), (4634,830), (4634,840). Independent orthogonal interval tests on every segment and all40 rectangles find zero uninflated node-interior intersections. Applying the core12-unit inflation finds:
| Segment | Core inflated obstacle intersection |
| --- | --- |
| (4120,477)→(4120,498) | Communications Publish `...030dc3`, inflated [3996,4244]×[496,652]; last2 units enter its clearance. Source owner alone is exempt on its lead. |
| (4120,498)→(4502,498) | Same Communications Publish clearance. Actual top508 gives only10-unit separation. |
| (4502,498)→(4502,830) | None. |
| (4502,830)→(4634,830) | Assessment Package inflated bottom832 and Planning Aggregate inflated top828 both obstruct the horizontal tail. Actual gap is only20 units. |
| (4634,830)→(4634,840) | Assessment Package inflated obstacle for y830..832. Target owner alone is exempt on its lead. |
The raw final lead is10 units, less than mandatory18. It also turns inside the target's inflated region; exempting the actual target lead does not exempt the preceding horizontal segment. Source lead21 exceeds18 but proceeds into another node's clearance. Comparisons use strict rectangle interiors with epsilon; distances2 and10 are far from numerical ambiguity. No visual or glyph claim is made.
## Smallest useful next test
First add a focused fixed-semantic-port obstacle fixture to the evaluator/tests, using these exact target/package rectangles. Assert the explicit geometric witness: target stub inside unrelated inflated obstacle, no admissible18-unit lead, NoClearPath with unchanged tips and visible fallback warning. This falsifies the hypothesis that more search alone should solve the scene. A warning/fallback test is characterization, not acceptance of the penetration.
Then test a placement compatibility predicate before routing: every mandatory semantic-port lead must be clear of unrelated inflated rectangles; separately check a departure/arrival corridor outside the endpoint's own inflated rectangle. Report incompatible edge/port/obstacle identities rather than scoring fallback as a successful arrangement. For this top-entry pair with horizontal overlap, necessary vertical separation is at least PORT_STUB+CLEARANCE=30 (currently20), ignoring epsilon. A 30-unit gap only makes the lead geometrically admissible; it does not prove a complete route or label solution. Keep other geometry and port identities fixed in a minimal two/three-node witness to test that boundary, then evaluate any actual placement adjustment on the complete frozen scene with normal reprojection and unchanged released router.
For an ELK adapter experiment, reserve sufficient port-facing separation and check returned placements before transfer. Do not blindly increase a global spacing option and assume it enforces every compound/port constraint. Reject/report failures without changing authored anchors or persisting engine bends. Core-router policy alternatives (shorter adaptive stubs, reduced clearance, alternate port side) would change the contract and are separate decisions, not a lane-search fix.
## Scope and evidence
This explains this specific edge's fallthrough directly from immutable scene geometry and source branches. It does not run or instrument the search. Uninflated raw-path feasibility is narrower than core feasibility. Any corrected importer run must confirm the same node/port coordinates before reusing the conclusion.
- .local/auto-layout-20260925/crates/oa-core/src/routing.rs: SHA256 b377fe80cece3892d64f62ba5e1578d8974eeefc2a317620f343a86f2f257fbd.
- .local/elk-reference-20260925/rust-run02/subsystems_40_sparse-elk/stdout.jsonl: SHA256 37ef8db5a920a50a1ed12eba08913fee810d02226d920fc9018088c9e7b14c3a.
- .local/elk-reference-20260925/run01/subsystems_40_sparse/elk-result.json: SHA256 9763cda98e744040e1f2e9ad63662cf6e699e8fbdc7e77b388d60ab4303a4282.
@@ -0,0 +1,43 @@
# Connection-layout transfer audit — run01 / rust-run02
Independent read-only audit of source `8a2010d8a6033201d6efd742134dae9f3d235632`; no engine, Rust, compiler or GUI rerun. Results are diagnostic, not production adoption.
## Findings requiring qualification/correction
1. **Identity import is not reset-only.** All five plans preserve original positions, but the importer writes projected effective dimensions into stored expanded sizes: 3 placements in workshop original, 2 folded, 10 each mixed, and 40 sparse. Mixed stored height94 becomes effective height132, for example. These are real full-Project differences, not float spelling. The three ELK plans likewise keep original projected dimensions yet normalize stored sizes unnecessarily. Minimum correction: when supplied size equals the original projected size (typed f32), retain original stored size; write size only when the plan actually requests a different projected size. Keep collapsed exact-size admission and verify final reprojected dimensions against the plan. Parent has accepted this correction for a separately recorded Rust rerun; run02 remains the original evidence.
2. **ELK FIXED_POS ports are not faithfully transferred by placement-only import.** Every final projected node position and dimension in the three ELK imports exactly equals the recorded ELK plan. Nevertheless, Rust reselects automatic port sides/slots using the new geometry. Mixed and reversed mixed each have 10/25 materially changed port positions and 7 side changes; sparse has 48/110 changed positions and 32 side changes. Maximum coordinate discrepancy is224 world units. No small rounding-only differences occurred in these comparisons. Six authored anchored ports in each mixed case are exactly equal to ELK world coordinates; all material discrepancies are automatic ports. Thus this experiment evaluates placement followed by the existing projection/router, not preservation of the ELK edge-port geometry or ELK quality.
Eight mixed edges and29 sparse edges touch changed ports. Concrete mixed examples: `flow_01` Sensor B observations (`…01adb1`), `flow_03` Archive incoming observations (`…01adb3`), `flow_04` Validated observations (`…01adb4`), `flow_08` Actuator dispatch (`…01adb8`). Sparse examples: `flow_00` Sensing Acquire to Decode (`…033450`), `flow_01` Sensing Decode to Validate (`…033451`), `flow_03` Sensing Enrich to Aggregate (`…033453`), `flow_05` Sensing Decide to Package (`…033455`). Complete identities/coordinates remain in each imported stdout's `after.projected_ports/projected_edges` and corresponding run01 `placement-observation.json`.
## Preservation and limits
Independently recursively compared full before/after Projects for all eight successful imports and five Arrange outputs. Changes are confined to target-diagram node position/size and the intended mixed authored route reset. Semantic records, other views, placement identity/visibility/anchors, target diagram nongeometry, route entry identity/order and any attachment fields are unchanged. The mixed route (`…01adbd`, reversed `…01adb0`) retains its entry, clears its one authored waypoint and label; it is a visible non-promoted projected edge. Other import fixtures contain no authored routes. Consequently these outputs **do not exercise retained hidden/promoted authored-route translation**, multi-entry ordering, or nonempty authored attachment preservation. Source inspection confirms the importer invokes original-to-final `translated_routes` then resets only the captured eligible set; that is source evidence, not coverage of missing cases.
Folded identity import preserves the collapsed placement's stored expanded size272×600 exactly and has no position changes (including hidden descendants). The deliberate changed compact-size plan fails with the explicit collapsed-size rejection. Nonzero hidden-descendant translation remains unexercised: both workshop ELK attempts fail before engine invocation on undirected edge `22c7011d-b559-5df8-aadd-851002904ba0`. They must not be counted as successful hierarchical ELK transfers.
All eight successful import records report exact JSON and single-source round trips without errors. Five actual Arrange records separately report exact undo/redo, one history entry, second-call stability and before/after source/JSON round trips. The imported candidate is a pure transformation, not a Command/history/native GUI test. Five deliberate malformed plans (missing, duplicate, unknown ID, zero size, changed collapsed size) exit101 with the corresponding admission error; they are expected rejections, not successful imports.
## Evidence bindings
Read back175 recorded file bindings across Rust receipt/capture, excluding live target paths: all SHA256 and byte sizes match. All14 Rust invocations have expected exits and unchanged inputs; successful stderr is empty. Verified run01 successful output hashes; three ELK successes record source and bundle unchanged, while both unsupported workshop attempts remain failed.
- `rust-run02/receipt.json`: `7bd7b5dc2da6e078ab9bbec22671cadcb34f6d56765d533c755d1bfbf0465d44`.
- `rust-run02/capture.json`: `649e2f9f27f0d4283ba3b20ad4a3329b9008aeda3a7e80786ebdb2a91667acd4`.
- Preserved Rust binary: `3d0e5aced282761e89b6a36fdcdc79730029db721580941c7fe0315f4ba29f4c`; build receipt `de5b87f55d2b77a61297727940c9ba83fdf2a02aa807b5c8f33b751547fffef5`. Capture explicitly attributes the binary to immediate exclusive-target capture, not a compiler-exit binary hash.
Paths above are relative to `.local/elk-reference-20260925`. Recommendation: correct avoidable stored-size normalization and repeat only Rust transfer checks under a new pin. Preserve the measured automatic-port divergence as an experiment limitation; do not claim faithful ELK routing/port transfer or adopt it from these results.
## Corrected Rust run03 — identity-size finding closed
Read-only audit of `fc5c22c903c70b53102fa65e1b8cfdc971f877f1`, preserving run02. Independently reconstructed each identity expected Project by retaining the complete original and clearing only the existing eligible mixed route waypoint/label. All five identity outputs equal those full expected Projects exactly. All stored sizes now remain exact, including collapsed expanded sizes. All three ELK imports likewise preserve original stored sizes. Thus the avoidable geometry normalization finding is closed for these cases.
For all eight corresponding imports, complete `before` and `after` metric/geometry objects and `final_projected_ports` equal run02 exactly as parsed JSON. The full Arrange control stdout is byte-identical. Full import stdout is intentionally not byte-identical because corrected after-Project stored dimensions differ. Automatic-port discrepancies therefore remain exactly those measured above; the correction does not solve or obscure them. All eight import round-trip flags remain exact/error-free.
Read back179 run03 receipt/capture file bindings (excluding live target paths): every hash and byte size matched; inputs unchanged. The original14 invocations have expected exits. Added `negative-below-minimum` unexpectedly exits0 and must remain a failed negative-test expectation: its plan specifies width1, height132 for placement `…018705`, and final projection actually is width1, height132 at the requested position. Therefore this case does not demonstrate a reprojection-guard defect; its supposed minimum-width precondition is false. It also does not establish acceptable visual readability for width1. Parent plans a separate height1 case to exercise the real vertical-port minimum; no such result was assumed in this audit.
Run03 receipt SHA256 `aaee622d1c93fbdcbb56a16c411a62b30b4242606004704e660e46af5aaca914`; capture SHA256 `90c2b7810b1b9df1d8a41c19f0dce0c49ba9aa9ef8a25ead89caa909584cc30d`. No execution or source edits by reviewer.
### Corrected minimum-size rejection — final readback
Separately reviewed `rust-height-minimum/receipt.json`, plan and logs under the same fc5c22c9 source/preserved binary (`142e88eefedd57acae17f5ebd5b45a9edf682b9d5e5740ab57d2b2fa1d866e98`). The plan sets height1 on `…018705`; stdout is empty and exit101 stderr explicitly reports `Final Rust projection differs from intended node geometry`. Read back all12 before/after/log hash-and-size bindings successfully; inputs remain unchanged. This exercises the final reprojection rejection for the actual vertical-port capacity constraint. It closes the missing negative-test coverage caused by the wrong width precondition; the original width1 unexpected success remains preserved and is not relabeled. Audit frozen after this readback; no reviewer execution.
@@ -0,0 +1,47 @@
# Bounded placement compatibility design for #32
Recommendation: implement **A's small shared core feasibility seam, then B's bounded separation pass as the first experimental consumer**. This is one practical increment toward a native connection-aware planner, not a new router or a general constraint framework. Keep the released router, automatic-port projection policy and accepted Arrange reset/history contract fixed. C remains a diagnostic reference, not the next production step.
This source-only assessment follows reference2850b915 and the exact sparse diagnosis in `placement-sparse-routing-diagnosis-20260925.md`. No source changes, compiler, router or GUI execution were performed.
## What the source requires
- `routing.rs:387–409` maps actual projected semantic ports to exactly one tip and outward18-unit stub. Explicit non-port attachment preferences also constrain endpoints; otherwise four alternatives exist. `route_diagram_impl:519–541` handles promoted ownership, attachment suppression and existing authored route selection before endpoint generation. A planner must not approximate these choices independently.
- `edge_obstacles:662–680` preserves endpoint-ancestor headers, inflates obstacles by12; `route_edge:830–840` exempts only each lead's own endpoint owner from that lead's collision check. `fast_path:1056–1062` and `grid_path:1153–1159` also reject stubs inside any obstacle. Terminal lead clearance is necessary, not sufficient for complete routing.
- `projection/port_layout.rs:156–245` chooses automatic sides from peer centers, semantic fallback and clear exits, then overrides manual anchors. Lines246+ grow capacity and enclose nodes after freezing side choices for that projection call. Reprojecting a new placement can therefore change automatic side, order and effective node size. Fixed semantic port identity does not mean fixed automatic coordinates.
- The existing `examples/auto_layout_probe/layered.rs:27–83` starts with Layout, rejects folded/omitted topology, resets routes, and uses one global largest label for all gaps. Its three passes use boundary-neighbor order but no final lead-compatibility feedback. It is a useful coordinate-assignment skeleton, not ready for adoption; sparse shared-run regressions remain independent of terminal clearance.
## Alternatives and decision
| Alternative | Benefit | Concrete cost / failure | Decision |
| --- | --- | --- | --- |
| A. Shared core endpoint/lead feasibility, then constraint-aware placement | One authority for projection/attachments/promotions/ancestor obstacles. Planner can reserve actual required space and identify blockers. | A broad public routing API would ossify internals; pure advance spacing cannot predict every automatic-port flip. | Add only a small internal, read-only report reused by routing's lead guard and planner. Combine with actual reprojection. |
| B. Postplacement separation with actual reprojection | Small experiment on existing layered output; fixes the exact sparse gap without importing external routing. Tests whether locally enforcing clearance is useful before restructuring all coordinate assignment. | Arbitrary nudging can destroy layers/containment, oscillate as ports flip, and grow area indefinitely. A duplicate obstacle implementation would drift. | First consumer of A, with fixed sibling order, monotone gap constraints, finite rounds and atomic failure. Do not ship a free-form nudge loop. |
| C. ELK free automatic ports / coupled geometry | May let mature layout select compatible port-facing space; useful reference for quality ceiling. | Rust reselects automatic ports after import; importing ELK port locations would change application semantics or persist derived state. Node-level fixed/free policies complicate mixed authored/automatic anchors. Engine lead spacing differs from core. | Defer as implementation. Optional later diagnostic only if native bounded experiment fails a named case. |
## Small implementation seam
Extract a shared predicate for endpoint-pair lead admissibility and stub containment using the already constructed endpoints/edge obstacles. Routing should call exactly that predicate without changing endpoint order, search costs or fallback. A planner-facing internal report can identify edge, end, actual owner, semantic port or attachment, tip/stub, blocker ID/bounds and which guard failed. It must preserve alternative endpoints: an unconstrained non-port end is not infeasible merely because one of its four sides is blocked. Report a hard incompatibility only when no allowed pair survives. For the first separation consumer, act only on singleton endpoints with a unique unrelated obstacle; leave ambiguous alternatives explicit rather than choosing a new persistent attachment.
Reuse the same effective-route selection (promotion suspends custom attachments; semantic ports take precedence) as routing. Avoid a public serializable constraints model, desktop dependency, whole routed path search or label measurement within this report. A private helper plus thin crate-visible wrapper is enough. For a diagnostic example outside the crate, expose only the narrow report if needed, or run the test inside core instead of making every routing internal public.
## Finite native experiment
1. Preserve the original Project and freeze Arrange reset eligibility. Compute the existing connection-aware sibling order/ranks once, including its explicit cycle fallback; keep released/reset control available for comparison. Do not use repeated Command::Layout inside repair.
2. Project the candidate, obtaining actual automatic ports, projected sizes and obstacles. Obtain the shared incompatibility report. If none, proceed to final routing; this is not yet a quality pass.
3. For an actionable blocker, add a separation inequality to the **existing sibling/rank coordinate assignment**, not an arbitrary node translation. Lift owner and blocker to distinct movable child subtrees under their lowest common visible ancestor; translate whole subtrees, including latent folded geometry. If no distinct movable groups exist, report unsupported constraint. Keep sibling order/orientation fixed. Choose a consistent existing ordering axis; for the exact vertically stacked sparse pair, require owner top >= blocker bottom +30. The30 is this 18-unit outward lead plus12 clearance, not a universal node gap. Prefer a small explicit numerical margin for new placement, leaving router epsilon unchanged.
4. Recompute positions and parent enclosure from frozen minima and accumulated gap requirements. Reproject; side changes or capacity growth generate new constraints. Allow at most four repair rounds and a fixed global constraint/work bound. Never alternate swapping the same siblings or add gaps to already inflated stored sizes. Repeated identical geometry with unresolved constraints, opposite incompatible order constraints, excessive extent or exhausted rounds returns an explicit experimental failure and leaves original untouched. The first finite bound is an experiment limit, not proof of convergence.
5. Route the final candidate once with the released router; reject newly introduced unrelated-node penetrations or NoClearPath. Separately assess existing quality vector and trace tasks against reset control. All metadata reconstruction happens once from original to final deltas; retain existing route entries/order/attachments/port anchors, clear only eligible pins/full labels, and preserve hidden/promoted metadata via accepted translation. Production adoption would apply one candidate through the existing transaction/history path with final validation.
This experiment should first use flat sparse and mixed fixtures plus one nested pair, not silently claim all OA/SA/State layouts. The current layered folded/omitted rejection must remain explicit until the separate full-forest policy is implemented. A repair pass does not resolve the prototype's enormous shared runs: if those persist, do not accept it merely because lead clearance succeeds.
## Finite falsifiers and delivery point
- Exact sparse witness: at20-unit gap the target18-unit stub intersects the unrelated12-inflated obstacle; at30 plus declared placement margin the mandatory lead must clear. All tips/port identities follow final projection; no authored anchor edit or persisted bends.
- Automatic-side flip: moving a peer changes side; feasibility is reevaluated on the changed side. A stale first-projection pass is a failure. Shared semantic port must remain one port for all incident edges.
- Fixed-anchor witness and constrained non-port attachment: keep authored values exact; move geometry or fail. An unconstrained non-port edge with one clear side must not force unnecessary separation for its blocked alternatives.
- Nested obstacle: entire selected child subtree moves, children stay enclosed below headers, other branches and all semantic records remain exact. Folded/filtered cases must either satisfy the declared full-forest policy or return explicit unsupported; no unsupported-as-pass accounting.
- Same input twice must match; ten repeated full Arrange candidates must not accumulate clearance or oscillate. A two-cycle or container growth falsifies the proposed assignment scheme.
- Existing five-case frozen corpus: full conservation, actual projected geometry, warnings and unrelated penetration checks; retain label/crossing/shared-run/area values and original named trace tasks. Required outcome is no new hard routing failure plus at least a concrete connection-tracing improvement on a supported real scene. No scalar quality winner inferred from safety alone.
Stop after the shared seam, sparse/fixed-port tests and one bounded repair candidate are evaluated. If repair needs changing sibling order repeatedly or cannot fix the sparse witness without unacceptable displacement, move the constraints into coordinate assignment/ranking rather than adding more repair iterations. If it fixes terminal compatibility but old layered quality remains poor, next work is connection order/corridor allocation, not router penalty tuning. This yields a runnable, falsifiable increment without committing to an external engine or a general solver.
@@ -0,0 +1,986 @@
{
"schema": 1,
"source_commit": "074051261a0beee1047e2b5624c879deef7813bc",
"archive": {
"file": "placement-clearance-07405126.zip",
"bytes": 3887975,
"sha256": "0589a3d413596eec697bab37934d504b055bcf2ab53a0ccc0248ddc107e4a71c"
},
"members": [
{
"member": "collector/analyze-placement-clearance-20260925.py",
"bytes": 3875,
"sha256": "a52be0f3d79870eb554f52036bea032d72e5e641207a21b05f4f6a0779b32da5"
},
{
"member": "collector/analyze-placement-clearance-v2-20260925.py",
"bytes": 3907,
"sha256": "386225a8216e03a4a629e0dbe75d6cc1543d6cf5a20a5ad386e81621d3d5d4b7"
},
{
"member": "collector/archive-placement-clearance-20260925.py",
"bytes": 2866,
"sha256": "67d1f13a7e089668d45f8de10f6567e8c801ed65367ca20e25a1f82f90181bc1"
},
{
"member": "collector/run-placement-clearance-20260925.py",
"bytes": 4663,
"sha256": "8f4a7b8ad7ad10ef854503cd171068a8b395895dfafb82f1f09961e81bbe8fcd"
},
{
"member": "collector/run-placement-clearance-v2-20260925.py",
"bytes": 4727,
"sha256": "3e2449c87938ed233d68fe8f2db53c97e0b5aaa1ced021dbe7217f782a7e0d98"
},
{
"member": "collector/run-routing-corpus-check-20260925.py",
"bytes": 2793,
"sha256": "2726a397bd4ecb4dcfff6fc170a66ce2655229079f42335faa2a4bfe4a202f6d"
},
{
"member": "gates/13-clearance-core-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/13-clearance-core-tests/command/context.json",
"bytes": 3614,
"sha256": "17b422a15ea082957859136d11d2cabe19fdbd66e9d7f1a6143fd104870a1a5f"
},
{
"member": "gates/13-clearance-core-tests/command/inputs-after.json",
"bytes": 1750859,
"sha256": "f0483f2f9ce586c5dafd6e4639dc59116f21c180599a3aa14305b0029c5d7970"
},
{
"member": "gates/13-clearance-core-tests/command/inputs-before.json",
"bytes": 1750859,
"sha256": "f0483f2f9ce586c5dafd6e4639dc59116f21c180599a3aa14305b0029c5d7970"
},
{
"member": "gates/13-clearance-core-tests/command/output.log",
"bytes": 1951,
"sha256": "aa86ca8b741212dabdec034e5b5d2a6ff42bc34669d4cbc395037a487d422dbc"
},
{
"member": "gates/13-clearance-core-tests/command/result.json",
"bytes": 4286,
"sha256": "5fff01d5334d11f96cb035fc74567c156f7397d65d63738d0331e79a1d17b818"
},
{
"member": "gates/13-clearance-core-tests/command/stderr.log",
"bytes": 529,
"sha256": "bfdd486b19efdb9dc23e71473ec74f121f9f5c1f8871892acb68b3dd35822c09"
},
{
"member": "gates/13-clearance-core-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/13-clearance-core-tests/orchestration.log",
"bytes": 185,
"sha256": "638a9a0b1aeaa2ca4e016ccd20a5afa62b8d11ff84e9b37c1ac6500996f9b0da"
},
{
"member": "gates/14-clearance-core-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/14-clearance-core-tests/command/context.json",
"bytes": 3614,
"sha256": "e747d3edc3a8e22c412611866ef6a04a340dce9c5dfbf6c45f267b8f3be4c81d"
},
{
"member": "gates/14-clearance-core-tests/command/inputs-after.json",
"bytes": 1750859,
"sha256": "0232386c3fd6ce76cbc2b4919077fffdd1d8a5fe8eda2d04dcae783ee668c9e4"
},
{
"member": "gates/14-clearance-core-tests/command/inputs-before.json",
"bytes": 1750859,
"sha256": "0232386c3fd6ce76cbc2b4919077fffdd1d8a5fe8eda2d04dcae783ee668c9e4"
},
{
"member": "gates/14-clearance-core-tests/command/output.log",
"bytes": 3737,
"sha256": "6fe31a1fb49deaf06acbaf4f4f88a9188ccb132b8cbe72e051113d2d35302ee5"
},
{
"member": "gates/14-clearance-core-tests/command/result.json",
"bytes": 4284,
"sha256": "67e97e872a0e7936239fe3c3557ed04b2d1542854642017113e5dfc88dbe86c5"
},
{
"member": "gates/14-clearance-core-tests/command/stderr.log",
"bytes": 729,
"sha256": "2540d375f541048be3088c1e1bc4e9d6585ac706490d0823ce6d9f600a199ac5"
},
{
"member": "gates/14-clearance-core-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/14-clearance-core-tests/orchestration.log",
"bytes": 183,
"sha256": "7370c8cba21844ca9b00078dba0c7a03830e32161b102715c97825deb77a9395"
},
{
"member": "gates/15-clearance-unit-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/15-clearance-unit-tests/command/context.json",
"bytes": 3521,
"sha256": "384bba6f9aa5b50ffffa29cd73ef2185882cc62bbd53c25e02e4c31293ba1c4a"
},
{
"member": "gates/15-clearance-unit-tests/command/inputs-after.json",
"bytes": 1750859,
"sha256": "0232386c3fd6ce76cbc2b4919077fffdd1d8a5fe8eda2d04dcae783ee668c9e4"
},
{
"member": "gates/15-clearance-unit-tests/command/inputs-before.json",
"bytes": 1750859,
"sha256": "0232386c3fd6ce76cbc2b4919077fffdd1d8a5fe8eda2d04dcae783ee668c9e4"
},
{
"member": "gates/15-clearance-unit-tests/command/output.log",
"bytes": 14004,
"sha256": "e8e8079c8c5f7e7b7083d408d5f9810ebd4697c0365ec4c5312f5e237aa67b60"
},
{
"member": "gates/15-clearance-unit-tests/command/result.json",
"bytes": 4192,
"sha256": "a7e897f626d6adcca2db2ec79e1d4a7764a87c892c7a36bcd0025847877deaf7"
},
{
"member": "gates/15-clearance-unit-tests/command/stderr.log",
"bytes": 463,
"sha256": "f30d41bf925b7ff2169e0e34d3bd287274bba9dc966484290cec202c06e2f240"
},
{
"member": "gates/15-clearance-unit-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/15-clearance-unit-tests/orchestration.log",
"bytes": 183,
"sha256": "5dafd9bd73d6e6714baadf9ffd01cdfa22572a72882d6c6587e531fc4765c50d"
},
{
"member": "gates/16-clearance-release-build/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/16-clearance-release-build/command/context.json",
"bytes": 3536,
"sha256": "5c22dcf46818a8067f3e465725597510c7e29a32db6bfba1a7b7e912f9e57de5"
},
{
"member": "gates/16-clearance-release-build/command/inputs-after.json",
"bytes": 1750859,
"sha256": "0232386c3fd6ce76cbc2b4919077fffdd1d8a5fe8eda2d04dcae783ee668c9e4"
},
{
"member": "gates/16-clearance-release-build/command/inputs-before.json",
"bytes": 1750859,
"sha256": "0232386c3fd6ce76cbc2b4919077fffdd1d8a5fe8eda2d04dcae783ee668c9e4"
},
{
"member": "gates/16-clearance-release-build/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/16-clearance-release-build/command/result.json",
"bytes": 4209,
"sha256": "b2b897fae6648e0b781f660af1bc893d4393015e4603f490a3cba87475bd3c1e"
},
{
"member": "gates/16-clearance-release-build/command/stderr.log",
"bytes": 179,
"sha256": "2e3fa75afc6e2730e915bef139c9cf8d61d48819a4b43b75be8908efddb58cd3"
},
{
"member": "gates/16-clearance-release-build/environment.json",
"bytes": 9470,
"sha256": "1cda80470e5893747b1aad7eda5ef51d57069441e810698cd7f94f7a7521bfe5"
},
{
"member": "gates/16-clearance-release-build/orchestration.log",
"bytes": 186,
"sha256": "81b845a84ea6596724b39645b2aa13219d5da6ecd90e5f04064223dce6743cb8"
},
{
"member": "gates/17-clearance-clippy/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/17-clearance-clippy/command/context.json",
"bytes": 3592,
"sha256": "6ecbef4a4ea2e4d57a9b716815d41755da74689b6c486e6750436ecbaeccd404"
},
{
"member": "gates/17-clearance-clippy/command/inputs-after.json",
"bytes": 1750859,
"sha256": "0232386c3fd6ce76cbc2b4919077fffdd1d8a5fe8eda2d04dcae783ee668c9e4"
},
{
"member": "gates/17-clearance-clippy/command/inputs-before.json",
"bytes": 1750859,
"sha256": "0232386c3fd6ce76cbc2b4919077fffdd1d8a5fe8eda2d04dcae783ee668c9e4"
},
{
"member": "gates/17-clearance-clippy/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/17-clearance-clippy/command/result.json",
"bytes": 4251,
"sha256": "8c6c5562c8ac3b4e59152ace8a37a3dea3816655110f29579d7d2a7dbca6d40f"
},
{
"member": "gates/17-clearance-clippy/command/stderr.log",
"bytes": 177,
"sha256": "3d0e09339f91b9c510019c9d7fb5cc71d390f3b9836ac0e730bee6786f50a3d1"
},
{
"member": "gates/17-clearance-clippy/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/17-clearance-clippy/orchestration.log",
"bytes": 179,
"sha256": "3ca5c950ae1dc1d682540cb2bf903da48d0de29301706a342f2af55bbc16a92f"
},
{
"member": "reviews/placement-clearance-repair-implementation-20260925.md",
"bytes": 2624,
"sha256": "dc18890b4549945f853681b0098b5bfab6036192533226dd93bf642c164f8d4c"
},
{
"member": "reviews/placement-clearance-result-review-20260925.md",
"bytes": 6741,
"sha256": "a368b5d3d133092723918874ed0dda669109654fe37e712ea6425a1ecac1d1ee"
},
{
"member": "reviews/placement-clearance-source-review-20260925.md",
"bytes": 9543,
"sha256": "4f371bc0d2de1103c1a7dbc8452f7a1ec5b79a4b48e99c04263b7e0fba32eeaa"
},
{
"member": "reviews/placement-compatibility-design-20260925.md",
"bytes": 10304,
"sha256": "6f8359433ee8f13387b1bc722a8f84d22163f9ba6d8cf8bf5ca1387cf4f5b9cd"
},
{
"member": "reviews/run01-seed-audit.json",
"bytes": 22389,
"sha256": "f3785e637284923e87e55243436c2b45a1f101fb059d69d8a71b5f0def8380ea"
},
{
"member": "reviews/run02-independent-audit.json",
"bytes": 14244,
"sha256": "ec5094c81dc4f200ec53d01fb0dca9efd0ce71338922043f5a18a3d409a46c10"
},
{
"member": "run01/analysis-failure.txt",
"bytes": 582,
"sha256": "7395e44bf226f93f27785e65ec33de0767d8dfe2f56e5fac4db392d867c51d28"
},
{
"member": "run01/capture.json",
"bytes": 8525,
"sha256": "b95c23e22dcd31615f4728183d53cc047818fc10efd457635bb4f5360c0da0b8"
},
{
"member": "run01/inputs/mixed_dispatch-elk.json",
"bytes": 33766,
"sha256": "99350ea7c1757859b24f243d45432e9340c8be6cbaee3b888934220563fa5da9"
},
{
"member": "run01/inputs/mixed_dispatch-layered.json",
"bytes": 33771,
"sha256": "66064d986aaaceceaee01eff736a3ab704f2aa7e0c67bd82ce784bd077871c43"
},
{
"member": "run01/inputs/mixed_dispatch-reset.json",
"bytes": 33769,
"sha256": "c67e9c08e67aa20ede33ba212c05d85caae2a81d15987899ab15c3ab7ec850fb"
},
{
"member": "run01/inputs/mixed_dispatch_edge_ids_reversed-elk.json",
"bytes": 33766,
"sha256": "af8e8a61a3679cad342731907bead643417d7ec6e3c2aa6c3829525186e25928"
},
{
"member": "run01/inputs/mixed_dispatch_edge_ids_reversed-layered.json",
"bytes": 33771,
"sha256": "0edcad8dbce628792233c6a4f439d64e559142b503b12ec5de5f2b6f79d69fad"
},
{
"member": "run01/inputs/mixed_dispatch_edge_ids_reversed-reset.json",
"bytes": 33769,
"sha256": "d4e62c1183b9ef9fbf12e2e9a2fccbbe2d7e940138c25a811cc4962da2d7ff9f"
},
{
"member": "run01/inputs/subsystems_40_sparse-elk.json",
"bytes": 128200,
"sha256": "ef47a2d066571c04776e8d77426fb0bb40b6d692559eaac82dad9abe8ce14c5c"
},
{
"member": "run01/inputs/subsystems_40_sparse-layered.json",
"bytes": 128215,
"sha256": "7f44ec2ca16f7dec5bffaea1a994a849adaac051fb225bac780818e862a5b965"
},
{
"member": "run01/inputs/subsystems_40_sparse-reset.json",
"bytes": 128215,
"sha256": "54c00e446376f761146a9182b72f6b011ed92b09cbcd7914b294ba408719d219"
},
{
"member": "run01/inputs/workshop_sa_folded-reset.json",
"bytes": 106571,
"sha256": "9ed3116546363d13a3976e525e8432ef28148c55f92b66fdb2e19232f85c61ae"
},
{
"member": "run01/inputs/workshop_sa_original-layered.json",
"bytes": 106573,
"sha256": "4b8dcfb2cb71a352a39b214675460a6fda0aaf4d3fb058fe90f6831f7b442b76"
},
{
"member": "run01/inputs/workshop_sa_original-reset.json",
"bytes": 106572,
"sha256": "36276b9f623ffc83f379d8c9b9b3b1780342c73048c0a4d957b28d59e69f082e"
},
{
"member": "run01/mixed_dispatch-elk/receipt.json",
"bytes": 1101,
"sha256": "e8c63b05fbe8036c17fe911bfae30165572aca901dc6cca90c917c76fca3a059"
},
{
"member": "run01/mixed_dispatch-elk/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch-elk/stdout.jsonl",
"bytes": 88395,
"sha256": "f0b6b120cd5fcea1b1549cc4b764c888a62604d06cd756e53bf4ddda3630e879"
},
{
"member": "run01/mixed_dispatch-layered/receipt.json",
"bytes": 1118,
"sha256": "9a15482d16d5ac3c869711924229ac2b918d7866fb60178cb21fd62af0e6245a"
},
{
"member": "run01/mixed_dispatch-layered/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch-layered/stdout.jsonl",
"bytes": 97523,
"sha256": "6f74101c039421e334d6e442a943e8d5c0afa7eb3d6fb37ebb9bc33e5a10c681"
},
{
"member": "run01/mixed_dispatch-original/receipt.json",
"bytes": 1149,
"sha256": "09c61e5024a9ca925cb3d70be32e70f66b9bf2f036487922244350c1bed77446"
},
{
"member": "run01/mixed_dispatch-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch-original/stdout.jsonl",
"bytes": 87849,
"sha256": "a4a7735df682483085c7b33426789d6fedabe1a25c8335a66cc2005990f833fc"
},
{
"member": "run01/mixed_dispatch-reset/receipt.json",
"bytes": 1109,
"sha256": "4a2c2f44698f3cd569e41d3536dc2768a90506ce0a56401e4e15a44c6da5723e"
},
{
"member": "run01/mixed_dispatch-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch-reset/stdout.jsonl",
"bytes": 98875,
"sha256": "6b1d267ccbda72b8b2bc53ebba2c6cbb4af37a1d736139a38b74ffddd7cde2d6"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-elk/receipt.json",
"bytes": 1173,
"sha256": "656d800ec85058e5e1b89e55d3499c64670e73ad348a0f2896956e72f4324ba0"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-elk/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-elk/stdout.jsonl",
"bytes": 88397,
"sha256": "432e5dd9d5a48d1f2e24090de51114e6627b971c24684fed11d629b44f2fca9d"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-layered/receipt.json",
"bytes": 1189,
"sha256": "45858adf871952488e94e2ad103786e78c886cad5c4611695625507e00e9a313"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-layered/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-layered/stdout.jsonl",
"bytes": 97547,
"sha256": "1d0a7e69c88910f378dd83cbd1bc810648c5ede29945b7e95bd9d3c72d4dffd2"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-original/receipt.json",
"bytes": 1221,
"sha256": "800bf1fc798b77f72005fd5d4fe76c9a11a377b7a513518447d6e391f6565e58"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-original/stdout.jsonl",
"bytes": 87410,
"sha256": "384010f91f91255dbb46b993675bc4fb7f77f988df7b7231bf680950ffacdadd"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-reset/receipt.json",
"bytes": 1182,
"sha256": "1d78d262998d4dc8b15c8dfbbc297971a17ad6629f331141c4d6f62242539148"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed-reset/stdout.jsonl",
"bytes": 99029,
"sha256": "fa1c97f5b9da4cc8b7ac301403b00549bf1360d9d3e09c013f7a8e32b46735d3"
},
{
"member": "run01/receipt.json",
"bytes": 37673,
"sha256": "dfd80e78821c794c01a95fb6e8f2a285d51fe6a712e0d99326d09e3c0c80583d"
},
{
"member": "run01/route-control/receipt.json",
"bytes": 1065,
"sha256": "8f07833144e9eb39e335babd65f926892ee1ee04981579dd4831899d5e3e532c"
},
{
"member": "run01/route-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/route-control/stdout.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"member": "run01/subsystems_40_sparse-elk/receipt.json",
"bytes": 1126,
"sha256": "018895ce332f1e29dc169942cf33b9567f5d4af22819b2c4a97efb33421cb32b"
},
{
"member": "run01/subsystems_40_sparse-elk/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/subsystems_40_sparse-elk/stdout.jsonl",
"bytes": 357601,
"sha256": "ebfd9632d0ea6df9cfbbc8a3511a5566305bf7523c2316d1a4232a717fa3e836"
},
{
"member": "run01/subsystems_40_sparse-layered/receipt.json",
"bytes": 1142,
"sha256": "3947870f761565db0c70f1b2e5a61891f4cd050940d6b283d7e0f2f70be6343c"
},
{
"member": "run01/subsystems_40_sparse-layered/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/subsystems_40_sparse-layered/stdout.jsonl",
"bytes": 368843,
"sha256": "f02bcb62a3e7e11cf994b26e8b5cc074aaff0416ceb122830084f72ba752ffc2"
},
{
"member": "run01/subsystems_40_sparse-original/receipt.json",
"bytes": 1174,
"sha256": "8458a002400e58fd0d96d29f0c7851a269bfb5373d7a9032c31d229ac12b6038"
},
{
"member": "run01/subsystems_40_sparse-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/subsystems_40_sparse-original/stdout.jsonl",
"bytes": 366821,
"sha256": "0cc35e367e737ad0ea1fdd34088fc9a674766dc01cfc5e9913a1392258cc0780"
},
{
"member": "run01/subsystems_40_sparse-reset/receipt.json",
"bytes": 1134,
"sha256": "f5111d579f1ec28931745655b6bc52f6afff5c454a4d63a50e0c1949398abcf5"
},
{
"member": "run01/subsystems_40_sparse-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/subsystems_40_sparse-reset/stdout.jsonl",
"bytes": 435141,
"sha256": "896d90ef5b1ebb92d9c8af1924543f7276ed9cde18f4888f72f4fec0cfc4e90e"
},
{
"member": "run01/workshop_sa_folded-original/receipt.json",
"bytes": 1165,
"sha256": "d28ea27b77a15966b4335af5ab0c8f2785cc34cd359fc4a1540968de1bab215d"
},
{
"member": "run01/workshop_sa_folded-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_folded-original/stdout.jsonl",
"bytes": 95759,
"sha256": "e2266a5fe9334780a0aca2779c7b43daefb65b7317b8568ddb587db176d754e5"
},
{
"member": "run01/workshop_sa_folded-reset/receipt.json",
"bytes": 1126,
"sha256": "8826a3078df460bf8bf0739797f115a8a85851f513e7ce561affc8c36824ca0b"
},
{
"member": "run01/workshop_sa_folded-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_folded-reset/stdout.jsonl",
"bytes": 93205,
"sha256": "4f4f9bf424e92a33cab0cde7b0ce0992b81819b9b2dfcc3c3da2906fd73808e9"
},
{
"member": "run01/workshop_sa_original-layered/receipt.json",
"bytes": 1141,
"sha256": "94ddfa1e3bb49ff730021937385fcb0729861f12292c8957168d62121a96f69b"
},
{
"member": "run01/workshop_sa_original-layered/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_original-layered/stdout.jsonl",
"bytes": 95705,
"sha256": "213f0ce9f8553aa42e07f3b049b0eeb8f8288677afa9b76419e9f2b884bdbfaa"
},
{
"member": "run01/workshop_sa_original-original/receipt.json",
"bytes": 1173,
"sha256": "663087e42eb6dfa3827327dec703474115e87c8b4284bc99a11ec506db83ff6e"
},
{
"member": "run01/workshop_sa_original-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_original-original/stdout.jsonl",
"bytes": 97692,
"sha256": "de792af0b61cefe9dfc5d92f07d9457fba5abbd29cf37af18b7e1c3d712b6a93"
},
{
"member": "run01/workshop_sa_original-reset/receipt.json",
"bytes": 1134,
"sha256": "028abaffbea45b21c53b46753ff6935de709104958571a8d4b4d043440df80a2"
},
{
"member": "run01/workshop_sa_original-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_original-reset/stdout.jsonl",
"bytes": 97045,
"sha256": "94f31323e069aa5bdcb5607294370071fab4ac13563d8f8ab5fa9ddf38822ed8"
},
{
"member": "run02/analysis.json",
"bytes": 20554,
"sha256": "a3441510e8d93dbc2beec36bcbda26c58a4d04b93465e4ada652911bd0cb344a"
},
{
"member": "run02/capture.json",
"bytes": 8528,
"sha256": "6636ae9b791887effa88f0790d683993d610c498073a5f73f1050bfb1d4694d1"
},
{
"member": "run02/inputs/mixed_dispatch-elk.json",
"bytes": 33766,
"sha256": "99350ea7c1757859b24f243d45432e9340c8be6cbaee3b888934220563fa5da9"
},
{
"member": "run02/inputs/mixed_dispatch-layered.json",
"bytes": 33771,
"sha256": "66064d986aaaceceaee01eff736a3ab704f2aa7e0c67bd82ce784bd077871c43"
},
{
"member": "run02/inputs/mixed_dispatch-reset.json",
"bytes": 33769,
"sha256": "c67e9c08e67aa20ede33ba212c05d85caae2a81d15987899ab15c3ab7ec850fb"
},
{
"member": "run02/inputs/mixed_dispatch_edge_ids_reversed-elk.json",
"bytes": 33766,
"sha256": "af8e8a61a3679cad342731907bead643417d7ec6e3c2aa6c3829525186e25928"
},
{
"member": "run02/inputs/mixed_dispatch_edge_ids_reversed-layered.json",
"bytes": 33771,
"sha256": "0edcad8dbce628792233c6a4f439d64e559142b503b12ec5de5f2b6f79d69fad"
},
{
"member": "run02/inputs/mixed_dispatch_edge_ids_reversed-reset.json",
"bytes": 33769,
"sha256": "d4e62c1183b9ef9fbf12e2e9a2fccbbe2d7e940138c25a811cc4962da2d7ff9f"
},
{
"member": "run02/inputs/subsystems_40_sparse-elk.json",
"bytes": 128200,
"sha256": "ef47a2d066571c04776e8d77426fb0bb40b6d692559eaac82dad9abe8ce14c5c"
},
{
"member": "run02/inputs/subsystems_40_sparse-layered.json",
"bytes": 128215,
"sha256": "7f44ec2ca16f7dec5bffaea1a994a849adaac051fb225bac780818e862a5b965"
},
{
"member": "run02/inputs/subsystems_40_sparse-reset.json",
"bytes": 128215,
"sha256": "54c00e446376f761146a9182b72f6b011ed92b09cbcd7914b294ba408719d219"
},
{
"member": "run02/inputs/workshop_sa_folded-reset.json",
"bytes": 106259,
"sha256": "9e920df52394934d23b0a41f6ef9711fd41252a4d5919e0f373839b35487ab49"
},
{
"member": "run02/inputs/workshop_sa_original-layered.json",
"bytes": 106261,
"sha256": "93bd82eceb23e7782519b4c58387c55fbf9618e611c3c14938c2cc32ebbb81e7"
},
{
"member": "run02/inputs/workshop_sa_original-reset.json",
"bytes": 106260,
"sha256": "68ef8ff4ef7bfd1199ae6dbd13039412d022e7f49219fa7c2f81816af9c124d5"
},
{
"member": "run02/mixed_dispatch-elk/receipt.json",
"bytes": 1102,
"sha256": "5473c00e19f59d6d5fa5a33928f9f935f49ff8b8ad502c1aa677717f9210669e"
},
{
"member": "run02/mixed_dispatch-elk/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch-elk/stdout.jsonl",
"bytes": 88395,
"sha256": "f0b6b120cd5fcea1b1549cc4b764c888a62604d06cd756e53bf4ddda3630e879"
},
{
"member": "run02/mixed_dispatch-layered/receipt.json",
"bytes": 1118,
"sha256": "54cd13fb24ae247405dc58f7212da8a30a839b46c3890542049ebb0bdb0df3ab"
},
{
"member": "run02/mixed_dispatch-layered/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch-layered/stdout.jsonl",
"bytes": 97523,
"sha256": "6f74101c039421e334d6e442a943e8d5c0afa7eb3d6fb37ebb9bc33e5a10c681"
},
{
"member": "run02/mixed_dispatch-original/receipt.json",
"bytes": 1150,
"sha256": "e46b48e3e49dc0ccb10372b32a6d369479241e9c009f078bef9f39ff3269c6f9"
},
{
"member": "run02/mixed_dispatch-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch-original/stdout.jsonl",
"bytes": 87849,
"sha256": "a4a7735df682483085c7b33426789d6fedabe1a25c8335a66cc2005990f833fc"
},
{
"member": "run02/mixed_dispatch-reset/receipt.json",
"bytes": 1109,
"sha256": "69451d3930709bd1800ceaa45608f36100ccb2e7685608b77468b3f258cc1180"
},
{
"member": "run02/mixed_dispatch-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch-reset/stdout.jsonl",
"bytes": 98875,
"sha256": "6b1d267ccbda72b8b2bc53ebba2c6cbb4af37a1d736139a38b74ffddd7cde2d6"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-elk/receipt.json",
"bytes": 1173,
"sha256": "ffef9c8dd2d615250c75eeff5f773f9e664cf7a09f96fad7d64877949a6c3e6e"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-elk/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-elk/stdout.jsonl",
"bytes": 88397,
"sha256": "432e5dd9d5a48d1f2e24090de51114e6627b971c24684fed11d629b44f2fca9d"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-layered/receipt.json",
"bytes": 1190,
"sha256": "8b3eaf9b14c96cee74a8bd4d2fe5226e5dfadc8384265260017a197a104f17ad"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-layered/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-layered/stdout.jsonl",
"bytes": 97547,
"sha256": "1d0a7e69c88910f378dd83cbd1bc810648c5ede29945b7e95bd9d3c72d4dffd2"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-original/receipt.json",
"bytes": 1221,
"sha256": "0b2264c14a252c9dd92e048f77179ee93f2fb874e158e5f736f4d913f3c8f0fd"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-original/stdout.jsonl",
"bytes": 87410,
"sha256": "384010f91f91255dbb46b993675bc4fb7f77f988df7b7231bf680950ffacdadd"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-reset/receipt.json",
"bytes": 1181,
"sha256": "51a0b236a09548c517557a8a6e89e358c13a1d5d621230fcd025b5671cb441a4"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed-reset/stdout.jsonl",
"bytes": 99029,
"sha256": "fa1c97f5b9da4cc8b7ac301403b00549bf1360d9d3e09c013f7a8e32b46735d3"
},
{
"member": "run02/receipt.json",
"bytes": 37682,
"sha256": "ea2eeea0e09d9588a5c1a025c058455fa984f46d17a154f08ec4d328732cc1ee"
},
{
"member": "run02/route-control/receipt.json",
"bytes": 1064,
"sha256": "3021239a337c4c68ad71727d49b74316f21f36797926737c131ddea02bcab64e"
},
{
"member": "run02/route-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/route-control/stdout.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"member": "run02/subsystems_40_sparse-elk/receipt.json",
"bytes": 1126,
"sha256": "c1676d9476d3f178e28f483e1274c6f6019b9cbf6863e6fb5c2a68fb317083a8"
},
{
"member": "run02/subsystems_40_sparse-elk/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/subsystems_40_sparse-elk/stdout.jsonl",
"bytes": 357601,
"sha256": "ebfd9632d0ea6df9cfbbc8a3511a5566305bf7523c2316d1a4232a717fa3e836"
},
{
"member": "run02/subsystems_40_sparse-layered/receipt.json",
"bytes": 1142,
"sha256": "10a62ab568ef9b3b1f4e04bf2002cc5df508e1e983db955c5862fbce2b1650e7"
},
{
"member": "run02/subsystems_40_sparse-layered/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/subsystems_40_sparse-layered/stdout.jsonl",
"bytes": 368843,
"sha256": "f02bcb62a3e7e11cf994b26e8b5cc074aaff0416ceb122830084f72ba752ffc2"
},
{
"member": "run02/subsystems_40_sparse-original/receipt.json",
"bytes": 1174,
"sha256": "243a8f870cdcc3ec4e47dbb6cf19a896672bd1a7040db9c301728752b474bc39"
},
{
"member": "run02/subsystems_40_sparse-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/subsystems_40_sparse-original/stdout.jsonl",
"bytes": 366821,
"sha256": "0cc35e367e737ad0ea1fdd34088fc9a674766dc01cfc5e9913a1392258cc0780"
},
{
"member": "run02/subsystems_40_sparse-reset/receipt.json",
"bytes": 1134,
"sha256": "3b80d2939f1afadde3f37048dc4ea79fb0e4b142ec78dd8d9e82fc55b9bbfbbb"
},
{
"member": "run02/subsystems_40_sparse-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/subsystems_40_sparse-reset/stdout.jsonl",
"bytes": 435141,
"sha256": "896d90ef5b1ebb92d9c8af1924543f7276ed9cde18f4888f72f4fec0cfc4e90e"
},
{
"member": "run02/workshop_sa_folded-original/receipt.json",
"bytes": 1166,
"sha256": "596ac22850349c04fe91ac3e9952e565c754659bcde853d479b0949f898ceb74"
},
{
"member": "run02/workshop_sa_folded-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/workshop_sa_folded-original/stdout.jsonl",
"bytes": 95759,
"sha256": "e2266a5fe9334780a0aca2779c7b43daefb65b7317b8568ddb587db176d754e5"
},
{
"member": "run02/workshop_sa_folded-reset/receipt.json",
"bytes": 1126,
"sha256": "724482facb67292b3571f49473bb7b031b30b19da5c83dbb6bc6672e97264fc7"
},
{
"member": "run02/workshop_sa_folded-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/workshop_sa_folded-reset/stdout.jsonl",
"bytes": 93076,
"sha256": "95d778bbe3dee916e4204afc50e20b6b6f9b73e40589707948b3db3a73680c3d"
},
{
"member": "run02/workshop_sa_original-layered/receipt.json",
"bytes": 1142,
"sha256": "1ef9543b9c6421b5dc55d69157861d2d2e28ee4c0496b17f99fd7d62cc288a30"
},
{
"member": "run02/workshop_sa_original-layered/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/workshop_sa_original-layered/stdout.jsonl",
"bytes": 95576,
"sha256": "cdeb01dfcd147f74f9f3f367b1db0ca7cc45721f6ad09d5d6d0a534783c42611"
},
{
"member": "run02/workshop_sa_original-original/receipt.json",
"bytes": 1173,
"sha256": "960c99b78fdfb2d0b7cc6fe912ae4d74195edb9d91bc33206ac1c9f5398e5719"
},
{
"member": "run02/workshop_sa_original-original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/workshop_sa_original-original/stdout.jsonl",
"bytes": 97692,
"sha256": "de792af0b61cefe9dfc5d92f07d9457fba5abbd29cf37af18b7e1c3d712b6a93"
},
{
"member": "run02/workshop_sa_original-reset/receipt.json",
"bytes": 1134,
"sha256": "37f8a5fb878e988dfd62641b6df35c0801fe176906c4e5afd8f826cba22a88ee"
},
{
"member": "run02/workshop_sa_original-reset/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/workshop_sa_original-reset/stdout.jsonl",
"bytes": 96916,
"sha256": "9940aa16725bb801e97ff2d2abda0256a7ac5ab3d25609c13f684905f213b363"
}
]
}
@@ -0,0 +1,28 @@
# Final clearance evidence and claim review
2026-09-25. Read-only review of `harness/experiments/placement-clearance-20260925/results.md`, the final related `harness/DECISIONS.md` section, run02 analysis/receipt, independent result review, gate receipts/logs and evidence archive. No compiler, routing/repair execution or GUI actions.
**Verdict: no material overclaim, missing failure or unsupported adoption claim found.** Ready for the parent's documentation checkpoint, with local-only publication status retained until an actual successful push/readback. The record correctly separates solving the named mandatory-lead conflict from general layout quality and native usability.
Verified facts:
- Gates14–17 identify tested executable source `074051261a0beee1047e2b5624c879deef7813bc`, exit0, unchanged inputs and no runner failure. Gate14 log counts5+4+13+18=40 integration tests; gate15 counts130 library and2 example tests. Optimized build and strict Clippy success are recorded. No broader-suite claim is made.
- Both runner receipts contain18 completed, non-timeout, exit0 children with unchanged bound inputs and byte-exact released route control. This does not turn unsupported candidate results into successes. Primary run02 analysis accounts for all17 scenes:12 supported and5 workshop-topology refusals.
- Only sparse ELK changes node geometry, moving8 nodes and23 ports with no side changes. The two original mixed scenes change route/bounds metrics through the declared reset without node/port movement; results explicitly avoid attributing that to clearance repair.
- Sparse lead incompatibility, NoClearPath and unrelated-node penetration each change1→0 while overlap remains0. Reported regressions20→22 crossings,55→58 contacts,666→761 shared length and0→1 label/stroke intersection match primary analysis and independent review. The stated outcome does not infer native unreadability or improvement from those metrics alone.
- The independent result review supplies complete Project conservation and port-identity checks beyond the observer's broad booleans, independent raw-contact/penetration arithmetic, and recorded repeat/roundtrip coverage. Documentation keeps automatic side changes, compounds, opposite-order rejection, native tracing and timing guarantees outside the established scope.
- Gate13's invalid primitive DataType fixtures and the corrected Record fixture are explicit. The first runner's cp1252 decoding issue is preserved, with81 altered string leaves across three workshop seeds, no numeric differences, and run02 designated primary. Unsupported topology, previous quality problems, and publication failure are not omitted.
Archive independently read back: `placement-clearance-07405126.zip`,195 members,3887975 bytes, SHA256 `0589a3d413596eec697bab37934d504b055bcf2ab53a0ccc0248ddc107e4a71c`. ZIP CRC test passes and every member's byte count/SHA matches `manifest.json`. Gate13 receipts and both the run01 seed audit and run02 independent audit are present. This confirms the archive integrity claim; it does not add a new execution or usability result. This final review is outside that immutable archive.
One minor wording issue: reproduction says “archived v2 collector” when the intended executable workflow is the v2 experiment runner. The archive collector packages existing evidence. Prefer naming that runner or changing “collector” to “runner”; this is not a correctness blocker.
Independently inspected the subsequent `clearance.rs` diff: only the16-factor work-charge comment changes, with no executable statement changed. The source review already treated it as a weighted budget, not a conservative bound on actual scans/projection work or wall time. Executable gates remain attributed to07405126; document the later comment explicitly rather than claiming a fresh tested source pin.
Reviewed document hashes at inspection (subsequent wording updates may change them):
- results.md: `7ac0155cb52acd2a3b0ba9782c0b7387a3efe19daa0d6a9346e9acae70bd3d7e`.
- result-review.md: `a368b5d3d133092723918874ed0dda669109654fe37e712ea6425a1ecac1d1ee`.
- DECISIONS.md: `5ebc04454e9f736bde41befa9575a06c08c08d3539b5c89fa59b82be05b0860c`.
The no-adoption decision is proportionate: retain released routing and arrangement, keep repair example-only, and use final-port/lead compatibility as a necessary constraint in future initial coordinate assignment. No issue closure, production integration, Linux verification or remote publication is established here.
@@ -0,0 +1,11 @@
# Bounded flat clearance repair candidate
Own module: `crates/oa-core/examples/auto_layout_probe/clearance.rs` in research worktree. Pure `repair(&Project, Id) -> Result<Project, ModelError>`; no compilation/execution by implementation agent. Parent owns CLI, test execution, final original-to-final route metadata reconstruction, and integration. Input routes, authored sizes/anchors and semantic records are untouched by this function.
Freeze total X/Y orders by initial coordinate then placement ID. Reject initial actual-node overlaps. For every disjoint pair, retain its original gap on one existing separating axis (deterministic X before Y); preserve adjacent start order on both axes. For a diagnosed singleton blocked lead, strengthen the corresponding outward-facing owner/blocker boundary separation to PORT_STUB + CLEARANCE + explicit1-unit margin, currently31. Reject ambiguous endpoint sets, noncardinal blocked leads and constraints opposing frozen order. Solve acyclic longest-path lower bounds from frozen initial coordinates, so movement is positive and constraints only strengthen.
Reproject after each adjustment and before success: identity/topology and every effective node size must remain unchanged. Diagnostic uses actual reselected automatic ports, not frozen engine ports. Four adjustments maximum; unresolved or non-strengthenable failures reject. Bound256nodes/1024edges,100000-unit span per axis, and10000000 charged work units (including conservative16 endpoint-pair/node allowance per diagnostic round). Nested/folded/omitted/Scenario input is rejected. Errors drop a private clone and cannot mutate the input.
This is deliberately conservative: fixed-axis pair gaps may propagate movement farther than necessary; opposite side changes may make constraints impossible under the frozen order. Size-changing automatic capacity redistribution is rejected rather than silently accommodated. Work accounting bounds explicit pair/constraint/diagnostic scan allowance, not wall-clock time or all projection internals. Empty lead incompatibilities prove only the router's necessary lead guard, not obstacle-free complete paths, label clearance, readability or adoption. No heuristic nudges, engine tuning or production changes are included.
API inspected: routing::lead_incompatibilities(Project, Diagram, ProjectedView) returns actual singleton candidates and inflated blocker identities. Stub containment is diagnostic-only and is not substituted for the existing lead guard. Parent should retain all rejected cases and evaluate full route/label results independently after successful repair.
@@ -0,0 +1,43 @@
# Placement clearance experiment
Continuation of issue32 from connection-layout-reference results at2850b915.
The sparse external placement leaves20 units between rectangles where its
final Rust top port needs18 units of outward lead plus12 units of unrelated
obstacle clearance. This experiment addresses that necessary placement
condition. It does not adopt either previous placement candidate.
Use the router's actual endpoint selection, promotion/attachment policy and
lead collision predicate in a narrow read-only diagnostic. Preserve existing
router guard order, search, costs and fallback. Compare the five-case frozen
route output exactly with the released-router control, and exercise targeted
lead, alternative-endpoint and folded/ancestor tests.
First consumer is an isolated example-only flat repair: at most256 nodes,
1024 edges and four separation rounds. Freeze axis order and initial coordinate
floors; seed separation inequalities from every initially disjoint node pair.
Add a31-unit boundary gap (18+12+1 margin) for unambiguous cardinal singleton
lead blockers and recompute monotone coordinates. Reproject actual automatic
ports each round. Reject overlapping input, unsupported nested/folded/omitted
topology, conflicting order, projection size changes, excessive extent/work,
or unresolved constraints. No mutation escapes on failure. This narrower
first experiment deliberately leaves subtree/compound coordinate assignment
for a later planner increment.
Evaluate all five frozen original and Arrange-reset scenes, all four supported
old native candidates, and all three prior ELK geometry transfers, unchanged.
Keep unsupported cases and failures explicit. Reconstruct route reset/retained
translation once from input to final geometry using the audited import helper.
Check semantic/anchor/other-view conservation, round trips, repeat determinism
and ten repeated repair calls. Report all existing quality measures, actual
port changes, warnings and unrelated-node penetrations. Require the exact sparse
terminal conflict to disappear without introducing a new node overlap or routing
failure before calling this compatibility increment successful. Lead clearance
alone is not complete routability or readability acceptance.
Stop after one bounded candidate and independent review. If the sparse witness
cannot be repaired under frozen orders, retain the counterexample and move
constraints into initial coordinate assignment; do not increase iteration
counts or tune the corpus. Even success leaves prior shared-run, area,
compound/undirected and native usability limitations unresolved.
Windows only. No Linux build, release change or production Arrange adoption.
@@ -0,0 +1,57 @@
# Independent clearance experiment result review
Primary evidence is explicit-UTF8 `placement-clearance-20260925/run02`, source074051261a0beee1047e2b5624c879deef7813bc. Read-only analysis of recorded Projects/geometry/receipts; no compiler, router, engine or GUI run. **The bounded repair resolves the exact sparse terminal incompatibility, but the result is not a general connection-aware Arrange solution or a quality winner.** It remains flat-only and worsens several tracing metrics.
## Admission and corpus integrity
Independently verified every run02 bound input's current SHA against inputs_after, exact inputs_before/after equality, all18 process receipts (17 candidate cases plus routing control) exit0/not timed out, and stdout/stderr hashes. Routing-control bytes equal the frozen released-router geometry file for all five original cases. These observations support the narrow no-output-change routing refactor claim for that corpus, not all possible graphs.
All12 generated seed Projects exactly equal the corresponding prior UTF8-decoded Projects, recursively without float tolerance. Original corpus files remain hash bound. Run01 is preserved and superseded: nine generated mixed/sparse seeds were exact, but three workshop seeds each changed27 string leaves (81 total). Every change is exactly the result of decoding original UTF8 bytes as cp1252; numeric geometry and structure were unchanged. Full paths and values are in `placement-clearance-run01-seed-audit-20260925.json`. Corrected run02 removes those seed changes. This is runner encoding failure, not model mutation by the Rust candidate.
## All17 cases accounted for
- Unsupported5: workshop original's original/reset/layered placements, and folded workshop original/reset. Each explicitly reports nested/folded/omitted placements unsupported. No successful hierarchy result is inferred.
- Supported12: four original/reset/layered/ELK placements for each of mixed dispatch, its relation-ID permutation, and sparse40.
- Eleven supported cases have no node movement. Sparse40 ELK alone moves8 stored node positions by exactly(0,+11), changes23 projected port positions and zero port sides.
For every supported case, independently reconstructed the entire expected raw Project from before: substitute only returned node positions and clear waypoints/full label only for visible flat edge route entries. Complete object equality with after proves preserved stored sizes, all node metadata/anchors, semantic records, other diagrams, route entry/order/attachments and unrelated fields. Verified exact stored/projected node identity scope, flat/unfolded topology, complete `(owner,element)` port key sets without duplicates, and exact projected-edge identities/semantics. This does not rely on the emitted conservation booleans. All12 recorded same-input repeats and9 subsequent repair calls report exact equality; both recorded JSON and source roundtrips are exact. These are assertions from the frozen executable output, not independently rerun commands.
## Independent geometry agreement
Applied the preexisting independent segment interval/contact evaluator to all24 before/after supported scenes. All96 comparisons agree within0.001 for proper crossings, unique pairwise contacts, common physical terminal contacts and raw pairwise shared length. Independently intersected every unrelated routed stroke with flat node interiors and every node pair in all24 scenes; penetration and overlap counts agree. Full results and source receipt binding are retained in `placement-clearance-run02-independent-audit-20260925.json`.
Sparse ELK changes:
| Metric | Before | After |
| --- | ---: | ---: |
| NoClearPath warnings |1|0|
| Unrelated node penetrations |1|0|
| Unrelated node overlaps |0|0|
| Proper crossings |20|22|
| Point contacts |55|58|
| Pairwise shared length |666|761|
| Label/stroke intersections |0|1|
| Total route length |64223|64322|
| Drawing area |12840450|12936535|
The shared/crossing/contact/penetration numbers above have independent arithmetic corroboration. Label/stroke, length and area are emitted metric observations; the new label/stroke witness is explicitly identified below. No count establishes glyph readability or navigation usability.
## Exact repaired witness
Assessment Package remains x4522..4746,y660..820. Planning Aggregate moves from top840 to851 with unchanged stored/projected size224×160. Its top port is now(4634,851), outward18-unit stub(4634,833). The blocker inflation ends at832: the planned one-unit margin is realized exactly. Independently checked all110 semantic-port terminal leads in the final sparse scene against all40 inflated rectangles: zero unrelated lead intersections and zero stub-containing obstacles.
Flow_45 `...03347d` now follows (4120,477)→(4120,495)→(4377,495)→(4377,833)→(4634,833)→(4634,851). The recorded prior160-unit unrelated-node penetration is absent under independent interval tests. This validates the local spacing hypothesis without changing port sides, authored anchors, or adopting raw ELK bends.
A new recorded label/stroke intersection remains: flow_45 crosses the label of edge `...03347a`, emitted interior intersection length23.9998. Thus the former hard terminal failure has been traded for additional route contacts/crossings/sharing and a new label interference. The test is a useful capability witness, not adoption evidence.
## Decision and limitations
Accept the evidence that final-projection lead compatibility is a useful placement constraint and that this bounded flat repair can solve the named mismatch. Do not adopt the repair as the user-facing Arrange planner: five hierarchy cases are unsupported, supported no-op cases retain their prior quality limitations, and sparse quality is non-dominating. Do not retune this frozen experiment to erase the tradeoff. The next implementation decision belongs in connection-aware placement/coordinate assignment with shared lead constraints and actual reprojection; production selection/history integration and native trace tasks remain untested here.
The diagnostic is necessary-only, and the independent final sparse clearance check does not imply every graph admits a route. No performance, glyph measurement, native usability, production acceptance or remote publication claim is made.
- placement-clearance-run02-independent-audit-20260925.json SHA256 ec5094c81dc4f200ec53d01fb0dca9efd0ce71338922043f5a18a3d409a46c10.
- placement-clearance-run01-seed-audit-20260925.json SHA256 f3785e637284923e87e55243436c2b45a1f101fb059d69d8a71b5f0def8380ea.
- receipt.json SHA256 ea2eeea0e09d9588a5c1a025c058455fa984f46d17a154f08ec4d328732cc1ee.
@@ -0,0 +1,124 @@
# Mandatory-lead placement repair result
**The diagnosed sparse terminal conflict is repairable with a bounded native
separation pass, but the result is not an accepted Arrange replacement.** It
removes the routing warning and unrelated-node penetration while making
crossings, shared connector length and one label/stroke intersection worse.
Keep the released router and production node arrangement. The next useful
planner work is connection ordering and corridor/label space during initial
coordinate assignment, including compound geometry; do not add more local
repair rounds or retune router penalties on this corpus.
Source `074051261a0beee1047e2b5624c879deef7813bc`, based on the placement reference
at2850b915. Core changes extract the existing endpoint choice and early lead
guard into shared helpers and expose a read-only necessary-condition report.
Router search/cost/fallback behavior is unchanged. Repair is an example-only
consumer, unsupported for nested/folded/omitted placements and Scenario.
It is not connected to Command::Layout, REST or desktop history.
## Observed result
Primary run02 preserves the five original scenes, five Arrange-reset controls,
four old native candidates and three external-placement transfers. Twelve flat
cases are supported; the five workshop variants explicitly reject unsupported
topology. These are not counted as repair passes. Only the sparse external
placement changes node geometry: eight nodes move down11 units. Twenty-three
of110 projected port positions move, with zero side changes. Final port
identity and owner sets are exact.
The target Planning Aggregate top moves840→851 while Assessment Package's
bottom remains820. The top port's18-unit outward stub ends at833, just beyond
the inflated blocker bottom832. The sole incompatible edge becomes admissible
and obtains a complete route with no warning or unrelated-node penetration.
| Sparse external placement measure | Before | After repair |
| --- | ---: | ---: |
| Incompatible mandatory-lead edges | 1 | 0 |
| NoClearPath warnings | 1 | 0 |
| Unrelated-node penetrations | 1 | 0 |
| Node overlaps | 0 | 0 |
| Proper crossings | 20 | 22 |
| All point contacts | 55 | 58 |
| Pairwise collinear shared length | 666 | 761 |
| Label/node and label/label collisions | 0 / 0 | 0 / 0 |
| Label/stroke intersections | 0 | 1 |
| Route length | 64223 | 64322 |
| Drawing area | 12840450 | 12936535 |
The two original mixed scenes also change route length and drawing bounds because
eligible authored pins/label overrides are reset; no nodes or ports move.
Do not attribute that effect to the new separation pass. All other supported
cases retain geometry and measured results. The old native sparse candidate's
40522 shared-length problem remains. Empty lead diagnostics do not establish
legibility or complete route feasibility.
All12 supported outputs conserve the complete Project except declared node
positions and eligible route reset, retain stored node sizes and port anchors,
preserve complete projected edge/port identity, and pass JSON/single-source
round trips. Duplicate input gives the same result; all nine subsequent calls
through call10 remain exactly equal. Automatic side-flip repair, compound
translation, opposite-order rejection and native usability are not established
by these successful corpus cases.
## Verification and failures retained
Windows Rust1.98.1 gnullvm, LLVM-mingw20260908, offline locked dependencies,
one build job and previously frozen environment. No Linux build or native UI
acceptance run for this experimental repair.
The subsequent evidence commit changes only a prototype budget comment and
documentation/evidence; executable Rust statements remain those tested at07405126.
```
cargo test --locked --offline -p oa-core --test lead_feasibility --test routing_geometry --test edge_attachments --test port_anchors
cargo test --locked --offline -p oa-core --lib --example auto_layout_probe
cargo build --release --locked --offline -p oa-core --example auto_layout_probe
cargo clippy --locked --offline -p oa-core --lib --example auto_layout_probe --test lead_feasibility -- -D warnings
```
Gates14–17 pass at07405126:40 selected integration tests,130 library tests,
2 example solver tests, optimized build and strict Clippy. No broader-suite
claim. Five-case route-control JSONL is byte-for-byte identical to the frozen
released-router output (SHA2569a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2).
Both runners complete18 children (route control plus17 scenes), exit0 with
unchanged bound inputs; unsupported status is inside the result, not inferred
from exit status. Each child has a90-second cap. No latency claim is made.
Gate13 at2be8c7f2 compiled but two new non-port fixtures failed semantic
validation because their default DataTypes were primitives. Source07405126
changes only those fixtures to valid Record types; the failed receipt remains.
The first analysis failed on implicit Windows cp1252 decoding of UTF-8 JSONL.
Independent audit found81 altered string leaves in three workshop seeds
(27 each), no numeric/geometry differences; nine other generated seeds were
exact. Preserve run01 as superseded evidence. The v2 runner/analyzer use
explicit UTF-8 and produce primary run02. They also independently compare the
complete raw Project modulo allowed changes and full(owner,port) identity sets.
The prototype's work counter is a weighted size/iteration budget, not an exact
count of all routing/projection operations or a wall-clock guarantee. Explicit
graph, round and span limits remain separate guards.
## Reproduction and evidence
Build the source pin above, then use the archived v2 experiment runner with the frozen
corpus and prior reference archive. The portable probe interface is:
```
auto_layout_probe --route-corpus MANIFEST
auto_layout_probe --repair-placement PROJECT_JSON DIAGRAM_UUID
```
The latter emits before/after geometry, full models, diagnostics, quality
measures, metadata checks and ten-call stability. Original inputs, run receipts,
commands, scripts, failure logs and independent audits are retained in
`evidence/placement-clearance-07405126.zip`; `evidence/manifest.json` identifies
every member and SHA256. Native binaries are represented by capture hashes,
not embedded. See [source review](source-review.md), [result review](result-review.md),
[final claim/archive review](final-review.md), [design alternatives](design.md)
and [bounded consumer](implementation.md). The final review is versioned outside
the immutable evidence archive; its minor runner wording correction is applied.
This branch evidence is local-only until a successful Gitea push and byte
readback; earlier publication attempts failed with remote disk-full errors.
No issue closure, release change, merge or whole-Arrange quality claim.
@@ -0,0 +1,51 @@
# Independent placement-clearance source review
2026-09-25. Reviewed the initial working diff and then its settled, clean commit `2be8c7f2929684a99bfb92b63e1585980d6313cf` against `2850b915`, including the plan, routing extraction, diagnostic, flat repair, tests and example CLI. No edits, compilation, test execution, routing calls or GUI actions by this reviewer.
**Verdict: no P1/P2 source blocker found for the declared bounded experiment.** The extracted predicates appear behavior-preserving, and the flat repair's separation constraints preserve an initially disjoint axis for every node pair. Approval here is for verification of this candidate, not production adoption or a claim that lead clearance establishes routability. Parent's exact frozen-route comparison and17-case experiment remain necessary.
## Findings and verification limits
**P3 — semantic/coincident self-loop coverage is narrower than the requested diagnostic coverage.** `crates/oa-core/src/routing/leads.rs:142` verifies the coincident exception and owner-obstacle distinction using direct helper calls. It does not run `lead_incompatibilities` on an actual projected semantic self-loop or coincident authored attachment pair. The source reuses the real endpoint selector and reproduces the route-edge coincident condition, so this is a coverage gap, not an identified false result. If the parent claims these cases tested, add or reuse an actual Project/projection-level witness; otherwise preserve the limitation. Existing self-loop routing tests can establish routing regression coverage but not every new report field.
**P3 — solver unit tests do not establish full repair/persistence behavior.** `crates/oa-core/examples/auto_layout_probe/clearance.rs:260` and `:274` exercise one propagated inequality and an extent refusal. The17-case observer must verify final no-overlap identities, the exact sparse lead/warning/penetration changes, complete metadata/reset policy, and ten-call stability. Its emitted `supported:true` only means the repair/import returned successfully; no quality-pass follows. A duplicate-call failure currently appears as `same_input_exact:false` without its error text, sufficient to fail repeatability but less diagnostic than the ten-call error record.
No source change is requested solely to broaden this first experiment. Failed cases and the above limits must remain explicit in the report.
## Router extraction
At `routing.rs:425`, `effective_route` retains actual-owner versus projected-owner promotion, suspension of the whole authored route when promoted, and semantic-port precedence over dormant explicit attachments. At `:447`, `edge_endpoints` calls the previous `endpoints` expressions in source/target order with the same semantic/projected-port fallback. These helpers are pure reads; source/target endpoint vectors have the same ordering.
At `routing.rs:475` and `:483`, the allowed-pair and mandatory-lead expressions are the original expressions with the same Boolean logic. The route path still filters self-loop anchors before candidate scoring/sorting, and still checks the lead guard after best-cost pruning at `:868`. Pins, obstacle construction, preview reuse, search budget, costs and fallback are not changed by this extraction. Moving the two endpoint calls into a local array before `route_edge` does not introduce a mutation or reorder obstacle/pin processing. This is source-equivalence reasoning; only the pending recorded-route equality check establishes observed unchanged output.
## Diagnostic fidelity
`routing/leads.rs:67` constructs the same node/rectangle/header maps and edge-ID order as the router. It uses effective promotion/attachment policy, actual endpoint alternatives and `edge_obstacles`, including ancestor-header versus traversable-body treatment. Missing projected owners are skipped as in routing; empty diagnostics cannot certify that all semantic connections are present.
The diagnostic counts every permitted source/target pair and reports an incompatibility only when none passes the exact early lead guard (`:100–118`). It therefore does not promote one blocked automatic side to a hard incompatibility when another side remains usable. Coincident singleton tips use the same exception as route-edge selection. Pins, later stub-search containment, path reachability, global search budget and labels are deliberately outside this necessary-condition diagnostic.
`describe` at `leads.rs:43` excludes an endpoint's own rectangle from lead blockers, matching the early guard. `stub_containers` deliberately includes all containing obstacles and is separately documented; consuming it as additional mandatory blockers would change the historical semantics. The repair correctly uses only `blockers`.
The integration tests meaningfully distinguish20-unit blocked clearance from30/31-unit clear geometry, assert independent tip/stub/inflated-obstacle coordinates, check read-only Project equality, semantic-port precedence over stored attachments, and an unconstrained alternative versus explicitly anchored non-port endpoint. The ancestor/promotion test at `lead_feasibility.rs:182` is transparently a synthetic projected forest; it proves that supplied-view policy, not a complete authored folded-project lifecycle.
## Monotone flat repair
`clearance.rs:130` seeds one boundary inequality for every initially disjoint pair: X separation when available, otherwise Y. Initially overlapping rectangles are explicitly refused. Because positive extents make each chosen direction forward in that axis's frozen start-coordinate order, these original constraints are acyclic. Newly required lead gaps are accepted only in that same rank direction (`:214`).
`solve` at `:27` visits targets in frozen order, so every constraint predecessor has already been resolved. It applies coordinate floors, nondecreasing adjacent starts, and `start[to] >= start[from] + extent[from] + gap`. Constraints only strengthen and dimensions are rechecked each round. Therefore, in the represented arithmetic, each pair retains at least its originally selected separating axis; strengthening a lead gap cannot remove that preserved pairwise separation. The recorded final overlap check remains appropriate for f32 effects and integration mistakes.
The31-unit required gap is `PORT_STUB + CLEARANCE +1` at `:217`; it is deliberately conservative for a flat rectangular blocker in front of a cardinal singleton endpoint. Unexpected direction, degenerate lead, multiple endpoint choices, unknown owner/blocker or a constraint opposing frozen order returns an error. Reprojection after every adjustment observes automatic-port changes; it does not assume the initial tips remain attached to the same side. Up to four adjustments are allowed, followed by a final diagnosis; a still-blocked or unstrengthenable result fails explicitly.
Flat, complete, noncollapsed topology, finite positive geometry,256 nodes,1024 edges,100000-unit span and a cumulative work allowance are checked. There is no unbounded iterative optimizer. The work allowance is a coarse charge for bounded graph operations, not an exact CPU-operation counter or wall-clock guarantee; parent process supervision remains useful. Every failure drops the private clone.
## Metadata and interpretation boundary
`clearance::repair` changes only positions in its clone. It does not incrementally rewrite stored routes or anchors while adjusting. Parent wrapper `auto_layout_probe.rs:1027` invokes the audited import policy once from the original input to final projected geometry. That preserves authored sizes when projection minima are unchanged, actual attachments and other-view records; applies retained-route translation from the full final deltas; and clears only original eligible pins/full labels.
Even if no node movement was needed, the wrapper can still clear eligible pins/labels. Thus output differences on an original authored scene may include the declared reset, not solely clearance movement. Compare complete records and the appropriate reset control before attributing quality gains to gap repair. For scenes already reset this distinction disappears.
CLI results expose baseline/final geometry, lead reports, conservation, roundtrip, same-input equality and repeated repair outcomes, with explicit errors for unsupported cases. The accepted success criterion remains the plan's narrow one: remove the exact sparse terminal conflict without a new node overlap or routing failure. Empty lead reports alone cannot establish this, and even that compatibility result leaves shared runs, labels, area, compounds and native traceability unresolved.
## Fixture correction addendum
Reviewed parent follow-up `074051261a0beee1047e2b5624c879deef7813bc`: only five fixture lines change, converting the three DataType definitions to `Record { supertype: None }` before constructing the DataAssociation. The previous fixture relied on the default primitive definition, contrary to `crates/oa-core/src/data.rs:1089` requiring Record endpoints. The original gate13 failure remains evidence of a fixture precondition defect, not a passing non-port test. This correction supplies valid intended association endpoints without changing geometry, assertions, production routing, diagnostic or repair logic. Test functions now start at107/144/167/187; earlier test line references refer to2be8c7f2. No rerun result is claimed here; gate14 is parent-owned. Static verdict is unchanged, now covering this exact correction.
@@ -0,0 +1 @@
* -text
@@ -0,0 +1,64 @@
# Independent routing corpus: pre-result adoption rubric
Prepared before the new corpus routing/timing outputs. This is a proposed engineering decision rule, not a replacement for user requirements or a production acceptance claim. Compare released715 router, J and L on identical frozen cases; route-only observation must not invoke the unsupported layered layout prototype.
## Existing requirements and precedent
`PROJECT_GOAL.md` provides no numeric routing-latency requirement in the scoped search. `harness/release-routing-verification.md:172–184` supplies an existing initial100ms settled-solve target, explicitly not a universal guarantee:100 nodes/150edges/eight pins per edge measured release119ms full solve and2.4ms maximum single-edge preview (debug863ms/16.4ms). The119ms miss remains a recorded limitation. `harness/allocation-arrange-planner-20260923.md` explicitly disclaims large-scene latency. No frame-rate or universal routing SLA is inferred from these records.
`docs/language.rst:1235–1256` requires semantic-port precedence, suspension of authored route data for promoted folded endpoints, restoration on expansion, exact stored route metadata and explicit route-edit lifecycle. These are hard constraints. Automatic unpinned non-port attachment sides may legitimately change with routing cost; classify their coordinate changes as geometry results, not invariant violations.
## Frozen cases and trace tasks
Before any result, freeze manifest, all complete Projects/diagram identities, input hashes, generation source and variant binaries. Include original and folded workshop SA Allocation; a named mixed8–12-node scene with shared/distinct physical semantic ports, authored anchors/pins, a cycle and an untouched other view; its fixed relation-ID permutation with explicit old/new semantic correspondence; and a sparse40-node/~55-edge scene. Preserve all frozen cases in every report, including failures and censored calls.
The corpus author should record these concrete trace tasks by actual source/target/edge names and IDs before outputs: (1) workshop cross-container exchange in original and folded projection, identifying promoted visible ends; (2) mixed shared-output fan-out, identify each of at least two named targets without switching routes; (3) two distinct ports on the same card, trace each to its correct receiver; (4) cycle return edge, trace its direction back to the intended source; (5) authored pinned edge, identify the exact endpoint and passage through each pin; (6) sparse first-to-last long-span exchange plus one neighboring distractor. Repeat mixed tasks under the frozen ID permutation, using its semantic mapping. Do not select whichever routes look best after observation.
For later native inspection, all target identifications must be correct without consulting the source model, route recoloring, temporary geometry edits or hiding the distractors. Normal selection/zoom/pan are allowed and recorded. Report actions, wrong turns, uncertainty and time; no invented universal human completion-time threshold. Inspect at the same declared readable zoom and one Fit view, acknowledging Fit may be unreadable for40 nodes. No pure geometry metric substitutes for this task gate.
## Hard gates and geometry evidence
- No mutation of Projects or stored routes; semantic endpoint/edge identity, authored port anchors/attachments/pins, folds, filters and other-view records exact. Physical semantic-port tips remain exact. Dormant attachments remain stored. Promoted authored routes correctly suspended rather than incorrectly enforced; compare visibility/projection eligibility explicitly.
- No new missing route, nonfinite coordinate, invalid model, unrelated-node/header penetration or routing warning. Existing warning types must remain visible per edge; they cannot be averaged away. Authored unavoidable collision cases require exact predeclared exceptions, not blanket incident-edge exemption.
- Report every raw overlap interval and unique proper/T/bend/endpoint contact with edge IDs and locations. Classify common physical terminals but retain raw counts. Labels/headers/port labels must not obscure required routes in native review. Automatic attachment changes and label shifts are explicit results.
- No weighted aggregate quality pass. A new isolated crossing replacing coincidence is a reviewable tradeoff, not automatically failure or success. Adoption requires a predeclared trace task improvement or restored correctness and no newly ambiguous task elsewhere. ID sensitivity must be disclosed; a favorable naming/order cannot be chosen post hoc.
## Timing decision rule (proposed, not user-owned requirement)
Use optimized Windows variants with identical toolchain/profile and interleaved declared order. Parse/project outside the measured call; route_diagram alone is timed. One warmup plus seven measured samples per case; record each duration, median and maximum, not a claimed p95 from seven values. Verify identical output across repetitions outside the timed region. Exclude parsing/serialization/hash/drop work explicitly from the timer, while admitting that allocator/cache/OS state still affects observations.
For this modest frozen corpus, adopt the existing100ms target as the proposed per-case median ceiling and200ms maximum-sample ceiling. Also require candidate median <=1.25*released-baseline median +1ms per case; compare L against J as the simpler candidate too. These are deliberately declared engineering guardrails, subject to explicit future revision rather than post-result relaxation. If baseline itself fails the absolute ceiling, report a capacity limitation and do not treat relative improvement alone as a responsiveness pass. A meaningful correctness fix exceeding a guardrail needs a documented tradeoff and native response evidence; it is not an automatic pass.
Any completed warmup/measured call above5s censors the case and stops its remaining repetitions. Retain its actual elapsed time and failure status. This after-call cutoff cannot stop a hung individual call; parent supervision must provide a finite process timeout. Missing/censored samples never count as fast results. Seven interleaved samples are screening evidence, not a scaling or tail-latency theorem.
## Decision and stopping rule
Complete this fixed comparison once, investigate concrete correctness or measurement defects, and stop parameter tuning. Prefer the simpler J if L has no independently observable task benefit or exceeds the timing guardrails. Keep L experimental or discard it rather than add permanent settings to preserve sunk work. If none meets the rubric, report the failing constraint and choose the smallest conceptually different next experiment; do not quietly extend the corpus until a winner emerges. Production Command::Layout/reset integration, Undo/Redo/Save, desktop input behavior and native acceptance remain subsequent gates.
Driver/corpus source review is pending their readiness; this rubric makes no claim that they already implement these checks.
## Ready driver source review
Reviewed `crates/oa-core/examples/routing_cost_probe.rs` SHA256 `90ad27099a9486e9a7d45460bc9b66930e35d8336e3007fc30f90b48d88407d4` before compilation. No blocking source defect found for this protocol. The timer encloses routing plus result black_box; projection, parsing, cloned input, result equality/digest/serialization/destruction are outside. Seven full RoutedViews compare to warmup, with endpoint comparisons additionally emitted. Both warmup and samples can censor; median is absent for incomplete cases and stability_observed is false when warmup prevented all measured calls. Schema requires description in each case in addition to name/project_file/diagram. Paths are canonicalized under the manifest directory and duplicate case names reject.
The driver's censored case can still finish with process exit0 by design. External acceptance must require every expected case, complete=true, censored=false, seven measured samples, all equality flags true and project_unchanged=true; do not equate exit0 with responsiveness. A finite external process timeout is still required. The digest is correctly labeled noncryptographic; external corpus/source/binary hashes remain necessary. No execution occurred during this review. Corpus source review remains pending readiness.
## Final corpus and probe source review before execution
Read final prepared sources, with no builds/generation/routing calls by reviewer:
- `routing_eval_corpus.rs`: SHA256 `55ad185b3a72f5c1aa082732058604600cb016556c41aa5a3a21122766171bf6`.
- `routing_cost_probe.rs`: SHA256 `6f67abae2f912ed27215f8823b6dbcd41ca880b198dc60d5a10e88c71b38b8c0`.
- `auto_layout_probe.rs`: SHA256 `48e540f2176252d8ea1e110dd17fce37bd19f75f61fa6902356925bfe01540bc`.
No blocking source finding for the frozen five-case comparison. This completes the pending source review stated above; compilation/generation remain parent-owned verification.
Corpus constructs the saved12-placement SA Allocation workshop and its single collapse-flag change,10-function/14-exchange mixed case, reversed-edge-ID paired case, and40-function/55-exchange sparse case. No Layout/projection/router call constructs input geometry. Generated port IDs are v5-derived from fixed exchange IDs in ports::plan_functional_exchange; generated element/placement IDs are reidentified. The permutation uses temporary IDs and asserts inverse recovery of the entire Project, including authored-route references. Six fixed semantic-port anchors, an authored feedback pin/label, shared source/target ports and a separate-view sentinel provide meaningful independent constraints. The generator validates all cases before writing a fresh directory and refuses overwrite. Trace IDs, aliases, names and semantic endpoints are frozen in manifest metadata.
Coverage limits, not hidden successes: workshop contains no authored routes, so its folded case does not exercise suspension/restoration of a nonempty authored pin list. Mixed has semantic-port anchors and a pin/label but no explicit non-port EdgeAttachment. Sparse subsystem groups are flat named chains, not hierarchical containers. The frozen trace list selects representative branches; native review must inspect companion branches too to establish fan-out discrimination, using the manifest/model identities rather than selecting routes after seeing outputs. These are finite first-corpus limits, not blockers requiring the experiment to become comprehensive acceptance.
The geometry mode validates nonempty unique cases, Project validity and diagram existence; then calls metrics/roundtrip directly, without Layout/reset/candidate transformation. Analytic metric selfchecks still run before mode dispatch. Emitting full projected_edges, actual endpoint owners, effective pins, pin fractions and custom_suspended supports the required later semantic/geometry distinction. The output is observation, not an automatic oracle: later audit must compare authored/effective pins and port positions, account for folded promotion, and interpret legal automatic attachment changes. Full before_project and manifest remain present for this audit.
The updated cost schema intentionally removes deny_unknown_fields, retaining additional corpus/case metadata in flattened maps and emitting those maps. This now accepts generator trace_tasks/source_counts/metadata without losing them. Required typed fields remain required. Clock and censor logic agree with the earlier review. Neither probe must claim that a zero exit status alone establishes all semantic constraints or timing acceptance. External exact corpus/binary hashes and timeout remain necessary.
The geometry loader's relative-component check is less strict than the timing loader's canonical containment check (a symlink could resolve outside); for these parent-generated frozen ordinary files this is not a blocker. Both must read the same hashed files. No request is made for unrelated loader architecture or extra fixture families before the finite run.
@@ -0,0 +1,37 @@
# Independent routing analysis/supervisor source review
Static review before result analysis; no compiler, router, GUI or evaluator execution. Reviewed analyzer SHA256 `115258fe13f76ad77daacf0937955b14c497a4618e86a84c42c7e4ce845c1f24` and supervisor SHA256 `903c1c21971e7c5d73875db7df578c442496a17f98e4dde7a437d5f116f54604`. Line references below refer to those bytes.
## Actionable findings
1. Analyzer lines237–238 can falsely pass the rubric's no-new-penetration gate: total counts alone allow a new edge/node penetration to replace an old one. Compare identities from edge_node_details and node_collision_details using edge/node or unordered node pairs; retain segment/location/length changes for review. Keep the total vector, but do not label a lower/equal count as proof of no new affected object. This is material to automated acceptance; fix before relying on the report, without rerunning routers.
2. Lines116–118 check that each pin lies somewhere on the route and that fractions are sorted/in-range, but never bind a fraction to its corresponding pin. Wrong fractions or traversal assignment can pass. Interpolate the recorded polyline at each cumulative-length fraction and require the corresponding pin within tolerance. Current corpus has only one main authored pin, so multiple-pin order coverage is explicitly limited; it still supplies a nonvacuous fraction-position check.
Small useful consistency check at lines119–123: verify emitted source/target tips equal routed_edges.points first/last before using them as the physical-port oracle. The current producer directly emits those endpoints, so this is defensive evidence consistency rather than a demonstrated router defect. Do not require automatic non-port endpoint equality across variants.
## Sound scope and limitations
The analyzer requires exact case sets, optimized timing metadata, seven valid uncensored samples, stable full-route repetitions, unchanged Projects, independently recomputed medians/maxima, absolute100/200ms guardrails and declared relative guardrails. It binds raw receipt stream hashes, binary size/hash to the build receipt and current corpus hashes. Failures stay in the output and cause nonzero analysis status; no native/production acceptance is claimed. Nonfinite JSON is rejected. Per-edge warning-set comparison is appropriately stronger than total warning count. The model permutation inversion is meaningful for this explicitly named fixture; route-order sensitivity remains an observation rather than an equality requirement.
Effective pins and promoted-owner suspension are checked against full frozen Projects and projected definitions. Explicit non-port attachments and folded nonempty authored pins are absent from the corpus, as already recorded; do not claim those contracts fully exercised. Semantic-port checking skips absent projected ports, which is appropriate only with projection/folding evidence retained; do not generalize it as proof of hidden semantic-port placement. Projected nodes/ports/edges compare exactly, whereas legal automatic attachment sides remain observations.
Supervisor runs the declared released/J/L/L/J/released timing sequence, then separate geometry runs. It refuses existing attempt directories, checks binary/corpus before launch and after completion, captures stdout/stderr raw hashes, and has90s process timeout/kill. This is a finite whole-process timeout, not a guaranteed5s interruption of an individual route call. It preserves timed-out/nonzero receipts rather than silently omitting them; analyzer rejects them. Censored exit0 is also rejected by complete/sample checks. Build/source identity ultimately depends on parent's build-admission record, correctly noted by analyzer. No major timing-scope defect found.
## Corpus alias correction and actual byte evidence
Inspected source fix `f0eae74912061455453acd7ec17e2ddbe498ee2c`: after stable secondary placement reidentification, set alias to feedback_review_{i}. This addresses the observed random alias suffix without changing topology or geometry. The earlier source review established deterministic ID construction, not byte-identical generation; the original two generation folders remain preserved as counterevidence to the stronger claim.
Read-only comparison now confirms all six files in `.local/routing-independent-corpus-v2-20260925`, its `-v2-repeat-` counterpart and the frozen checked-in corpus at `f674e36c8b75dfa95246eabb672e36c937aec31b` are byte-identical. This is observed repeat-generation equality after correction, not an untested source inference. Manifest SHA256 `a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717`.
No request for broader framework changes or additional fixtures before this finite run. Apply the two concrete analysis fixes, retain the corpus limits, then assess actual results separately.
## Findings closed by source re-review
Reviewed corrected analyzer SHA256 `91383f12dc1c895f1b1dcffe6d99acc3358f0a2795fd9aff35baab2625dbc79d`, still without executing it or reading routing outcomes. Both material findings are addressed:
- collision_changes now keys edge penetration by edge/node/header-only identity and node collisions by unordered node pair. Added identities fail explicitly; removed/changed details and before/after route/node geometry remain in the report. This closes the equal-count substitution false pass.
- point_at_fraction independently computes cumulative polyline length and interpolates each reported pin fraction, then checks corresponding authored pin distance within0.001 world units. Empty, nonfinite and degenerate polylines receive explicit handling. This closes the unbound fraction-position check. Multiple-pin traversal coverage remains limited by the one-pin corpus, not falsely asserted.
The small optional endpoint-record consistency suggestion is not promoted to a blocking defect: producer fields are directly derived from the same point list. No outstanding material source-review finding prevents analysis of this finite corpus.
Also reviewed commit `095ab3b35847654d40e7bab9815c2bceb77484d1`: it extracts the same constraints, endpoint and routed-edge JSON mapping expressions into local Vec values before the outer json! macro. Field names, sources and iteration order remain unchanged; no router/corpus behavior change found. The preceding optimized build recursion-depth failure remains a failed build, not successful validation. Parent's rebuild outcome is outside this source review.
@@ -0,0 +1,41 @@
# Independent routing corpus contact review
Reviewed the completed three-variant geometry outputs and independent axis-interval audit, without builds, router reruns, GUI input or visual/native acceptance. All five cases are present for each of `released`, `j` and `lanes`. The audit's three recorded input SHA256 values match the actual geometry files reread for this review.
Evidence: `.local/routing-independent-contacts-20260925.json`, SHA256 `40b62731db7dc332b13021fa1f13bed176455feb2fb13d15998c761a4623b492`; standalone script `.local/audit-routing-corpus-contacts-20260925.py`, SHA256 `a6d95610a45faa3b4417df3c82059967d9729975fcf39dd1e9359ff1a20e0036`. The recorded primitive witnesses passed. The script uses independent axis-aligned interval intersection, rather than the Rust determinant intersection implementation.
## Agreement and measured tradeoffs
All **60 comparisons agree exactly**: raw unique point contacts, strict proper crossings, common-physical-terminal point contacts, and raw pairwise positive shared length, across 15 case/variant combinations. No nonzero numeric difference was found. These agreements validate these finite observations, not all possible geometry or a quality threshold.
Each table entry is **shared length / proper crossings / raw point contacts**. Shared lengths are diagram units; point contacts include proper crossings and T/vertex/end contacts.
| Case | Released | J | Lanes |
| --- | ---: | ---: | ---: |
| Workshop original | 1042 / 6 / 22 | 1074 / 5 / 23 | 602 / 5 / 23 |
| Workshop folded | 1096 / 7 / 20 | 1096 / 7 / 20 | 1096 / 7 / 20 |
| Mixed dispatch | 132 / 0 / 5 | 132 / 0 / 5 | 132 / 0 / 5 |
| Mixed, reversed edge IDs | 132 / 0 / 4 | 233.5999755859375 / 0 / 5 | 233.5999755859375 / 0 / 5 |
| Sparse 40 nodes | 496 / 24 / 32 | 372 / 25 / 31 | 372 / 25 / 31 |
The original workshop's lanes result reduces overlap substantially, while its nonproper contacts rise from 16 to 18: released has 8 T + 8 vertex contacts; lanes has 13 T + 5 vertex contacts. J has 11 T + 7 vertex contacts and a small overlap increase. The folded case's listed metrics are unchanged; this does not assert point-for-point route equality.
Both candidates worsen overlap in the edge-ID-permuted mixed case, adding one T contact (released 1 T + 3 vertex contacts; candidates 2 T + 3). The nonpermuted mixed case stays at 2 T + 3 vertex contacts. Consequently these observations do not establish ID-order invariance. Sparse routing trades 124 fewer shared units and one fewer raw contact for one additional proper crossing. Neither candidate uniformly dominates released routing on this corpus. These facts should remain visible in an adoption decision rather than being collapsed into a favorable single score.
## Ports, folded endpoints, and authored pin interpretation
All three variants' emitted tips for the two mixed cases match their referenced semantic ports' emitted positions **and projected owner IDs**: 28 ends per case, no missing ports or mismatch. The sparse case similarly matches all 110 ends per variant. This is a consistency check between independently selected records in the geometry output; it does not certify fixed-anchor fraction computation against source or prove all semantic conservation.
The common-terminal point count is zero in all 15 observations, despite deliberately reused semantic ports. This is not evidence that routes never share tips: a positive collinear shared interval is not enumerated as infinitely many point contacts. The interval audit explicitly retains common-terminal classifications. For example, mixed dispatch contains four segment-pair overlap intervals on edge pairs with a common terminal, three of which contain the common terminal itself. The permuted candidates contain five such intervals, still three containing the terminal. No common-tip overlap is subtracted from the raw length.
The original workshop projects 12 nodes/12 edges; folded projects 9 nodes/11 edges in all variants. Resolving relation endpoints through actual port owners and stored placements identifies four folded endpoint promotions in each output: target of `sa_relay_to_rescue`, source of `sa_direct_advice`, target of `validated_distress_report`, and source of `sa_advice_to_relay`. Original workshop has no such owner promotion. These are legitimate folded presentation changes, not semantic reconnections. Both workshop source cases have zero authored route records, so they cannot establish preservation or passage of suspended authored pins.
In each mixed case and each variant, the one authored feedback waypoint `(300,-100)` lies on the emitted route at arc distance 1392, and ordered passage is observed. The original sentinel edge is `00000000-0000-0000-0000-00000001adbd`; the reversed-ID counterpart is `00000000-0000-0000-0000-00000001adb0`. This verifies six concrete waypoint passages, not general retention of every route field. The other-view sentinel is not rendered by these selected-view observations and is left to the separate metadata analyst. Emitted geometry lacks `custom_suspended`; the audit deliberately reports absence/passage without calling every absent pin a failure.
## Mathematical and evidence limits
Contacts deduplicate per edge pair and coordinate within EPS=0.0001; a physical location shared by three edges may count three pairwise contacts. Proper means interior to both tested segments; a visually crossing route at a bend or redundant vertex can instead appear under T/vertex classification. Labels describe primitive geometry, not perceived topology or usability. Positive collinear intervals are summed per segment pair with multiplicity, not union length; shared-run endpoints can also appear as point contacts when another segment pair supplies a point witness. Common-terminal classification requires equal projected owner plus coincident physical endpoint, and never exempts a raw count.
The script rejects nonorthogonal segments and uses axis tolerance, unlike Rust's determinant/quantization details. Tiny near-tolerance geometry may produce different results even though every metric agrees here. Stroke width, arrowheads, port labels, glyphs, perceptual traceability, runtime and native interaction are outside this audit. Automatic non-port attachment choices may legitimately differ between routers and are not treated as preservation failures.
The parent is separately diagnosing emitted f32 serialization/model-comparison differences. This review does not resolve that issue or infer changed accepted input Projects from decimal spellings. Expected corpus inputs remain the frozen inputs; complete stored metadata/source/Project preservation belongs to the separate audit. There is no visual or native acceptance claim.
@@ -0,0 +1,21 @@
# Frozen source-first routing corpus (#32)
Prepared from f72aa2ca without calling Layout, projection, routing, or reading new routing results. This defines inputs and invariants, not expected quality. Generator ownership: `crates/oa-core/examples/routing_eval_corpus.rs`; no production changes. Generation, validation, serialization, and disk I/O are outside routing timing.
## Cases fixed before generation
1. `workshop_sa_original`: decode the embedded existing `examples/routing-workshop.json` through the production persistence decoder. Select Allocation view `sa_system_boundary_and_functions`, UUID `cb21862d-79e1-5a9d-bdf0-ee344c2fb219`, with 12 authored placements. Preserve the complete loaded Project. The saved source currently has six views and no authored routes: preserving these empty route records is explicit, not claimed pin coverage.
2. `workshop_sa_folded`: clone case 1 and set only the placement of `rescue_coordination_system` to collapsed. Semantic records, other views, all placement positions/sizes, routes and labels stay exact. This exercises hidden descendants and promoted endpoints through an actual allocation view. No generated route result is used to select the fold.
3. `mixed_dispatch`: ten named Functions (Sensor A, Sensor B, Ingest, Validate, Archive, Correlate, Plan, Dispatch, Actuator, Operator) and 14 FunctionalExchanges. Edges in authored order: A→Ingest; B→Ingest; Ingest→Validate; Ingest→Archive; Validate→Correlate; Archive→Correlate; Correlate→Plan; Plan→Dispatch; Dispatch→Actuator; Dispatch→Operator; Operator→Actuator; Archive→Actuator; B→Archive; Plan→A. The final edge is explicit feedback; branching can create more than one graph-theoretic cycle. A/B→Ingest reuse one semantic input; Ingest fan-out and Dispatch fan-out each reuse one output. Other endpoints are explicitly distinct. Empty carried-item contracts are legal and avoid unrelated data typing. Six fixed anchor records include opposite-side feedback and vertical fan-out. Plan→A carries one authored waypoint and a label offset sentinel. A separate three-placement FunctionalDataflow view carries its own route/label sentinel. No Layout is used to construct either view.
4. `mixed_dispatch_edge_ids_reversed`: exact clone of case 3 with the 14 relation IDs reversed across their original sorted set, using a collision-free temporary ID domain and production `reidentify` for every reference. Names, endpoint semantics, port identities, aliases, positions, and authored route geometry retain correspondence. The inverse permutation must recover the exact original Project. This diagnoses relation-ID order sensitivity; exact geometric equality is an observation, not assumed quality success.
5. `subsystems_40_sparse`: five named subsystems, each with eight named processing stages, represented as 40 flat Function placements. Seven consecutive stage links in each subsystem (35), plus four cross-subsystem links per subsystem to its successor modulo five (20), totaling 55 distinct FunctionalExchanges. Cross links go stages 1/3/5/7 to successor stages 0/2/4/6. Positions are a predeclared 8-column × 5-row stage/subsystem grid. Every endpoint explicitly uses a distinct semantic port. This modest sparse cyclic workload is not the earlier diamond/bipartite corpus.
## Trace tasks and invariants
Predeclared trace tasks: workshop aliases `sa_report_to_relay`, `sa_direct_advice`, `sa_incident_decision`; mixed Sensor B→Ingest (shared target input), Ingest→Archive (shared source output), Dispatch→Operator, and feedback Plan→Sensor A; sparse subsystem 0 stage 1→subsystem 1 stage 0 and subsystem 4 stage 7→subsystem 0 stage 6. The manifest records trace edge identities and endpoints from the source model.
Every generated Project must pass `validate_candidate` before any output directory is created. JSON files serialize complete Projects directly. Manifest schema is 1; each case has name, relative project_file, diagram UUID, description, source counts, trace tasks, and relevant correspondence/sentinel metadata. Stable IDs and unique aliases are assigned independently of routing. Repeated generation should give byte-identical output; this is for the parent to verify, not asserted as already run.
Routing must preserve complete input Project bytes/model identity, semantic port assignments, authored routes/labels/attachments, fixed anchors, fold flags, and other views. Automatic non-port attachment-side choices are routing results, not preservation failures. The workshop contains no authored route sentinels; mixed cases supply that coverage. A promoted route may suspend authored geometry in rendered output while its stored metadata must remain intact. The generator does not prescribe which route topology, automatic side, contact count, length, or warning count is acceptable.
Usage (parent execution only): `cargo run --locked --offline -p oa-core --example routing_eval_corpus -- NEW_DIRECTORY`. The destination must not exist; manifest is written last. Existing files are never overwritten. No corpus generation, compiler, formatter, or router execution by this author before handoff.
@@ -0,0 +1,271 @@
{
"cases": [
{
"description": "Saved coastal rescue Allocation view, all source records retained.",
"diagram": "cb21862d-79e1-5a9d-bdf0-ee344c2fb219",
"metadata": {
"source": "examples/routing-workshop.json",
"view_alias": "sa_system_boundary_and_functions"
},
"name": "workshop_sa_original",
"project_file": "workshop_sa_original.json",
"source_counts": {
"elements": 75,
"relations": 62,
"selected_view_authored_routes": 0,
"selected_view_placements": 12,
"views": 6
},
"trace_tasks": [
{
"alias": "sa_report_to_relay",
"edge": "4678335a-04ae-5a19-a302-ea583bdd6c65",
"name": "Report to relay",
"source": "f5497540-43a7-5573-826b-61eb7e4760a9",
"target": "8b23ecf0-f5ce-57cf-8bce-8e0c08f89436"
},
{
"alias": "sa_direct_advice",
"edge": "956d5b0a-1e34-518f-b46d-425751998bbc",
"name": "Direct advice",
"source": "b8896811-d893-50fc-b695-d2ee07dae9e3",
"target": "febf00a2-efed-5faf-b8c2-5d4bc77ddb53"
},
{
"alias": "sa_incident_decision",
"edge": "526753bc-88b0-5322-bffc-1b36376becf1",
"name": "Incident decision",
"source": "b05744bd-4dce-54b7-a9ff-8861d11dc1e0",
"target": "b8896811-d893-50fc-b695-d2ee07dae9e3"
}
]
},
{
"description": "Same saved Project with only rescue_coordination_system placement folded.",
"diagram": "cb21862d-79e1-5a9d-bdf0-ee344c2fb219",
"metadata": {
"folded_element": "30fc41ea-fc3d-5b57-9a05-67b14425fad9",
"folded_placement": "75920e7a-4586-58b7-9eb2-7e0a3d8a1825",
"source": "examples/routing-workshop.json",
"unfold_restores_original_exact": true
},
"name": "workshop_sa_folded",
"project_file": "workshop_sa_folded.json",
"source_counts": {
"elements": 75,
"relations": 62,
"selected_view_authored_routes": 0,
"selected_view_placements": 12,
"views": 6
},
"trace_tasks": [
{
"alias": "sa_report_to_relay",
"edge": "4678335a-04ae-5a19-a302-ea583bdd6c65",
"name": "Report to relay",
"source": "f5497540-43a7-5573-826b-61eb7e4760a9",
"target": "8b23ecf0-f5ce-57cf-8bce-8e0c08f89436"
},
{
"alias": "sa_direct_advice",
"edge": "956d5b0a-1e34-518f-b46d-425751998bbc",
"name": "Direct advice",
"source": "b8896811-d893-50fc-b695-d2ee07dae9e3",
"target": "febf00a2-efed-5faf-b8c2-5d4bc77ddb53"
},
{
"alias": "sa_incident_decision",
"edge": "526753bc-88b0-5322-bffc-1b36376becf1",
"name": "Incident decision",
"source": "b05744bd-4dce-54b7-a9ff-8861d11dc1e0",
"target": "b8896811-d893-50fc-b695-d2ee07dae9e3"
}
]
},
{
"description": "Ten-function sensing/decision/dispatch network, explicit port sharing and fixed anchors.",
"diagram": "00000000-0000-0000-0000-0000000186a1",
"metadata": {
"authored_label_count_main": 1,
"authored_waypoint_count_main": 1,
"declared_feedback_cycle": [
"00000000-0000-0000-0000-000000018704",
"00000000-0000-0000-0000-000000018708",
"00000000-0000-0000-0000-00000001870a",
"00000000-0000-0000-0000-00000001870e",
"00000000-0000-0000-0000-000000018710",
"00000000-0000-0000-0000-000000018704"
],
"fixed_anchor_records": 6,
"secondary_diagram": "00000000-0000-0000-0000-0000000186a2",
"sentinel_edge": "00000000-0000-0000-0000-00000001adbd",
"shared_input": "ebfcf690-4ac5-5976-864c-337d844b6cd6",
"shared_outputs": [
"9244d718-d53a-54cb-a920-5b5312576da6",
"169224b3-b692-540d-ac73-1435e2a87b04"
]
},
"name": "mixed_dispatch",
"project_file": "mixed_dispatch.json",
"source_counts": {
"elements": 35,
"relations": 14,
"selected_view_authored_routes": 1,
"selected_view_placements": 10,
"views": 2
},
"trace_tasks": [
{
"alias": "flow_01",
"edge": "00000000-0000-0000-0000-00000001adb1",
"name": "Sensor B observations",
"source": "00000000-0000-0000-0000-000000018706",
"target": "00000000-0000-0000-0000-000000018708"
},
{
"alias": "flow_03",
"edge": "00000000-0000-0000-0000-00000001adb3",
"name": "Archive incoming observations",
"source": "00000000-0000-0000-0000-000000018708",
"target": "00000000-0000-0000-0000-00000001870c"
},
{
"alias": "flow_09",
"edge": "00000000-0000-0000-0000-00000001adb9",
"name": "Operator dispatch copy",
"source": "00000000-0000-0000-0000-000000018712",
"target": "00000000-0000-0000-0000-000000018716"
},
{
"alias": "flow_13",
"edge": "00000000-0000-0000-0000-00000001adbd",
"name": "Sensor A sampling feedback",
"source": "00000000-0000-0000-0000-000000018710",
"target": "00000000-0000-0000-0000-000000018704"
}
]
},
{
"description": "Same mixed Project with fixed reversed relation-ID permutation, remapped references.",
"diagram": "00000000-0000-0000-0000-0000000186a1",
"metadata": {
"edge_id_correspondence": {
"00000000-0000-0000-0000-00000001adb0": "00000000-0000-0000-0000-00000001adbd",
"00000000-0000-0000-0000-00000001adb1": "00000000-0000-0000-0000-00000001adbc",
"00000000-0000-0000-0000-00000001adb2": "00000000-0000-0000-0000-00000001adbb",
"00000000-0000-0000-0000-00000001adb3": "00000000-0000-0000-0000-00000001adba",
"00000000-0000-0000-0000-00000001adb4": "00000000-0000-0000-0000-00000001adb9",
"00000000-0000-0000-0000-00000001adb5": "00000000-0000-0000-0000-00000001adb8",
"00000000-0000-0000-0000-00000001adb6": "00000000-0000-0000-0000-00000001adb7",
"00000000-0000-0000-0000-00000001adb7": "00000000-0000-0000-0000-00000001adb6",
"00000000-0000-0000-0000-00000001adb8": "00000000-0000-0000-0000-00000001adb5",
"00000000-0000-0000-0000-00000001adb9": "00000000-0000-0000-0000-00000001adb4",
"00000000-0000-0000-0000-00000001adba": "00000000-0000-0000-0000-00000001adb3",
"00000000-0000-0000-0000-00000001adbb": "00000000-0000-0000-0000-00000001adb2",
"00000000-0000-0000-0000-00000001adbc": "00000000-0000-0000-0000-00000001adb1",
"00000000-0000-0000-0000-00000001adbd": "00000000-0000-0000-0000-00000001adb0"
},
"inverse_recovers_original_exact": true,
"paired_case": "mixed_dispatch",
"secondary_diagram": "00000000-0000-0000-0000-0000000186a2"
},
"name": "mixed_dispatch_edge_ids_reversed",
"project_file": "mixed_dispatch_edge_ids_reversed.json",
"source_counts": {
"elements": 35,
"relations": 14,
"selected_view_authored_routes": 1,
"selected_view_placements": 10,
"views": 2
},
"trace_tasks": [
{
"alias": "flow_01",
"edge": "00000000-0000-0000-0000-00000001adbc",
"name": "Sensor B observations",
"source": "00000000-0000-0000-0000-000000018706",
"target": "00000000-0000-0000-0000-000000018708"
},
{
"alias": "flow_03",
"edge": "00000000-0000-0000-0000-00000001adba",
"name": "Archive incoming observations",
"source": "00000000-0000-0000-0000-000000018708",
"target": "00000000-0000-0000-0000-00000001870c"
},
{
"alias": "flow_09",
"edge": "00000000-0000-0000-0000-00000001adb4",
"name": "Operator dispatch copy",
"source": "00000000-0000-0000-0000-000000018712",
"target": "00000000-0000-0000-0000-000000018716"
},
{
"alias": "flow_13",
"edge": "00000000-0000-0000-0000-00000001adb0",
"name": "Sensor A sampling feedback",
"source": "00000000-0000-0000-0000-000000018710",
"target": "00000000-0000-0000-0000-000000018704"
}
]
},
{
"description": "Five eight-stage subsystem chains with twenty directed cross-subsystem handoffs; all ports distinct.",
"diagram": "00000000-0000-0000-0000-000000030d41",
"metadata": {
"all_exchange_ports_distinct": true,
"chain_edges": 35,
"cross_edges": 20,
"grid_columns": 8,
"grid_rows": 5,
"groups": [
"Sensing",
"Communications",
"Assessment",
"Planning",
"Delivery"
],
"stages": [
"Acquire",
"Decode",
"Validate",
"Enrich",
"Aggregate",
"Decide",
"Package",
"Publish"
]
},
"name": "subsystems_40_sparse",
"project_file": "subsystems_40_sparse.json",
"source_counts": {
"elements": 150,
"relations": 55,
"selected_view_authored_routes": 0,
"selected_view_placements": 40,
"views": 1
},
"trace_tasks": [
{
"alias": "flow_35",
"edge": "00000000-0000-0000-0000-000000033473",
"name": "Sensing Decode handoff to Communications Acquire",
"source": "00000000-0000-0000-0000-000000030da6",
"target": "00000000-0000-0000-0000-000000030db4"
},
{
"alias": "flow_54",
"edge": "00000000-0000-0000-0000-000000033486",
"name": "Delivery Publish handoff to Sensing Package",
"source": "00000000-0000-0000-0000-000000030df2",
"target": "00000000-0000-0000-0000-000000030db0"
}
]
}
],
"construction": "Source-authored positions/topology, no Layout/projection/routing calls; validate all before writing.",
"definition_baseline": "f72aa2ca",
"generation_in_routing_timing": false,
"invariants": "Routing is read-only. Preserve all semantic records, port identities, fixed anchors, authored routes/labels, fold flags, and other views. ID permutation correspondence is explicit. No quality or automatic endpoint-side expectation.",
"schema": 1
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,55 @@
# Independent routing decision review
**Recommendation: retain the released router in the Arrange-reset candidate. Keep J and L as published experiments; do not tune further on either corpus.** The new evidence supports a meaningful L overlap improvement in one realistic view, but does not satisfy the predeclared native trace-task adoption gate and includes label/ID-order regressions. This is a bounded decision, not a finding that the released router is already satisfactory.
## Exact runs and integrity
Optimized variants: released-equivalent router at `4fb3cdc721e6fb8d70141b9c8f59809c53e7f16c`; J at `3ea0e23b70edfcaf61b1e900afb00254c7e80f75`; L at `095ab3b35847654d40e7bab9815c2bceb77484d1`. These are evaluator-bearing source pins, not three releases. Frozen corpus commit `f674e36c8b75dfa95246eabb672e36c937aec31b` and manifest hash `a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717`.
Independently checked all nine timing/geometry receipts: process exit0, no timeout, corpus/binary unchanged, raw stdout/stderr lengths and SHA256 match receipts. Recomputed timing summaries for six runs ×five cases ×seven samples=210 measured calls, all complete/uncensored with full-route repeat equality and unchanged Project flags. No rerun, compilation or native action performed during this audit.
## Practical timing result
The predefined100ms median/200ms maximum and relative1.25×baseline+1ms screening checks pass. Observed median ranges across the two interleaved passes:
| Variant | Workshop original | Mixed original | Mixed reversed IDs | Sparse40 |
|---|---:|---:|---:|---:|
| Released |0.541–0.663ms|0.213–0.215ms|0.179–0.202ms|2.260–2.704ms|
| J |0.441–0.716ms|0.259–0.285ms|0.331–0.477ms|2.225–2.306ms|
| L |0.577–0.579ms|0.407–0.422ms|0.365–0.589ms|2.966–3.210ms|
Maximum observed measured call6.196ms; every case median below3.3ms. The+1ms relative allowance intentionally matters when baseline calls are submillisecond; passing it does not mean zero overhead. L is slower on sparse/mixed cases but comfortably passes these modest-corpus absolute screens. The earlier debug routing_geometry suite4.30→16.43s remains a separate cost signal; it cannot override or be substituted for these optimized route-only observations. Neither dataset proves a general latency bound, scaling law, p95, worst-case timeout or native input responsiveness.
## Quality tradeoffs against released routing
| Case | J | L |
|---|---|---|
| Workshop original |sharing1042→1074; proper6→5; contacts22→23; label/node11→13; label/stroke5→6|sharing1042→602; proper6→5; contacts22→23; label/node11→12; label/stroke5→6; length+24; area+12756|
| Workshop folded |reported scalar vector unchanged|unchanged|
| Mixed original |unchanged|unchanged|
| Mixed reversed IDs |sharing132→233.5999756; contacts4→5|same regression|
| Sparse40 |sharing496→372; proper24→25; contacts32→31; label/stroke15→13; area+8960|same changes|
L removes440 raw shared units in workshop (970→530 nonterminal), a substantial improvement worth retaining as evidence. It still adds a label/node collision and unrelated label/stroke intersection. J's smaller scoring patch is theoretically motivated and improved the earlier diamond, yet this realistic workshop and fixed-ID permutation expose regressions. Fewer proper crossings or contacts cannot automatically excuse shared trunks, obscured labels or wrong-turn ambiguity. The unchanged folded case and mixed original do not make ID sensitivity disappear.
Earlier37-scene evidence remains consistent with a non-dominating tradeoff: J solved diamond's extra trunk but regressed original bipartite overlap; P offered no layered benefit; L/PL improved layered bipartite only11 shared units and left104 nonterminal units. P+L traded baseline overlap for an isolated crossing. These are finite observations rather than an adoption score. Do not select favorable graph IDs or add another penalty coefficient after seeing results.
## Analysis-v1 failure remains explicit
The current analysis has six `frozen_project_exact` failures, one per mixed case/variant. Independent inspection of mixed original shows only typed fractional values expanded by serde_json::Value: anchor offsets0.3/0.6 and label fractions0.4 become their exact f32-to-f64 expansions. This supports the representation-mismatch diagnosis, not a blanket tolerance waiver. Parent's separate typed-normalization-v2 check must close every discrepancy at schema-known f32 fields while keeping identities, strings, arrays and other numeric fields exact. Preserve analysis-v1 and its failed status. This review does not silently relabel those six failures as passed.
All other existing analysis checks pass, including projected identity/geometry, effective pins/fractions, physical visible semantic-port tips, warning sets, and no-new node/penetration identities. That is scoped evaluator evidence, not independent verification of every hidden-port or explicit-attachment case. The independent contact audit is available and bound below; native task assessment remains absent.
## Adoption boundary
The frozen rubric requires correct source-to-target trace tasks and no newly ambiguous task elsewhere. No native trace-task result exists; approximate core label rectangles cannot prove actual text readability. Therefore neither J nor L earns production adoption merely by passing timing. Keep the reset candidate independent on released routing and verify its explicit reset/history/source contract. If future native evaluation is undertaken, use the already frozen named tasks and report uncertainty/wrong turns without changing fixture geometry. Do not broaden this into indefinite tuning or silently change the adoption rubric.
Evidence SHA256: analysis-v1 `1634f06ef7c4e50ebcbec64423a9a8730c08c822bf0023572e62ca0281c96302`; independent contact audit `40b62731db7dc332b13021fa1f13bed176455feb2fb13d15998c761a4623b492`. No production acceptance, #32 closure or native observation claimed.
## Typed-serialization finding closed
Reviewed v2 analyzer SHA256 `a72895248175fc56667d7b86cb4120a840d931e74ab1149e9649bb82d179f1ae`. Its comparison policy applies exact IEEE754 binary32 bit equality ONLY at schema-declared Diagram node PortAnchor.offset and route EdgeLabel.fraction paths. It requires finite numeric values in[0,1], preserves dict keys/list lengths, and compares every other field and type exactly. It does not apply a global numeric tolerance or alter raw evidence.
Independently inspected all15 reported Project comparisons:30 differing leaves across exactly six mixed-case/variant observations, five typed fractional paths each. Every pair independently packs to identical binary32 bytes. No other differences are reported. V2 has zero failed checks. Verified script/output and original-before/original-after hashes directly against current bytes; original failed report remains `1634f06e...` unchanged. V2 report SHA256 `88af679275d85dad44a10dfb1eb4da94b861125c5948062c450635bdeb9814fd`.
This closes the six representation-related Project equality failures without rerouting, changing the corpus or weakening other-field equality. Earlier section records the truthful v1 state and is superseded only on that finding. The production recommendation is unchanged: retain released routing for the reset candidate; J/L remain experiments pending the unmet native trace-task criterion. No timing or geometry quality numbers were changed by this normalization review.
@@ -0,0 +1,744 @@
{
"archive": "routing-independent-evidence.zip",
"bytes": 6545295,
"sha256": "fe88b4dccb41a639c7cca421d057c77652bfbdbeb908651e56b5a10274b0cdb6",
"member_byte_readback": true,
"members": [
{
"path": "binaries/j/build.json",
"bytes": 556,
"sha256": "88556a6d32ce1fd13c8831c88701e91eed5e195bce3daf440ddfaa9bf63d0973"
},
{
"path": "binaries/lanes/build.json",
"bytes": 570,
"sha256": "c20aa7deaf068d1923f0cadd6dec34dc3150a4a6d1859db4421a0091fce5487e"
},
{
"path": "binaries/released/build.json",
"bytes": 570,
"sha256": "e6d1676f9b89fcf711edd1cdaa149d578c15ccfcdfe893a8b6c7ab430fd947f5"
},
{
"path": "corpus/manifest.json",
"bytes": 10593,
"sha256": "a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717"
},
{
"path": "corpus/mixed_dispatch.json",
"bytes": 32787,
"sha256": "81d25af021cbad18af4262a220ba60372e51ca19083b7e80f2b19196baf05990"
},
{
"path": "corpus/mixed_dispatch_edge_ids_reversed.json",
"bytes": 32787,
"sha256": "25c95be6b6e7ad9ebcdc83aacc13fbbaa5a56651ba2843f8d1658c075ed789f8"
},
{
"path": "corpus/subsystems_40_sparse.json",
"bytes": 124043,
"sha256": "ad0ee7a0ab9c9f3c5f26a6d839f6627a82aa38858a3d5cc1ca87f5a8d795533e"
},
{
"path": "corpus/workshop_sa_folded.json",
"bytes": 102922,
"sha256": "ea5fd285d11795e5e543e4144349c32c92a5b328b8c5e2d1be8b75b70703dc97"
},
{
"path": "corpus/workshop_sa_original.json",
"bytes": 102923,
"sha256": "cc9b26390594513c11b3d85b768d244b2df8e7bed8cb76c4bdf0dc24db1d2ef6"
},
{
"path": "routing-corpus-checks-20260925/01-generate/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/01-generate/command/context.json",
"bytes": 3599,
"sha256": "e780b950bbb8087003017e3649a507b738c3425ae09b64aa10301f0cb5520431"
},
{
"path": "routing-corpus-checks-20260925/01-generate/command/inputs-after.json",
"bytes": 1735049,
"sha256": "784d52a2766b11aba0a1c0c3f3a225b30e3e4ca0186c8b59f329f805992a5de4"
},
{
"path": "routing-corpus-checks-20260925/01-generate/command/inputs-before.json",
"bytes": 1735049,
"sha256": "784d52a2766b11aba0a1c0c3f3a225b30e3e4ca0186c8b59f329f805992a5de4"
},
{
"path": "routing-corpus-checks-20260925/01-generate/command/output.log",
"bytes": 100,
"sha256": "20f06b14f491c24c6951a4f5a75336919b666190a41f83295c733d488727ba08"
},
{
"path": "routing-corpus-checks-20260925/01-generate/command/result.json",
"bytes": 4244,
"sha256": "82d0cc88d8013ec8c05c9276c85300338eb19010473f2aabb35f8a2e7ced31e1"
},
{
"path": "routing-corpus-checks-20260925/01-generate/command/stderr.log",
"bytes": 366,
"sha256": "e439707594bbff491ca818d2cfd3ea66b3871943a036c131be8a684ade3292e4"
},
{
"path": "routing-corpus-checks-20260925/01-generate/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"path": "routing-corpus-checks-20260925/01-generate/orchestration.log",
"bytes": 171,
"sha256": "c5399c8626075ecac0187eef141e9c59dc022ce54c32445ea6c2aa0f593ad887"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/command/context.json",
"bytes": 3613,
"sha256": "8e383c2c18b49227c24b423f7908b442c3988d16516c61eafeeafdf45bb569d2"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/command/inputs-after.json",
"bytes": 1735049,
"sha256": "784d52a2766b11aba0a1c0c3f3a225b30e3e4ca0186c8b59f329f805992a5de4"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/command/inputs-before.json",
"bytes": 1735049,
"sha256": "784d52a2766b11aba0a1c0c3f3a225b30e3e4ca0186c8b59f329f805992a5de4"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/command/output.log",
"bytes": 107,
"sha256": "be957352ab5ae1aca47ae57d39765985f2417b91ee974583864a5ae104140019"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/command/result.json",
"bytes": 4272,
"sha256": "96601902508ef873612be164bc6adfbe7be799d1bcd63d68b27aeaa3dbed1f04"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/command/stderr.log",
"bytes": 257,
"sha256": "16f676779879f4832ef510d76fa6f63abf83c191eb393d388d885b15c6cdbbc5"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"path": "routing-corpus-checks-20260925/02-generate-repeat/orchestration.log",
"bytes": 178,
"sha256": "9cabeb98b46d4944fdf5867951bfbd9227ac32dc19ffb097dde76ad84cad7ab5"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/command/context.json",
"bytes": 3608,
"sha256": "bb9b5d39f9d36accbb9d10c5694ec5a333482d93fb060485adb59ab22f6fb9c2"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/command/inputs-after.json",
"bytes": 1735049,
"sha256": "a492a98cf40cb84d1fa9d46e5d11f0a98a2bf2ec03dd030013ebcdfc04d5521a"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/command/inputs-before.json",
"bytes": 1735049,
"sha256": "a492a98cf40cb84d1fa9d46e5d11f0a98a2bf2ec03dd030013ebcdfc04d5521a"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/command/output.log",
"bytes": 103,
"sha256": "58bd78b19f839933c31ca11f902daa5b38c0d14720003cca2dced8bf9249fc44"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/command/result.json",
"bytes": 4265,
"sha256": "965c9a3c82c8f2f2bd4b82158e2b15340b4f00fe427d19ca040ec54b3c92443c"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/command/stderr.log",
"bytes": 369,
"sha256": "1fe1b633ee58c0f1249354057013547561c8f4aa946d16b70553ab6102eb0b50"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"path": "routing-corpus-checks-20260925/03-generate-fixed/orchestration.log",
"bytes": 177,
"sha256": "22d5231c06be3af285ec1f4df4946292660dcfc70318c92fb23f4f9099e4e66a"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/command/context.json",
"bytes": 3622,
"sha256": "4b12917c2770834c59ed9be866e1132bc3056d6913eeae68ce95cdc494c47bdc"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/command/inputs-after.json",
"bytes": 1735049,
"sha256": "a492a98cf40cb84d1fa9d46e5d11f0a98a2bf2ec03dd030013ebcdfc04d5521a"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/command/inputs-before.json",
"bytes": 1735049,
"sha256": "a492a98cf40cb84d1fa9d46e5d11f0a98a2bf2ec03dd030013ebcdfc04d5521a"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/command/output.log",
"bytes": 110,
"sha256": "c3bec5cc117c1465de6872a49274c9cd622c117c5061b9b3a8a9141643e94a95"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/command/result.json",
"bytes": 4293,
"sha256": "bc1535e096dc19f27b405bb22cd6087ede32f69e1a171ab4b2a3a095ea2bbe5c"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/command/stderr.log",
"bytes": 260,
"sha256": "c061b9732c764caa80dc2bcba37f5b41eab0f45db45d9e3dd2eac4e20c7245b4"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"path": "routing-corpus-checks-20260925/04-generate-fixed-repeat/orchestration.log",
"bytes": 184,
"sha256": "497d19bd6fbaf3dfb4a6e4d54667dfc0275a9d484ca8658d9d9d91c0c9090ec1"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/command/context.json",
"bytes": 3567,
"sha256": "3940fa319e4587151d0db7f1c6dd1263ea2cd1a9305e3c487a0d8bd841f8a34f"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/command/inputs-after.json",
"bytes": 1738623,
"sha256": "03047439b559a298fc4ef0ca6cc3b113e4a53fa5df8e0456aeeab43d86f52441"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/command/inputs-before.json",
"bytes": 1738623,
"sha256": "03047439b559a298fc4ef0ca6cc3b113e4a53fa5df8e0456aeeab43d86f52441"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/command/result.json",
"bytes": 4219,
"sha256": "eee254721a983e49ffe929f1e0f70b06853565a23d261a326620c69529c947ce"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/command/stderr.log",
"bytes": 1905,
"sha256": "67da03bbab8006a70245e7b96ee5493793de0d5e5914f2c0bdc876ca2208d726"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/environment.json",
"bytes": 9470,
"sha256": "1cda80470e5893747b1aad7eda5ef51d57069441e810698cd7f94f7a7521bfe5"
},
{
"path": "routing-corpus-checks-20260925/05-build-lanes/orchestration.log",
"bytes": 176,
"sha256": "b35f03c05260c4c01e72a9c8234da36783676b741e887dba9497115e7c8ecb0e"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/command/context.json",
"bytes": 3573,
"sha256": "100c5a4d5eb776805b67f4a2f4a6304578cedd527f1b34ec74348535ee8c959c"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/command/inputs-after.json",
"bytes": 1738623,
"sha256": "1dbd1badc2494426719bd0e19eccf804f301d9f47bdb50ea7772a32d9c9b9008"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/command/inputs-before.json",
"bytes": 1738623,
"sha256": "1dbd1badc2494426719bd0e19eccf804f301d9f47bdb50ea7772a32d9c9b9008"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/command/result.json",
"bytes": 4234,
"sha256": "67fdba73a040aae0fbcc06fc2f1e27c6d1dc24d8c4dcb1f9d92dd58d7ea1aedb"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/command/stderr.log",
"bytes": 179,
"sha256": "b3986da5974723f61b3a8257786c9c0721e32f14534c35ae3cb92a119987723c"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/environment.json",
"bytes": 9470,
"sha256": "1cda80470e5893747b1aad7eda5ef51d57069441e810698cd7f94f7a7521bfe5"
},
{
"path": "routing-corpus-checks-20260925/06-build-lanes-fixed/orchestration.log",
"bytes": 180,
"sha256": "6da6086f8bbbaad90e3cefb8d9ac58ee7ef384601c2523381f0e6321c58bd2b3"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/command/context.json",
"bytes": 3563,
"sha256": "a3234c8d6b2e7258b1a3d39555fe58e459020bc0b3205440cdfd851d8c6b8cfe"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/command/inputs-after.json",
"bytes": 1738623,
"sha256": "447b0f3be97b1d4885e3c6c72308e75e78b78c8f3cd5d15711f3088896bec345"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/command/inputs-before.json",
"bytes": 1738623,
"sha256": "447b0f3be97b1d4885e3c6c72308e75e78b78c8f3cd5d15711f3088896bec345"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/command/result.json",
"bytes": 4204,
"sha256": "ce07dc5193bf2d5c875f19e576e821d303a414ab2f4ac31a9b0f281c24cb2c5a"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/command/stderr.log",
"bytes": 179,
"sha256": "e35e1e1566c879a49cb498a2b309a2c9193bbbd80cca790da79b6615f94ef187"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/environment.json",
"bytes": 9470,
"sha256": "1cda80470e5893747b1aad7eda5ef51d57069441e810698cd7f94f7a7521bfe5"
},
{
"path": "routing-corpus-checks-20260925/07-build-j/orchestration.log",
"bytes": 170,
"sha256": "8c4c6481f5aa21a6ef8ef53ed37420cde0da80f67e782c9ee9cb04ef5e909c3d"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/command/context.json",
"bytes": 3570,
"sha256": "60e081d0c2a3903e9cd1cf2bb961138c90824993857251dc6960709fa59d5261"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/command/inputs-after.json",
"bytes": 1738623,
"sha256": "16189a473862e3793be91a9d46063dff43cef609b19a8f87472d56eb2230b3fd"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/command/inputs-before.json",
"bytes": 1738623,
"sha256": "16189a473862e3793be91a9d46063dff43cef609b19a8f87472d56eb2230b3fd"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/command/result.json",
"bytes": 4225,
"sha256": "7745afe769aba3141cf258cd6c0b9344b5ceb84c37f9698f9433c5b4a8fb7659"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/command/stderr.log",
"bytes": 179,
"sha256": "8d6a94bea51603e4d6e7f296942356b2772b352ae9b406be8da946c755b69799"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/environment.json",
"bytes": 9470,
"sha256": "1cda80470e5893747b1aad7eda5ef51d57069441e810698cd7f94f7a7521bfe5"
},
{
"path": "routing-corpus-checks-20260925/08-build-released/orchestration.log",
"bytes": 177,
"sha256": "59b278df15f857851ad8d748a9f116ca7be21fadeb6fc6900049a205524921b0"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/command/context.json",
"bytes": 3519,
"sha256": "99ffd62ac4ff9900612bb0bc3e785a0f92d0ff63ffd8695f69110858f83e4a1c"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/command/inputs-after.json",
"bytes": 1738623,
"sha256": "16189a473862e3793be91a9d46063dff43cef609b19a8f87472d56eb2230b3fd"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/command/inputs-before.json",
"bytes": 1738623,
"sha256": "16189a473862e3793be91a9d46063dff43cef609b19a8f87472d56eb2230b3fd"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/command/result.json",
"bytes": 4176,
"sha256": "b836499659fb9229b4f44f97c7056e44ddb02f97fb736f69ca8ea264d6654a6a"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/command/stderr.log",
"bytes": 177,
"sha256": "c97eb40db6f4904093faae2961f0360dad2986b4be3a36ffc14ff6b83218477c"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"path": "routing-corpus-checks-20260925/09-observer-clippy/orchestration.log",
"bytes": 178,
"sha256": "1ca36161f9ff64871b19ff64cbbec01f889a4bfdc1344910bc08ca46b6bc286c"
},
{
"path": "routing-corpus-runs-20260925/01-released/receipt.json",
"bytes": 2682,
"sha256": "b9d83c9930c9cbbcdc069bb86bab557171eeebbe1ff1357fa98efe8e26642e3c"
},
{
"path": "routing-corpus-runs-20260925/01-released/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/01-released/stdout.jsonl",
"bytes": 11218,
"sha256": "ae4056cac47d41d6ab8f3585cb53c5a6d734dc60d3d7ddc3af84e97a7e41ecfc"
},
{
"path": "routing-corpus-runs-20260925/02-j/receipt.json",
"bytes": 2654,
"sha256": "7a1b3b837d512b9be3c8649644ac374a5732364e62090c18038e8b0ab994c683"
},
{
"path": "routing-corpus-runs-20260925/02-j/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/02-j/stdout.jsonl",
"bytes": 11219,
"sha256": "847db6381f23a9c4c4a2a01e0c2aa9adec65671ab99d136247e9f79385e5b8d9"
},
{
"path": "routing-corpus-runs-20260925/03-lanes/receipt.json",
"bytes": 2677,
"sha256": "750965ee4205793bfdcc66fd4080e3aa438df808c0844e62df0381b83f1c810f"
},
{
"path": "routing-corpus-runs-20260925/03-lanes/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/03-lanes/stdout.jsonl",
"bytes": 11221,
"sha256": "1f9e91d34c6ab828be8412ad4015e0bdef443e1f94f16b309355bb11ed2cb3f8"
},
{
"path": "routing-corpus-runs-20260925/04-lanes/receipt.json",
"bytes": 2678,
"sha256": "d5ad4ee28ba4b15b68afefc7957e995c13d3bf53bd6f3e0c4be1363039067763"
},
{
"path": "routing-corpus-runs-20260925/04-lanes/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/04-lanes/stdout.jsonl",
"bytes": 11221,
"sha256": "9600f47829425938d72f12666324e8fba45def4c6c5ee6073fb81c46383daf91"
},
{
"path": "routing-corpus-runs-20260925/05-j/receipt.json",
"bytes": 2656,
"sha256": "65ee12d5b456f0d097d085b1a6f226655f36977cc2b875056a9b5a35625a0f2f"
},
{
"path": "routing-corpus-runs-20260925/05-j/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/05-j/stdout.jsonl",
"bytes": 11220,
"sha256": "b3611d72e9c193aace8d0e05980b1860eb12d48ad26b7a8b57613fdfa07fbc20"
},
{
"path": "routing-corpus-runs-20260925/06-released/receipt.json",
"bytes": 2683,
"sha256": "9c6e8e9ef1012c6718744d2fe968e49c5ebc38ad190e910a68b81e558e7d67a6"
},
{
"path": "routing-corpus-runs-20260925/06-released/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/06-released/stdout.jsonl",
"bytes": 11220,
"sha256": "989af06061fbce0dcfd6bf164fec02362546a1702ae9a5cb144842861fdd3748"
},
{
"path": "routing-corpus-runs-20260925/analysis-receipts.json",
"bytes": 1816,
"sha256": "b5c091729f2496c764abec53ca9167580d308b8bdc78797bb902c54607634e54"
},
{
"path": "routing-corpus-runs-20260925/geometry-j/receipt.json",
"bytes": 2680,
"sha256": "81680314df505602fe2f05eb8f7e87296b92d66f1b30c0688a24a7a793a26152"
},
{
"path": "routing-corpus-runs-20260925/geometry-j/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/geometry-j/stdout.jsonl",
"bytes": 470513,
"sha256": "23874838cc63ac640c941939599af225762ffc3d1fa07ca0a954dc97a1d40db2"
},
{
"path": "routing-corpus-runs-20260925/geometry-lanes/receipt.json",
"bytes": 2701,
"sha256": "92dff19e9740315382c2a86d7270e5c4f553524d0a294f08791925fc6afca8de"
},
{
"path": "routing-corpus-runs-20260925/geometry-lanes/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/geometry-lanes/stdout.jsonl",
"bytes": 470437,
"sha256": "07ddac7f8515797a433aef9a0306850eadc457411666325a9f710c68473f9c68"
},
{
"path": "routing-corpus-runs-20260925/geometry-released/receipt.json",
"bytes": 2707,
"sha256": "d957c153fb80bcf2b95f0ba863f0f899bac29368e85d272bfcda4ea3bf97083e"
},
{
"path": "routing-corpus-runs-20260925/geometry-released/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "routing-corpus-runs-20260925/geometry-released/stdout.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"path": "routing-independent-corpus-20260925/manifest.json",
"bytes": 10593,
"sha256": "a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717"
},
{
"path": "routing-independent-corpus-20260925/mixed_dispatch.json",
"bytes": 32796,
"sha256": "9f0c3bb9e06028ca38746014e34638660760323044aad8e594ebd89b056edc7a"
},
{
"path": "routing-independent-corpus-20260925/mixed_dispatch_edge_ids_reversed.json",
"bytes": 32796,
"sha256": "2de27d96c21ed3a2d63a66eea44ce78744d66709956cd7db232f9178979f5789"
},
{
"path": "routing-independent-corpus-20260925/subsystems_40_sparse.json",
"bytes": 124043,
"sha256": "ad0ee7a0ab9c9f3c5f26a6d839f6627a82aa38858a3d5cc1ca87f5a8d795533e"
},
{
"path": "routing-independent-corpus-20260925/workshop_sa_folded.json",
"bytes": 102922,
"sha256": "ea5fd285d11795e5e543e4144349c32c92a5b328b8c5e2d1be8b75b70703dc97"
},
{
"path": "routing-independent-corpus-20260925/workshop_sa_original.json",
"bytes": 102923,
"sha256": "cc9b26390594513c11b3d85b768d244b2df8e7bed8cb76c4bdf0dc24db1d2ef6"
},
{
"path": "routing-independent-corpus-repeat-20260925/manifest.json",
"bytes": 10593,
"sha256": "a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717"
},
{
"path": "routing-independent-corpus-repeat-20260925/mixed_dispatch.json",
"bytes": 32796,
"sha256": "6c6708e2b5fa8224246dac428d42068f44436c05b28aba0483b69190504cadf1"
},
{
"path": "routing-independent-corpus-repeat-20260925/mixed_dispatch_edge_ids_reversed.json",
"bytes": 32796,
"sha256": "9378a170ac70992035536b50cb07b851dcfec28acc08ef92f2465edeaee93abe"
},
{
"path": "routing-independent-corpus-repeat-20260925/subsystems_40_sparse.json",
"bytes": 124043,
"sha256": "ad0ee7a0ab9c9f3c5f26a6d839f6627a82aa38858a3d5cc1ca87f5a8d795533e"
},
{
"path": "routing-independent-corpus-repeat-20260925/workshop_sa_folded.json",
"bytes": 102922,
"sha256": "ea5fd285d11795e5e543e4144349c32c92a5b328b8c5e2d1be8b75b70703dc97"
},
{
"path": "routing-independent-corpus-repeat-20260925/workshop_sa_original.json",
"bytes": 102923,
"sha256": "cc9b26390594513c11b3d85b768d244b2df8e7bed8cb76c4bdf0dc24db1d2ef6"
},
{
"path": "tools-and-analysis/analyze-routing-independent-20260925.py",
"bytes": 19925,
"sha256": "2816a8f56b888b28b611e0045b533f7bd2da1b06222430423b595463dc377903"
},
{
"path": "tools-and-analysis/analyze-routing-independent-v2-20260925.py",
"bytes": 22830,
"sha256": "a72895248175fc56667d7b86cb4120a840d931e74ab1149e9649bb82d179f1ae"
},
{
"path": "tools-and-analysis/audit-routing-corpus-contacts-20260925.py",
"bytes": 12483,
"sha256": "a6d95610a45faa3b4417df3c82059967d9729975fcf39dd1e9359ff1a20e0036"
},
{
"path": "tools-and-analysis/freeze-routing-corpus-20260925.py",
"bytes": 1452,
"sha256": "31317e3b66e7407d6ca68a6ee6087837b52e31341989dbd2401997220444d04b"
},
{
"path": "tools-and-analysis/preserve-routing-binaries-20260925.py",
"bytes": 1209,
"sha256": "969142ee22eee24d40a21e4ad854720a484c6e30325a92a9e6fc262001076b97"
},
{
"path": "tools-and-analysis/routing-independent-analysis-20260925.json",
"bytes": 7649923,
"sha256": "1634f06ef7c4e50ebcbec64423a9a8730c08c822bf0023572e62ca0281c96302"
},
{
"path": "tools-and-analysis/routing-independent-analysis-review-20260925.md",
"bytes": 6513,
"sha256": "dd07a61afb4717256565953f629d9e312b38dbca56fcc2c8b8db01f7230a45a4"
},
{
"path": "tools-and-analysis/routing-independent-analysis-v2-20260925-receipt.json",
"bytes": 2100,
"sha256": "16d036d4bf061ea35d297fc8d765ff6ff639825bc86fa065787d0cfc13427cd9"
},
{
"path": "tools-and-analysis/routing-independent-analysis-v2-20260925.json",
"bytes": 7687929,
"sha256": "88af679275d85dad44a10dfb1eb4da94b861125c5948062c450635bdeb9814fd"
},
{
"path": "tools-and-analysis/routing-independent-contact-review-20260925.md",
"bytes": 6764,
"sha256": "1e90af45a96adc6f3cda418c3c3a4362b2bb773c46df66fbd40508bf032a4e0e"
},
{
"path": "tools-and-analysis/routing-independent-contacts-20260925.json",
"bytes": 213737,
"sha256": "40b62731db7dc332b13021fa1f13bed176455feb2fb13d15998c761a4623b492"
},
{
"path": "tools-and-analysis/routing-independent-decision-review-20260925.md",
"bytes": 7539,
"sha256": "de8fc5cb4ec10bffa9780e80c272d9aa55eeedf4ea2cc7b81aeff45f77040e7c"
},
{
"path": "tools-and-analysis/run-routing-analysis-20260925.py",
"bytes": 1632,
"sha256": "0a5d44c80eb59841b5c9323c8e13370b30dc60b29e200de2fa8ab54a4ad6f338"
},
{
"path": "tools-and-analysis/run-routing-binaries-20260925.py",
"bytes": 2882,
"sha256": "903c1c21971e7c5d73875db7df578c442496a17f98e4dde7a437d5f116f54604"
},
{
"path": "tools-and-analysis/run-routing-corpus-check-20260925.py",
"bytes": 2793,
"sha256": "2726a397bd4ecb4dcfff6fc170a66ce2655229079f42335faa2a4bfe4a202f6d"
},
{
"path": "tools-and-analysis/run.py",
"bytes": 13814,
"sha256": "698ed7182726c77fa4a1c85fc6dd08187ed20689941f57e749e3f0bc845f3252"
},
{
"path": "tools-and-analysis/select-routing-variant-20260925.py",
"bytes": 930,
"sha256": "bee977f62516d2e610a4aa5addfc9f17af8c61103b5f69c61733b6e38a257ffa"
}
],
"excluded": "Executables reproducible from identified source/build commands; binary hashes preserved. New frozen inputs are also committed alongside this archive."
}
@@ -0,0 +1,36 @@
{
"source_commit": "f0eae74912061455453acd7ec17e2ddbe498ee2c",
"repeated_generation_byte_identical": true,
"files": [
{
"path": "manifest.json",
"bytes": 10593,
"sha256": "a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717"
},
{
"path": "mixed_dispatch.json",
"bytes": 32787,
"sha256": "81d25af021cbad18af4262a220ba60372e51ca19083b7e80f2b19196baf05990"
},
{
"path": "mixed_dispatch_edge_ids_reversed.json",
"bytes": 32787,
"sha256": "25c95be6b6e7ad9ebcdc83aacc13fbbaa5a56651ba2843f8d1658c075ed789f8"
},
{
"path": "subsystems_40_sparse.json",
"bytes": 124043,
"sha256": "ad0ee7a0ab9c9f3c5f26a6d839f6627a82aa38858a3d5cc1ca87f5a8d795533e"
},
{
"path": "workshop_sa_folded.json",
"bytes": 102922,
"sha256": "ea5fd285d11795e5e543e4144349c32c92a5b328b8c5e2d1be8b75b70703dc97"
},
{
"path": "workshop_sa_original.json",
"bytes": 102923,
"sha256": "cc9b26390594513c11b3d85b768d244b2df8e7bed8cb76c4bdf0dc24db1d2ef6"
}
]
}
@@ -0,0 +1,150 @@
# Independent routing corpus comparison
Issue [32](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/32).
**Decision: retain the released router for the separate Arrange-reset candidate.**
J and L remain experiments. L provides a substantial workshop overlap improvement,
but both candidates worsen a fixed ID-permutation case and neither has native
traceability acceptance. The timing screen passes on this corpus; the earlier
debug-suite cost concern is not reproduced here and is not thereby disproved.
No release, merge, issue closure, Linux build or native UI acceptance is claimed.
## Inputs and identified code
The [corpus plan](corpus-plan.md), [timing protocol](timing-protocol.md) and
[adoption rubric](adoption-rubric.md) preceded routing observations. Five complete
Projects are committed under [corpus](corpus/manifest.json): saved SA workshop,
its single collapsed-placement variant, ten-function mixed dispatch with shared
and distinct ports and an authored pin/label, fixed reversal of its fourteen
edge IDs, and a flat forty-function/fifty-five-exchange sparse workload.
All inputs validate; repeated corrected generation is byte-identical.
Generator source `a879341c` initially produced differing random suffixes in three
secondary-view placement aliases. Two original generations are retained in the
archive. `f0eae749` assigns fixed aliases; two new generations agree in all six
files, frozen at `f674e36c`. This was corrected before any routing observation.
The corpus manifest SHA256 is
`a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717`.
Generation receipts and every input hash are retained.
| Variant | Router source | Common-harness build commit |
| --- | --- | --- |
| Released | `715036e132677dd2bc2fb37ed316d93dc9987aec` | `4fb3cdc721e6fb8d70141b9c8f59809c53e7f16c` |
| J: target-join scoring | `08656b18bf8934cf264469cf68fc6dea97c15cbb` | `3ea0e23b70edfcaf61b1e900afb00254c7e80f75` |
| L: J plus bounded lane coordinates | `e8ec6dbb3160f62476a5557f14605f68959f65fe` | `095ab3b35847654d40e7bab9815c2bceb77484d1` |
These are three router sources in one identical evaluator, not whole historic
product builds. Only `crates/oa-core/src/routing.rs` differs among their build
commits. Windows Rust 1.98.1 stable gnullvm/LLVM mingw, Cargo release profile,
one build job and incremental disabled. Original tool/configuration/source-tree
receipts identify the environment; executable hashes are in `binaries/*/build.json`
inside the evidence archive. Copies were preserved before another build replaced
the shared target outputs. No compiler or other evaluator ran during timings.
The first optimized attempt at `f674e36c` failed on the expanded geometry JSON
macro's recursion depth. `095ab3b3` extracts three serialization expressions
without changing their schema or routing. All three final builds passed;
the failed receipt remains in the archive. Strict core/all-target Clippy also
passes at `4fb3cdc7` (`09-observer-clippy`).
## Timing result
The fixed order was released→J→L→L→J→released. Each invocation loads/projects
outside the clock, then performs one retained warmup and seven measured routing
calls per case. All 210 measured calls completed without censorship or timeout;
each complete RoutedView and its endpoints equalled that invocation's warmup.
All nine timing/geometry receipts confirm unchanged input files and binaries.
The table gives the two invocation medians in milliseconds (first / second),
not a percentile or scaling guarantee.
| Case | Released | J | L |
| --- | --- | --- | --- |
| Workshop original | 0.541 / 0.663 | 0.716 / 0.441 | 0.579 / 0.577 |
| Workshop folded | 0.409 / 0.623 | 0.406 / 0.419 | 0.567 / 0.638 |
| Mixed dispatch | 0.215 / 0.213 | 0.285 / 0.259 | 0.422 / 0.407 |
| Mixed IDs reversed | 0.179 / 0.202 | 0.477 / 0.331 | 0.589 / 0.365 |
| Forty-function sparse | 2.260 / 2.704 | 2.225 / 2.306 | 2.966 / 3.210 |
Maximum observed measured call: 6.1959 ms. Every case passes the predeclared 100 ms
median/200 ms maximum screen and candidate ≤ 1.25×baseline + 1 ms rule in both rounds,
including L versus J. At sub-millisecond medians, the absolute1ms allowance and
visible run-to-run variation matter; do not market ratios as precise speedups.
This finite result does not dismiss the earlier 16.43 s versus 4.30 s debug geometry
suite observations, certify pathological dense scenes, or establish native
interaction latency. One existing folded route reports NoClearPath in every
variant: completing a fast call is not proof it found a clear route.
## Quality and invariants
| Case | Pairwise shared length: released / J / L | Proper crossings: released / J / L | Raw point contacts: released / J / L |
| --- | --- | --- | --- |
| Workshop original | 1042 / 1074 / 602 | 6 / 5 / 5 | 22 / 23 / 23 |
| Workshop folded | 1096 / 1096 / 1096 | 7 / 7 / 7 | 20 / 20 / 20 |
| Mixed dispatch | 132 / 132 / 132 | 0 / 0 / 0 | 5 / 5 / 5 |
| Mixed IDs reversed | 132 / 233.5999756 / 233.5999756 | 0 / 0 / 0 | 4 / 5 / 5 |
| Forty-function sparse | 496 / 372 / 372 | 24 / 25 / 25 | 32 / 31 / 31 |
L removes 440 shared units from the workshop, but estimated label/node collisions
increase 11→12 (J: 13), label/stroke intersections 5→6, route length 5744→5768 and
drawing area 786620→799376. J increases workshop sharing by 32 despite reducing
proper crossings by one. Sparse sharing improves 124 under both candidates while
adding a proper crossing; estimated label/node collisions remain 70. The ordinary
mixed case is unchanged. Under the fixed semantic edge-ID reversal, both
candidates add 101.5999756 shared units relative to released routing. Released
routing itself changes two of fourteen route polylines under permutation;
J/L change four. No favorable edge order was chosen after observation.
All variants preserve frozen Rust model values, projected nodes/ports/edges,
semantic-port tips and authored constraints, with exact canonical JSON/source
round trips. No new missing route, nonfinite coordinate, edge/node penetration,
node collision identity or per-edge warning was observed. The folded scene
retains four PromotedEndpoints warnings plus one NoClearPath on the fourth edge;
these are recorded, not masked or called successes. Four promoted owner pairs
are independently identified. Its saved Project has no authored routes, so this
does not prove suspension/restoration of nonempty folded pins.
The [independent contact review](contact-review.md) confirms all 60 metric
comparisons across fifteen geometry observations using separate axis arithmetic.
It retains raw proper/T/bend/endpoint contacts and shared intervals, including
common semantic terminals. Six mixed-case authored waypoint passages and 498
mixed/sparse semantic endpoint tips agree. This is geometry evidence, not glyph,
port-label, arrowhead, native trace-task or editing acceptance.
The initial analysis reported six full-Project mismatches: five numeric leaves
per mixed Project, repeated across the three routers. Direct Project JSON writes
short f32 decimals, whereas `json!(Project)` through serde_json::Value expands
them to f64 decimals. Only PortAnchor.offset and EdgeLabel.fraction differ,
at 0.3/0.4/0.6; all thirty leaves have identical binary32 bits. V2 compares exact
bits only at these explicitly typed schema paths; every other field remains
exact, with changed-field and adjacent-f32 negative checks. Original failed
analysis, script and receipts remain unchanged. The independently reviewed v2
analysis has zero failed checks; this is not an aggregate quality acceptance.
The new record supplements the prior [nine-fixture comparison](../auto-layout-20260925/results-lanes.md).
## Consequence and reproduction
The [decision review](decision-review.md) supports retaining released routing.
Stop this fixed comparison without further parameter tuning. Preserve J/L as
diagnostic alternatives; reopening adoption requires demonstrated named trace
task improvements without new ambiguity and appropriate native/runtime evidence.
The separate reset candidate addresses stale authored constraints with the
released router; connection-aware node arrangement, label quality and complete
Arrange acceptance remain open in issue 32.
From each identified build commit, using the recorded Windows toolchain:
```text
cargo build --release --locked --offline -p oa-core --example routing_cost_probe --example auto_layout_probe
target/release/examples/routing_cost_probe.exe harness/experiments/routing-independent-20260925/corpus/manifest.json
target/release/examples/auto_layout_probe.exe --route-corpus harness/experiments/routing-independent-20260925/corpus/manifest.json
```
Preserve each executable before switching source, and run the fixed interleaved
order without compilation. The protocol requires an external 90 s per-process
timeout because the internal 5 s censor is checked only after a call returns.
Portable analysis scripts, original outputs, build receipts, corrected and
failed analyses, source/configuration inventories and archive-member hashes are
in [evidence/manifest.json](evidence/manifest.json). Local absolute paths in raw
receipts identify this machine; peers must build from the linked commits and
use their own filesystem/toolchain setup. No local path is a shared artifact.
@@ -0,0 +1,15 @@
# Route-only timing protocol v1
Parent execution order fixed before any outputs: preserve optimized binaries for released router source715036e, target-join J08656b18, and lanes L e8ec6db in a common harness. Run released, J, L, then L, J, released, with one complete corpus invocation per slot. Do not overlap compilation or other evaluator processes with timed execution. External timeout is90 seconds per invocation; retain partial output and explicitly mark missing cases if it expires. One separate untimed geometry invocation per variant uses `auto_layout_probe --route-corpus MANIFEST`. No new layout or router parameter tuning is part of this comparison.
Prepared example: `crates/oa-core/examples/routing_cost_probe.rs`. No execution, compilation or formatting by its author. Parent owns optimized builds, corpus and runs.
Invoke a preserved **release/optimized** binary as `routing_cost_probe.exe <absolute-manifest.json>`. No rounds override: every case uses one timed warmup followed by seven timed measured calls. External manifest is `{ "schema": 1, "cases": [{ "name": "unique-name", "project_file": "relative/project.json", "diagram": "UUID", "description": "fixture purpose" }] }`. Project files are direct serde Project JSON, validated before routing; paths resolve within the manifest directory. Cases run in manifest order.
Projection, decoding, validation and Project clone happen once outside timing. Each Instant interval includes only `route_diagram` and result black_box; inputs pass through black_box before the clock. Result destruction, equality, endpoint checks, digest and printing are outside. Allocation performed by routing remains included. Each repeat's complete RoutedView is compared to warmup, outside the clock; any mismatch is emitted then exits unsuccessfully. Project equality is checked against its initial clone. Endpoint equality is relative to the warmup, not a substitute for the independent semantic endpoint/quality evaluator.
JSONL starts with protocol metadata, then one record per completed/censored case with all measured nanoseconds, warmup duration, median, observed maximum, counts/warnings, stable route-point digest and checks. FNV-1a64 is a diagnostic identity only; use external SHA256 receipts for corpus, source, executable and runtime binding. Full RoutedView equality covers more fields than the point digest. Metadata reports debug_assertions but does not prove compiler optimization settings; the build receipt must do so. No environment secrets/configuration are printed.
If warmup or any sample exceeds five seconds, finish that call, stop remaining repeats for that case and mark it censored. Median is null for censored/incomplete series; maximum is only of observed measured samples, possibly null. The threshold is not a timeout: a hung call still requires external process supervision. A warmup-only censored case has no repeated stability evidence. Process failure may leave only partial JSONL; never interpret missing cases as zero cost or successful completion.
Warmup is retained so cache-sensitive first-call behavior remains visible, but one warmup does not prove steady state. Retaining its RoutedView and the original Project adds constant memory pressure across variants; repeat comparisons may influence caches between calls. Measure the same frozen corpus with interleaved preserved binaries for base/J/L variants on one machine, using the same release toolchain/profile, runtime, machine load and manifest order; do not compare dev versus release or include compiler time. Repeat entire interleaved sessions when a difference is close to noise. Seven samples characterize this run, not a latency distribution or statistical guarantee. Pair timings with the parent's independently calculated geometry/quality vectors; faster routing alone is not acceptance.
@@ -0,0 +1,15 @@
# SCC conservation review — corrected run02
Source `2426d286483ab0445663221cd6010a3dadb89a97`; all14 cases supported. Independent Python-only raw-Project audit passes every reconstructed conservation/minimum/enclosure check and all38 receipt file hash/size bindings. No Rust, compiler, routing or GUI execution by reviewer. Original run01 script, failure record and review remain untouched.
All13 previously successful complete after-Projects **and complete metric objects are exactly equal** to run01. The newly supported `two_containers_reversed_children` has roots at(40,40) and(494,40), each stored308×446; children at(72,136),(72,300),(526,136),(526,300), each stored224×94. Final projected child heights132 leave valid32left/96top minimum padding; final root projection matches308×446.
Independently evaluated the new conditional restoration, rather than allowing arbitrary size changes: these are noncollapsed, unported, ordinary parents whose original projected minimum is308×446. With original authored size and the final child geometry, core's24-unit side/footer and64-unit header enclosure would produce280×416 at the exact same position. The supplied unchanged effective minimum therefore requires explicit stored restoration to308×446. Both parents satisfy this condition; no other previously passing Project changes. This closes the recorded single-case transfer defect, not a new SCC-policy improvement.
The complete expected Project retains semantic records, other diagrams, authored anchor arrays, identities/order and all nongeometry fields. Three eligible authored routes reset as in run01. Folded workshop's three latent descendants still independently follow their actual Allocation/semantic ancestor by(-680,0), with expanded sizes retained. No dormant/promoted authored-route translation or nonempty attachment coverage is present; do not infer it from the policy code.
All14 records report exact same-input output, exact calls2–10 against both first and previous, and exact JSON/single-source round trips. These are recorded Rust checks; repeated full Projects and source strings are not serialized for independent reconstruction. Exact intended node plans remain a source-gate assertion: the audit checks emitted final geometry against permitted full-model changes/minima/enclosures, not an independent SCC-packing implementation. No native quality or production acceptance follows.
Standalone checker `audit-scc-conservation-v2-20260925.py` SHA256 `66a1621ac04e73bf08637047ed623c7154c0219a3076be7246004e6bf134d4e2`; result `scc-conservation-audit-run02-20260925.json` SHA256 `2897af5f3d131e2633a8dc5c9385307516c7c4db227349b374d4d062423a425e`. Both are under `.local`.
Invocation: `python audit-scc-conservation-v2-20260925.py .local/scc-placement-20260925/run02 NEW_OUTPUT_JSON 2426d286483ab0445663221cd6010a3dadb89a97 .local/scc-placement-20260925/run01`. Expected source pin is mandatory and output refuses overwrite.
@@ -0,0 +1,17 @@
# Independent SCC Project-conservation review
Read-only arithmetic/JSON audit of `.local/scc-placement-20260925/run01`, source `4dd764fa6cfc6920350383e523ba5a597412ddf4`. No Rust/compiler/router/GUI rerun. Auditable standalone Python checker: `audit-scc-conservation-20260925.py` SHA256 `7ebe5726c49c0918a9fbd55f74e16cac484ccec9d13f9cada7a7b36672ff1035`. Final machine result `scc-conservation-audit-final-20260925.json` SHA256 `c9156b710323d940a712ca8973a2e823a422faf96ad9c509193968ecf2f7fdd9`.
All14 cases accounted for:13 supported; `two_containers_reversed_children` rejects with `Final Rust projection differs from intended node geometry`. Its absence of an after-Project prevents conservation/enclosure/repeat checks; this is unsupported coverage, not a passed case. Read back38 receipt bindings with exact byte sizes/hashes; no mismatch.
For every supported case, independently reconstructed the entire expected Project from before-Project, final emitted projected positions/effective dimensions, actual semantic endpoint-owner placements, preoperation visible non-promoted edge eligibility and original route records. Compared the complete structure exactly, rather than trusting conservation booleans. All pass. Only declared target placement geometry and three eligible authored route resets change: mixed, reversed mixed, and authored_detour_and_label. Route entry identities/order and remaining fields are retained. All semantic records, other diagrams and authored port-anchor arrays remain exact. Projected identity/visual-parent inventory and frozen minimum sizes remain valid. Existing effective dimensions retain authored stored sizes; compact collapsed dimensions retain expanded stored sizes.
The folded workshop supplies actual latent movement: Rescue response, Send advice and Assess incident each translate by(-680,0) with collapsed owner `75920e7a-4586-58b7-9eb2-7e0a3d8a1825`. This was independently recovered through source Allocation/role/per-leaf performer and semantic ancestry relationships, not inferred merely from equal observed deltas. All hidden sizes/metadata remain exact. Supported final child enclosures satisfy left/right/bottom32 and non-State top96. This does not test State-specific header geometry.
All13 supported records report same-input exactness, nine repeat comparisons for calls2–10 equal both previous and first, and exact JSON/single-source round trips without errors. Those flags originate in Rust: repeated full Projects and source strings are not serialized, so this audit does not claim independent reexecution of them. Exact intended PlacementPlan nodes are also absent; the source final-reprojection gate checks that relation. This audit independently validates allowed full-Project changes, minima and enclosures using the emitted final projection, not a separate derivation of the SCC packing output.
No surviving dormant/promoted authored routes occur in supported fixtures; retained-route equal-delta translation and nonempty authored attachment cases therefore remain unexercised here. They must not be claimed from the checker implementing that policy. No quality, native workflow, full-router success or production adoption follows from conservation.
Audit development truth: initial local JSON reported one folded mismatch because the Python enum reader omitted unit-string bodies such as `{"Sa":"Function"}`. Inspecting the raw source established that checker defect; it was corrected before final assessment. Original JSON remains preserved, along with the intermediate v2 result. Final rerun additionally checks projected minima and visual-parent identity; all checks pass. No model or research source was edited.
Reproduce with Python only: `python audit-scc-conservation-20260925.py RUN_DIRECTORY NEW_OUTPUT_JSON`. Output creation refuses overwrite. Input strings are explicitly UTF-8; the checker invokes no application binaries.
@@ -0,0 +1,43 @@
# SCC placement: independent pre-result criteria
2026-09-25. Proposed experiment criteria for issue32, not production acceptance. Read `connection-corridor-sharing-diagnosis-20260925.md` and the previous placement/clearance findings. Research HEAD at inspection is `ae9dad54b749201c988fc398dbbc580db43e746f`. No new candidate source was reviewed for this record; author was asked to signal readiness. No compiler, router, engine or GUI execution.
**Proceed with one bounded SCC-condensation placement experiment, but make the planning graph and its relationship to authored containment explicit.** The observed native prototype interleaves four10-node sparse SCCs across16 ranks; moving to component-aware ordering directly tests that diagnosis. A compact perimeter is a falsifiable packing choice, not a consequence of SCC membership: strongly connected graphs are not generally simple cycles and need not have a crossing-free perimeter drawing.
## Material design risks to settle before results
1. **Do not confuse a hierarchy quotient with the actual connection graph.** At a containment level, mapping endpoints onto child/subtree representatives can introduce a proxy cycle even when underlying leaf connections are acyclic. Conversely, running independent leaf SCCs inside each parent can miss a real cycle crossing two containers. Preserve authored parent relationships; never reparent semantic nodes merely to make an SCC into a box. Record the exact vertices and mapped edges used for each SCC calculation, including planning parent and representative mapping. Call quotient components local placement blocks when appropriate; do not claim they prove global semantic SCC coherence.
2. **Perimeter order is a separate decision.** A component with ten vertices has many possible circular orders. An alias order or DFS order can recreate long backward edges, crossings and shared outer corridors, even after rank stretching disappears. Freeze a deterministic order before outputs, keep the edge-ID permutation, and disclose which connection information determines internal order. Do not rotate/reverse individual cases after seeing results. Singleton, two-node component and self-loop handling must be explicit; no duplicate placement at a repeated perimeter corner.
3. **Undirected means no authored direction.** An undirected relation can inform adjacency/proximity, but must not silently acquire a semantic arrow to satisfy the SCC algorithm. If treated as two directed adjacency arcs, state that it intentionally merges connected regions into placement blocks and may hide the directed condensation structure. If excluded from directed rank/SCC formation, keep it in geometry/quality evaluation and describe that weaker influence. A deterministic geometric orientation is another possible policy, but must remain a placement-only preference. Do not repeat the previous workshop omission without reporting unsupported cases.
4. **Local label gaps still have to cover actual routes.** A gap computed for one rank boundary does not guarantee space for long edges, perimeter return paths or the final Rust label location. Keep the released renderer/router as the observation source. Do not persist computed bends/label overrides or change the cutoffs to improve this comparison. Estimated label bounds remain a planning approximation; actual text and association require later native review.
## Preservation and projection gates
Use original visible placement identities and the actual projected forest, not semantic element IDs alone. Preserve complete authored containment, semantic endpoint/port identity, direction, names, relation data, filters, fold flags, entry order and other views. Freeze reset eligibility from the pre-operation projection; use the existing audited original-to-final import/reset/retained-route translation exactly once. A no-position-change result may still perform the declared route reset and must be reported accordingly.
For a visible collapsed node, retain its compact projected dimensions exactly and preserve stored expanded size. Treat it as opaque for packing. Its promoted visible edges can influence placement without turning promoted owners into actual semantic owners. Hidden descendants follow the importer's nearest visible collapsed ancestor translation; never use local compact coordinates as their expanded geometry or relayout them secretly. Ineligible/folded route metadata remains stored with the existing translation policy, ready for expansion. Unrelated filtered/out-of-projection placements remain governed by the declared import scope. The frozen folded workshop has no nonempty authored-route sentinel: preservation there alone cannot prove suspension/restoration of arbitrary hidden pins.
Expanded containers must contain their final projected children below the appropriate header and above any footer/port-content requirement. Use the core geometry minima for the applicable projection rather than universal64-unit assumptions for all kinds. Growing a container may change relative port tips, port spacing and automatic sides; recompute the actual final projection. Final-size constraint disagreement is a failure, not a reason to overwrite anchors. Check finite positions/sizes, no illegal shrink/overlap, complete projected IDs, and exact intended versus final node geometry.
Authored port anchors and dormant explicit attachments remain exact. Automatic port-side/slot changes are geometric outputs, not automatically conservation failures. Record every change and inspect the final mandatory leads. Repeated projection/packing must not cause side or size oscillation. A lead-incompatibility rejection is useful but necessary-only: final routing must still be checked for NoClearPath, warnings, unrelated node/header penetration and identity-specific collisions.
## Falsifiers on the fixed comparison
Keep all five frozen realistic cases and all nine existing small fixtures. Report unsupported/failed cases separately from outputs; never silently substitute a flattened or unfolded version. Keep the same reset baseline and unchanged released routing, and preserve the old prototype and prior external placements as references. New fixture construction or parameter selection must not be driven by these outputs.
- **Structural diagnosis:** for sparse40, independently recover the four10-node actual SCC memberships and relate them to placement blocks. Report each component's bounding span and its condensation rank interval. A proxy implementation that still interleaves those flat components or spreads a component over unrelated global ranks does not test the proposed remedy correctly. Mixed's six-node SCC and four singletons are a second independent topology check.
- **Dominant ambiguity:** recompute pairwise interval multiplicity on the final drawing. The sparse y28 trunk contributed38880/40522 and mixed y28 contributed4006/4228. Track the same edge groups wherever they move, as well as the new global worst corridor. Removing occupancy at literal y28 while recreating comparable sharing on another boundary is not success. Report unique corridor length, distinct-edge multiplicity and raw pairwise sharing separately; do not reinterpret a distinct-port trunk as an intentional bus.
- **Tradeoffs:** report proper/T/bend/endpoint contacts, nonterminal sharing, every new/resolved label/node and label/stroke conflict, route length/bends, drawing bounds and warnings. A compact arrangement that reduces area but increases ambiguous contacts is a tradeoff, not a quality pass. A large area gain bought with unreadable label packing is also a failed hypothesis. No weighted total determines adoption.
- **Compound capability:** the original/folded workshop must receive an actual declared supported result or explicit refusal. For supported compound cases, independently inspect child/header containment, port/edge promotion and hidden metadata. Passing flat sparse/mixed does not establish this milestone's hierarchy objective. The earlier two-container crossed-child fixture is useful here: check whether block order and child order cooperate rather than simply aligning container centers.
- **Port/lead compatibility:** preserve fixed-port fixture anchors and original opposing-side meaning; do not solve the task by moving an authored port. Final absence of incompatible leads must be followed by the normal full-route warning/penetration gate. Reject a new hard routing failure even when aggregate sharing decreases.
- **Repeatability:** same input yields identical Project; ten repeated candidate calls should settle after the first accepted arrangement, with no cumulative size inflation, shifting origin, side oscillation or hidden-coordinate drift. Keep mixed's fixed relation-ID permutation and semantic correspondence. Identical pixels are not required for every graph symmetry, but new failed trace tasks or severe order sensitivity cannot be hidden by selecting favorable IDs.
All14 cases need complete accounting. The small fixtures are explanatory witnesses, not training examples whose success compensates for realistic failures. Bound component recursion, graph/work/span, and any reprojection iterations; unsupported topology and bound exhaustion must discard the private candidate without partial model changes.
## What would justify the next step
A useful result would show that coherent components materially reduce the diagnosed long shared corridors on both sparse and mixed cases, without a new hard route/containment/identity failure, while producing explicit compound results. This would support further initial coordinate-assignment work. It would not yet establish readable engineer traceability or a generally optimal planner.
If actual SCC blocks become compact but long return paths still coincide, inspect internal cycle ordering and available local corridors from that fixed output before proposing another scalar router penalty. If compound quotient cycles or final-port/lead requirements prevent a faithful placement, the failure should revise the planning interface rather than force a proxy result into the Project. Do not increase iteration limits, choose a winning rotation, or add a second packing heuristic after results merely to make this corpus pass.
Before adoption, reuse the predeclared source-to-target and label-association tasks at a common readable scale with ordinary selection/pan/zoom recorded. Include fan-out, distinct ports, cycle return and promoted endpoints. Geometry improvements, even across every frozen case, do not replace that native evidence or production history/source round trips.
@@ -0,0 +1,62 @@
# Connection corridors: next bounded #32 experiment
Decision after ae9dad54: **test jointly assigned derived separation of existing orthogonal routes on a fixed placement**, before another placement-only spacing algorithm. Keep it an isolated geometry experiment. Do not integrate it into Arrange or change the released router until the named tracing witnesses and preservation checks pass. A small shared-run separator can test an actual missing mechanism; a new set of node gaps cannot ensure that the existing router consumes those gaps.
No external claims, source changes, builds, routing runs or GUI work underpin this note. Sources are the current research routing/projection code, `auto_layout_probe/layered.rs`, and the frozen connection-layout / placement-clearance experiments.
## The decisive limitation
There is no proof that *no* placement-only method can improve shared routing: the mixed ELK placement did improve it through the released router. The stronger assumption that reserving distinct empty corridors in node placement **enforces** distinct routed lanes is false under the present interface. `RoutingSpace::new` uses obstacle boundaries; `fast_path` builds direct/one-axis alternatives; `crossing_cost` only gives coincident spans a soft cost. No placement result carries edge-to-corridor membership into routing. Two connections may still choose the same shorter trunk regardless of how much unused space was reserved elsewhere. The old layered prototype illustrates the practical risk: huge sparse/mixed shared runs despite larger gaps. The clearance repair proves terminal compatibility but sparse sharing666→761 and crossings20→22 prove that compatibility is not lane allocation.
This is not a reason to adopt an entire new engine. It is a reason to test a route-space operation whose output is actually used, rather than interpreting free space as an edge reservation.
## Material options
| Approach | What it can directly control | Unresolved failure / cost | Choice |
| --- | --- | --- | --- |
| Initial coordinate assignment with distinct connection corridors | Node order, available width/height and containment; avoids known stub incompatibility. | Without route-to-corridor constraints, released routing may ignore all lane distinctions. Adding such constraints is already a joint placement/routing interface. Global per-edge spacing can explode area. | Necessary later for insufficient corridors; not the next isolated experiment. |
| Joint derived route separation after an initial route | Actual connection strokes, with fixed tips/stubs and obstacles. Can distinguish coincident nonterminal trunks without moving nodes or changing semantic ports. | Must handle order conflicts, route topology, turns, labels and insufficient clearance; careless nudging creates collisions or touches. | Preferred next bounded diagnostic. Preserve topology and refuse difficult bundles instead of silently forcing them. |
| Improve rank/order using virtual long-edge vertices | Adjacent-layer crossing order and space occupied by edges skipping ranks; fixes a real limitation of the current prototype's node-only incoming-neighbor means. | Straight-line/layer crossing reduction is not a guarantee about orthogonal trunks chosen by the independent router. Feedback/undirected/compound edges need policy. | Next placement improvement if fixed-route separation establishes that enough useful free space exists; do not present it as a direct shared-run fix. |
## Concrete experimental interface and lifecycle
One example-only function: `separate_routes(project, diagram, final_view, original_routed) -> Result<RoutedView, Diagnostic>`. Borrow the Project and view; return only derived geometry plus explicit moved-bundle/refusal facts. Initially require a flat, unfolded, complete projected scene, all relevant automatic routes free of authored pins, and no existing NoClearPath or unrelated-node penetration. The predeclared input set includes repaired sparse ELK, both mixed ELK orderings, and the small diamond/bipartite witnesses. Keep original routing as the paired control. No node geometry or anchor changes occur during this experiment.
Final automatic ports are already settled by projection. Their tips and full18-unit leads are fixed barriers/anchors for this operation, including shared semantic endpoints. Authored port anchors and explicit endpoint attachments remain exact. Protect common same-owner/same-port leads; do not require physically impossible separation of coincident terminal ink. Distinct ports must not be merged merely because coordinates coincide. Treat any authored pinned route as wholly fixed in the initial scope; defer partial between-pin movement. Preserve its label override. Generated bends must never be written to EdgeRoute.waypoints.
If later integrated, derive it every time `route_diagram` computes geometry from the current Project, not only immediately after Arrange. Otherwise Save/reopen or an unrelated redraw would lose the result. Preview must use the same derivation and respect cached unchanged routes or explicitly invalidate the appropriate bundle; that is an integration requirement, not work needed for the first example experiment. Arrange continues to commit only selected diagram presentation geometry and its existing eligible-route reset in one history transaction. Undo/Redo, other views, dormant/promoted route metadata and original-to-final translations retain their accepted behavior.
## Minimal bounded algorithm to falsify
1. From the frozen routed polylines, find positive shared **nonterminal** spans, grouped by orientation and overlapping longitudinal intervals. Split analysis intervals at segment endpoints; retain edge and original segment identity. No routing weights change and no new search grid is introduced.
2. For each small bundle, inspect the entire connected orthogonal run/turn chain that would move. Determine available transverse bounds from actual inflated obstacles, protected terminal leads and fixed routes. Assign a consistent edge order from branch attachments on both ends; if the two end orders conflict, mark unsupported rather than concealing an unavoidable crossing through arbitrary UUID ordering. Canonical semantic/placement ties are deterministic, with explicit relation-ID permutation sensitivity retained.
3. Solve all coordinates in that bundle together: neighboring tracks get a fixed declared separation, original coordinates are preferred, and adjacent perpendicular segments extend/shorten to meet the moved tracks. Do not independently move overlapping subsegments, which would produce broken routes. Any new connector needed near a protected stub is an explicit derived orthogonal dogleg, checked in full. First scope may simply refuse bundles requiring such a connector; record how many target witnesses are thereby unsupported.
4. Use a fixed small bundle/segment bound and one deterministic pass, followed by complete recomputation of geometric validity. No iterative tweak-until-metric-improves loop. If constraints lack room, either leave that bundle exactly original with an explicit refusal or fail the whole experiment according to the predeclared case protocol; never report it as repaired. Other bundles must not be treated as non-obstacles while solving, and later changes must not invalidate earlier separation.
5. Recompute automatic label placement on final paths using the same core label placement machinery. An example cannot honestly carry old bounds onto moved paths and call the resulting label metrics final. This is the main small core seam potentially needed beyond the example: factor the existing post-route label settlement phase for reuse, without changing its policy. If parent declines that extraction initially, retain labels as fixed obstacles and label the result geometry-only; it cannot pass label-aware Arrange acceptance.
This is a bounded parallel-segment constraint problem, not a whole orthogonal graph drawing framework. Avoid promoting a speculative reusable solver before one small bundle and one realistic scene demonstrate value. If the smallest useful bundle requires pervasive topology changes, stop and record that limitation; the next candidate is explicit corridor-aware routing coupled to placement, not hundreds of ad hoc bend exceptions.
## Finite evaluation and stop conditions
Use fixed geometry with an analytically separable two-route shared middle span and immutable terminal leads; a shared-port witness must retain its common lead while separating only beyond it. Include a too-narrow corridor (explicit refusal), opposite branch order (refusal or explicitly counted crossing), one fixed pinned route, and one real sparse shared-run bundle. Pair with diamond/bipartite and both mixed relation-ID variants already available. No parameter sweep.
Require exact Project, node geometry, semantic ports and endpoint tips/stubs; every output orthogonal; no new unrelated node/lead penetration, no lost hard pin, no newly introduced improper self-overlap/degenerate backtracking. Compare actual shared-run identities/lengths, proper and T/bend contacts, and label/stroke/label-node collisions after label settlement. The concrete user-facing target is tracing two formerly coincident connections from their branch points without an ambiguous shared middle run. A native trace task is still needed before adoption; an export diagram can provide review evidence but not replace interaction.
Success means at least the declared bundle and one realistic route-tracing witness separate with no new hard violation or label interference and a recorded acceptable path/area cost. A lower total shared length obtained by moving ambiguity to a different pair is failure. Idempotence means applying the separator to its own derived result makes no further change; Save/reopen recomputation from the same Project must match the original derived output. Do not claim full Arrange support: nested ancestor headers, folded promotions, undirected branch ordering and partial authored-pin routing are explicit later gates. Semantic direction is not invented for undirected edges; separator ordering derives from geometry and endpoints, and reversing an undirected edge must not change its physical lane assignment.
Stop after this fixed candidate is compared. If it only works by moving nodes, consumes excessive space, or fails the real witness because free corridors cannot preserve branch order, that is actionable evidence for a combined rank/order + corridor assignment planner. Virtual long-edge vertices then become part of routing constraints shared with coordinate assignment, rather than another placement proxy whose route result is assumed.
## Revision after grouped-sharing/SCC diagnosis
**Priority revised: SCC condensation with compact block placement is the justified next experiment; defer the joint separator.** This supersedes the initial next-action recommendation above, while preserving its alternatives and interface warning. New evidence is `connection-corridor-sharing-diagnosis-20260925.md` and its independently reconstructed interval/SCC data. The predeclared implementation contract is `harness/experiments/scc-placement-20260925/plan.md`.
The diagnosis resolves an uncertainty that my initial recommendation left too broad. Sparse has four ten-member SCCs interleaved over16 ranks;38880/40522 shared units (95.95%) occupy the same y28 outside corridor. Mixed has4006/4228 (94.75%) there. These are long stretched feedback/forward routes caused by incoherent component ranking plus aligned row boundaries and globally inflated gaps, not primarily the small local lane collision exhibited by repaired ELK geometry. A joint separator would treat a large structural symptom while retaining avoidable rank spans. Coherent condensation order and compact SCC membership directly change the implicated cause with the released router unchanged.
The frozen plan is a meaningful distinct candidate: SCCs per actual sibling quotient, condensation DAG ranks, compact perimeter for cyclic members, local label gaps, explicit final projection/lead checks and no iterative rescue. It is more appropriate now than virtual long-edge vertices: dummy vertices can improve ordering across coherent ranks but cannot undo an incorrectly split/interleaved SCC rank assignment. Among block rows and a compact perimeter, the predeclared perimeter is a reasonable single hypothesis because it bounds cyclic-member extent and distributes turn opportunities; it is **not** a proven cycle embedding. A strongly connected group need not be one simple cycle, directed DFS successor order need not make every adjacent perimeter pair connected, and chords can still cross or share trunks. Do not describe the perimeter as an optimal cycle layout.
Specific plan risks to retain in evaluation: a minimum30-unit gap only addresses a particular facing-port clearance case, not all final automatic-port choices; nested quotient SCCs are not leaf semantic SCCs; undirected edges must retain direction-free treatment and still be observed for routing quality; fixed anchors can oppose perimeter flow; expanded/folded footprints and local-label estimates must not induce repeated size growth. The plan's explicit final reprojection failure and original-to-final import policy address these as boundaries rather than silently assuming success. Header/enclosure checks and ten-call stability are essential, as declared.
The decisive falsifier is not merely fewer global ranks. Require coherent condensation order, reduced component span and the diagnosed top-corridor contribution, with no new hard geometry violation or comparable ambiguity shifted to another axis/pair. Retain area, labels, contacts and actual named trace tasks. If the perimeter introduces another outside shared loop or rejects a real case because of mandatory leads, preserve that counterexample without parameter tuning. Then select long-edge ordering for rank/order failure, or joint derived separation for a genuinely local residual channel failure.
Nothing here proves placement alone always enforces distinct lanes: that earlier interface limitation remains exact. Nor does the diagnosis prove that a coupled router is necessary. It supplies a narrower, more causal and cheaper first experiment than the initial separator recommendation. No new run or implementation was performed for this revision.
@@ -0,0 +1,54 @@
# Corridor sharing diagnosis
Read-only UTF-8 analysis of frozen `elk-reference-20260925/rust-run03/arrange-corpus/stdout.jsonl` and `placement-clearance-20260925/run02/subsystems_40_sparse-elk/stdout.jsonl`. No engine/router/compiler/native execution. Full source hashes, grouped intervals, edge identities/names/endpoints/sides, largest pairs and independently reconstructed SCC/ranks are in `connection-corridor-sharing-groups-20260925.json` (SHA256 `f9114eaafa22f1d618783b4a62a570d24387645451aafc2123561b53ed16968f`).
## Main finding
**The dominant layered failure is rank stretching plus aligned obstacle-boundary corridors. SCC-aware placement is a more direct first controllable experiment than requiring a joint routing engine.** Routing channel choice contributes, but these records do not show that a coupled router is necessary. They also do not prove that any proposed SCC packing will improve the full metric vector.
Independent sweep: group all positive orthogonal segments by axis and fixed coordinate, split at every endpoint, count distinct edge identities on each atomic interval, and accumulate length × choose(edge count,2). This exactly reproduces all four raw shared-length totals. Edge contribution counts each incident pair once per edge, so summing contributions doubles the total; this is not unique physical ink length.
| Scene | Raw pairwise sharing | Horizontal | Vertical | Common-terminal excluded |
|---|---:|---:|---:|---:|
| Sparse layered |40522|39174|1348|0|
| Mixed layered |4228|4042|186|54|
| Sparse ELK placement + Rust |666|0|666|0|
| Sparse clearance repair + Rust |761|0|761|0|
All four scenes are flat: no visual parents or compound-header explanation. Sparse sharing is entirely nonterminal; mixed remains4174 after the54 common-terminal units. Shared endpoint ownership is not itself a common physical terminal: distinct port channels remain distinct connections.
## Sparse: five long routes crowd the same top boundary
At y28 alone, shared pairwise length is38880, 95.95% of40522. This is exactly the top y40 node row minus12 clearance. The dominant interval x1746..3926 has five edges over2180 units, contributing21800 pairwise units. Adjacent x3926..5878 has four edges and contributes11712; x1258..1746 has four and contributes2928. Thus a few continuous outside runs, not thousands of independent intersections, dominate the score.
Five edges on the largest interval:
- `flow_15` Assessment Decode to Validate: source x528,y40 Right → target x5896,y40 Left; total incident sharing17046.
- `flow_16` Assessment Validate to Enrich: x5896,y40 Left → x40,y220 Right;17890.
- `flow_41` Communications Decide handoff to Assessment Aggregate: x6384,y40 Left → x40,y428 Right;18676, the maximum contributor.
- `flow_42` Communications Publish handoff to Assessment Package: x7360,y40 Left → x1016,y220 Right;16590.
- `flow_46` Assessment Publish handoff to Planning Package: x1504,y40 Right → x3944,y40 Left;8720.
These are distinct semantic ports, not a legitimate shared bus. Both forward long edges and backwards edges use the same corridor. Automatic side selection follows the stretched final geometry; sparse has no authored anchors to explain those choices.
Independent directed reachability finds **four SCCs of10 nodes**, not one40-node SCC. Reproducing the prototype's alias-ordered cycle breaking yields16 global ranks and exactly the observed x positions40,528,…7360 (488 pitch =224 node width +264 global gap). SCC members span ranks0..9,0..12,0..13 and2..15: components are interleaved and stretched rather than treated as compact units. Cycle breaks are Assessment Acquire, Assessment Aggregate, Assessment Enrich and Assessment Package. Source `layered.rs::ranks` breaks the first canonical remaining vertex even if an upstream SCC is still cyclic; later longest-path assignment uses already assigned predecessors. Thus even edges between different SCCs can become long backward connections in the resulting global order.
The global horizontal gap is derived from the maximum estimated edge-label width plus24, rather than local edge needs. It multiplies the cost of long rank spans. Three incoming-neighbour ordering passes only sort existing ranks; they cannot repair rank assignment, and do not introduce virtual vertices for long edges. Source `place` starts each rank at the same top y40, supplying a common outer obstacle boundary. This chain explains the geometry without attributing the entire problem to a routing coefficient.
## Mixed: same mechanism at smaller scale
Mixed has one6-node SCC plus four singletons. The SCC spans ranks1..6; the whole graph uses seven ranks with474 pitch (224+250 global gap). Cycle breaks Actuator, Archive and Correlate include an initially blocked singleton, again showing that canonical cycle breaking is not condensation-DAG ordering.
At y28, three dominant routes contribute4006/4228 (94.75%). Interval x1230..2178 carries `flow_04` Validated observations, `flow_08` Actuator dispatch and `flow_10` Operator acknowledgement:948×3=2844. Another948-unit interval carries dispatch/acknowledgement; the final214 units carry validated observations/acknowledgement. The largest contributor is acknowledgement3212; dispatch2892, validated observations2110. Unlike sparse, Dispatch's Right port is authored, so any future layout must honor that side rather than solving the overlap by changing its anchor.
## ELK and repair are a different, local channel issue
The666→761 increase has no horizontal sharing. Largest unchanged interval is x8517,y938..1030: three edges (`flow_12`,`flow_17`,`flow_38`) contribute276; this is18 units left of target-column x8535. Some terminate on different ports of Communications Package; another targets Assessment Aggregate, so the full interval is not common-terminal reuse.
Exact pairwise delta decomposition: `flow_19/flow_42` gains152; `flow_30/flow_51` loses11; `flow_50/flow_53` loses57; `flow_29/flow_48` gains11. Net95. The new152-unit channel is x4504,y526..678, again18 units left of x4522. This is a side effect of changed placement and derived rerouting after clearance repair, not persistence of the huge layered top trunk.
The released router processes routes sequentially and uses a soft collinear penalty min(overlap×0.12,80) per occupied segment; this is not a global no-sharing allocation rule. That source fact explains why channel reuse remains permitted, but does not establish why every alternative was rejected or that changing the penalty is the right solution. No cost tuning follows from this diagnosis.
## Next falsifiable comparison
Freeze these same input graphs and unchanged released routing. First compare an SCC-condensation ordering with explicit local packing/feedback treatment against the current alias cycle break. Preserve semantic ports/anchors and evaluate actual reprojection, rank span, backwards-edge span, shared interval multiplicities, crossings, labels, area and leads. Failure to reduce the y28 corridor without trading it for comparable hidden contacts/area falsifies the proposed structural benefit. A separate long-edge virtual-vertex ordering experiment is meaningful after ranks are coherent; it cannot by itself repair the present stretched SCC assignment. Local channel allocation can then be evaluated for the residual ELK/repair vertical runs at fixed geometry. Neither stage should be declared necessary or successful before measurement.
@@ -0,0 +1,851 @@
{
"schema": 1,
"source_commit": "2426d286483ab0445663221cd6010a3dadb89a97",
"archive": {
"file": "scc-placement-2426d286.zip",
"bytes": 6041259,
"sha256": "fbf40882ed807a1b40db8b3b9b9c846b060db02cbcc60611c18f9620c1fd59c9"
},
"members": [
{
"member": "collector/archive-scc-placement-20260925.py",
"bytes": 3887,
"sha256": "bcf1910bd5110c3c14c5bf4dd612fd65d2c686f8d9a5d45405b58ec7c5b1b486"
},
{
"member": "collector/run-routing-corpus-check-20260925.py",
"bytes": 2793,
"sha256": "2726a397bd4ecb4dcfff6fc170a66ce2655229079f42335faa2a4bfe4a202f6d"
},
{
"member": "collector/run-scc-placement-20260925.py",
"bytes": 3628,
"sha256": "40c33c2703768eaa512553322ccc628fbdc3630c2968c4cc8ce127a6c6714757"
},
{
"member": "collector/write-scc-results-20260925.py",
"bytes": 9848,
"sha256": "ad2ea7ac903f5557c2e5d522d04ea0a589b991ed3ca7c0840ec40d04d42d38ef"
},
{
"member": "gates/18-scc-example-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/18-scc-example-tests/command/context.json",
"bytes": 3505,
"sha256": "a38ff5f35a5578eb37f41bf2b6487634813861025bc3ad4d125251605f223a12"
},
{
"member": "gates/18-scc-example-tests/command/inputs-after.json",
"bytes": 1755092,
"sha256": "9e23948f6a23224909279ed38c366f45ff472aaf7c3dd94be74b5cd8ea3637e7"
},
{
"member": "gates/18-scc-example-tests/command/inputs-before.json",
"bytes": 1755092,
"sha256": "9e23948f6a23224909279ed38c366f45ff472aaf7c3dd94be74b5cd8ea3637e7"
},
{
"member": "gates/18-scc-example-tests/command/output.log",
"bytes": 440,
"sha256": "3510acc240220b72c1269b9b927656cd426fc4d62c975d96d13d50889e245943"
},
{
"member": "gates/18-scc-example-tests/command/result.json",
"bytes": 4168,
"sha256": "97d627584143e47a0bde6154edaaf403c07d248b60fc47cd3ffe1f6f8bb4f1e4"
},
{
"member": "gates/18-scc-example-tests/command/stderr.log",
"bytes": 336,
"sha256": "8e11399e5c28b4f0b364568f06d4922bfca59fb7b1dd0c4c73df3f88d60257ad"
},
{
"member": "gates/18-scc-example-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/18-scc-example-tests/orchestration.log",
"bytes": 180,
"sha256": "fdad0fe87d49b532b04b2612c3bde4f1a3114e12613189bb91952469bc635825"
},
{
"member": "gates/19-scc-corrected-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/19-scc-corrected-tests/command/context.json",
"bytes": 3507,
"sha256": "6030b5f305c844259023aae178f5cc99ec8d6af4b45582f2e333fc52a4061a00"
},
{
"member": "gates/19-scc-corrected-tests/command/inputs-after.json",
"bytes": 1755092,
"sha256": "53a042b82d8a6ce79de30e6bc6cfdc71f32e7762a82373ce1315423b5e5eae39"
},
{
"member": "gates/19-scc-corrected-tests/command/inputs-before.json",
"bytes": 1755092,
"sha256": "53a042b82d8a6ce79de30e6bc6cfdc71f32e7762a82373ce1315423b5e5eae39"
},
{
"member": "gates/19-scc-corrected-tests/command/output.log",
"bytes": 536,
"sha256": "833b6716dd2533562e8faa1062259da5b4d3ba2ebd89cd67393900b97b4c739c"
},
{
"member": "gates/19-scc-corrected-tests/command/result.json",
"bytes": 4174,
"sha256": "d6905113e765158dbfb9cbfb4c87f6c8eff7f36337a2e7b2845b5d51ef72ee71"
},
{
"member": "gates/19-scc-corrected-tests/command/stderr.log",
"bytes": 336,
"sha256": "4c991e05c9de1d64fd1747c686af26eec1f97a27c3626001fd900de70b60fa6b"
},
{
"member": "gates/19-scc-corrected-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/19-scc-corrected-tests/orchestration.log",
"bytes": 182,
"sha256": "314d9dd697a24da445f8e4533eb7b14197cdcff58d260b0a667fa9c0b00962b2"
},
{
"member": "gates/20-scc-clippy/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/20-scc-clippy/command/context.json",
"bytes": 3535,
"sha256": "3a999e9dd4d245bc01b9b264273e8525818b4892766deef6527bcdcd26c64e20"
},
{
"member": "gates/20-scc-clippy/command/inputs-after.json",
"bytes": 1755092,
"sha256": "53a042b82d8a6ce79de30e6bc6cfdc71f32e7762a82373ce1315423b5e5eae39"
},
{
"member": "gates/20-scc-clippy/command/inputs-before.json",
"bytes": 1755092,
"sha256": "53a042b82d8a6ce79de30e6bc6cfdc71f32e7762a82373ce1315423b5e5eae39"
},
{
"member": "gates/20-scc-clippy/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/20-scc-clippy/command/result.json",
"bytes": 4184,
"sha256": "b8aec050f2e1b5074717edede43ff3acfb3f42d251376e54fa116b16c09b47c9"
},
{
"member": "gates/20-scc-clippy/command/stderr.log",
"bytes": 830,
"sha256": "836381446c6b5aa7b0d0bd4e1321375595cf6f4001390e37c6042a3ae8a8ccbc"
},
{
"member": "gates/20-scc-clippy/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/20-scc-clippy/orchestration.log",
"bytes": 175,
"sha256": "82805760283baab8da36de90c204a723f71d90e00eb33d6cab99f58c9e89053c"
},
{
"member": "gates/21-scc-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/21-scc-tests/command/context.json",
"bytes": 3497,
"sha256": "e2ab8c21c637919f4e8d6e2d1ecea96289165bacdc468b8b0dd870977c6193d7"
},
{
"member": "gates/21-scc-tests/command/inputs-after.json",
"bytes": 1755092,
"sha256": "3c16e04dbe3215742da10626cd465e68cf32ccb7685b2bc5ab084548e70c30cb"
},
{
"member": "gates/21-scc-tests/command/inputs-before.json",
"bytes": 1755092,
"sha256": "3c16e04dbe3215742da10626cd465e68cf32ccb7685b2bc5ab084548e70c30cb"
},
{
"member": "gates/21-scc-tests/command/output.log",
"bytes": 536,
"sha256": "833b6716dd2533562e8faa1062259da5b4d3ba2ebd89cd67393900b97b4c739c"
},
{
"member": "gates/21-scc-tests/command/result.json",
"bytes": 4144,
"sha256": "5611dc41970a0f2ca240a7bd32aa8261851b05026a6df1ad85dcb0ce26735ebd"
},
{
"member": "gates/21-scc-tests/command/stderr.log",
"bytes": 336,
"sha256": "4eb583fbb1c6eb53b6fd0a17ef6a8faef02c5e5a678459d78ff101dc597db837"
},
{
"member": "gates/21-scc-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/21-scc-tests/orchestration.log",
"bytes": 172,
"sha256": "ecfa25a2732e5b5f2c7e9cf457de494dd89c43e8ba64d2caffebef38ef288185"
},
{
"member": "gates/22-scc-clippy/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/22-scc-clippy/command/context.json",
"bytes": 3535,
"sha256": "7641413d4d7712c0a1070e9634cd8b28bcc7f827c225ebda55aac45ce9208da0"
},
{
"member": "gates/22-scc-clippy/command/inputs-after.json",
"bytes": 1755092,
"sha256": "3c16e04dbe3215742da10626cd465e68cf32ccb7685b2bc5ab084548e70c30cb"
},
{
"member": "gates/22-scc-clippy/command/inputs-before.json",
"bytes": 1755092,
"sha256": "3c16e04dbe3215742da10626cd465e68cf32ccb7685b2bc5ab084548e70c30cb"
},
{
"member": "gates/22-scc-clippy/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/22-scc-clippy/command/result.json",
"bytes": 4182,
"sha256": "39395b4dcf3c66f3e490cd6bb4d2fa8f4ac40ba5ffd46708287f9012cd9b61a9"
},
{
"member": "gates/22-scc-clippy/command/stderr.log",
"bytes": 176,
"sha256": "7be90bc986d32ae1b1f4bf7e877bbcb73389e60288af76e6af2b6626e8cd2626"
},
{
"member": "gates/22-scc-clippy/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/22-scc-clippy/orchestration.log",
"bytes": 173,
"sha256": "3ff1bf85e86dabef766aad475314f4134a0cf663887bb74785ed8373b536b5ae"
},
{
"member": "gates/23-scc-release/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/23-scc-release/command/context.json",
"bytes": 3524,
"sha256": "a7f20125d78395643742fe1157d883f001d1d94e53697ca9c469ddb3340a7531"
},
{
"member": "gates/23-scc-release/command/inputs-after.json",
"bytes": 1755092,
"sha256": "3c16e04dbe3215742da10626cd465e68cf32ccb7685b2bc5ab084548e70c30cb"
},
{
"member": "gates/23-scc-release/command/inputs-before.json",
"bytes": 1755092,
"sha256": "3c16e04dbe3215742da10626cd465e68cf32ccb7685b2bc5ab084548e70c30cb"
},
{
"member": "gates/23-scc-release/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/23-scc-release/command/result.json",
"bytes": 4173,
"sha256": "3e5adf5bad50cacfdb02b10568d3699531e365380682fd247bc7e43df112b21a"
},
{
"member": "gates/23-scc-release/command/stderr.log",
"bytes": 179,
"sha256": "cd616b849f5be8e680183b2ec2fee33ca301a0151ddde93fcb2947a512bc287a"
},
{
"member": "gates/23-scc-release/environment.json",
"bytes": 9470,
"sha256": "1cda80470e5893747b1aad7eda5ef51d57069441e810698cd7f94f7a7521bfe5"
},
{
"member": "gates/23-scc-release/orchestration.log",
"bytes": 174,
"sha256": "bebcb80f84dc83fa0f718f41203fd3cdf52b70b2c7636fca4d1b432924c89d5f"
},
{
"member": "gates/24-scc-transfer-tests/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/24-scc-transfer-tests/command/context.json",
"bytes": 3506,
"sha256": "de2ae28d115235da55dd61bea562a752d982b27730ea30ebfecaee5aca972ecd"
},
{
"member": "gates/24-scc-transfer-tests/command/inputs-after.json",
"bytes": 1755092,
"sha256": "67557a240c92ce4b7d9395dccf4d8c783c95012b5ed04b3836e511117c34ae65"
},
{
"member": "gates/24-scc-transfer-tests/command/inputs-before.json",
"bytes": 1755092,
"sha256": "67557a240c92ce4b7d9395dccf4d8c783c95012b5ed04b3836e511117c34ae65"
},
{
"member": "gates/24-scc-transfer-tests/command/output.log",
"bytes": 810,
"sha256": "ada006a93f2d7512c1134d58dc3a163f1c3203e05812192ab267143979ba931e"
},
{
"member": "gates/24-scc-transfer-tests/command/result.json",
"bytes": 4171,
"sha256": "872ae3bfb6f724d53c3b82eb158df3bb402154ae3e8f08283c39b6256f84a915"
},
{
"member": "gates/24-scc-transfer-tests/command/stderr.log",
"bytes": 336,
"sha256": "f580a0e0f692d052343e2f196ee8b7506c89d0cf423ca1e261cc8388abbeaef6"
},
{
"member": "gates/24-scc-transfer-tests/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/24-scc-transfer-tests/orchestration.log",
"bytes": 181,
"sha256": "aa10d2e705dfe95b2a1aa57aaa630e474c98247216d85dc7011173ae2f86c1e8"
},
{
"member": "gates/25-scc-transfer-clippy/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/25-scc-transfer-clippy/command/context.json",
"bytes": 3544,
"sha256": "54ef12b091c100fe7e4dc15eb7f51160a4a30e8f3b716c021921c41acdc7df54"
},
{
"member": "gates/25-scc-transfer-clippy/command/inputs-after.json",
"bytes": 1755092,
"sha256": "67557a240c92ce4b7d9395dccf4d8c783c95012b5ed04b3836e511117c34ae65"
},
{
"member": "gates/25-scc-transfer-clippy/command/inputs-before.json",
"bytes": 1755092,
"sha256": "67557a240c92ce4b7d9395dccf4d8c783c95012b5ed04b3836e511117c34ae65"
},
{
"member": "gates/25-scc-transfer-clippy/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/25-scc-transfer-clippy/command/result.json",
"bytes": 4209,
"sha256": "7b037ce78415017a21577e32bda7c73b1658e222d53753cc00b53bf2ab74b510"
},
{
"member": "gates/25-scc-transfer-clippy/command/stderr.log",
"bytes": 176,
"sha256": "ec857d6226e95672a08768dfbd776562e3e9c329f9031c660c407d64edb1f452"
},
{
"member": "gates/25-scc-transfer-clippy/environment.json",
"bytes": 9466,
"sha256": "d9d984528a82c0db3c2e009db91104d7b7c1233921793802bbeb87677f35daf8"
},
{
"member": "gates/25-scc-transfer-clippy/orchestration.log",
"bytes": 182,
"sha256": "7fd6a5c356f4640a43faf5c91c01327f995a4d93f93c0a9b508ef6131a03c26d"
},
{
"member": "gates/26-scc-transfer-release/command/changes.patch",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/26-scc-transfer-release/command/context.json",
"bytes": 3533,
"sha256": "46588f276ededd1c28852659b30af3b13d074421a134106a0b75679f0a50d379"
},
{
"member": "gates/26-scc-transfer-release/command/inputs-after.json",
"bytes": 1755092,
"sha256": "67557a240c92ce4b7d9395dccf4d8c783c95012b5ed04b3836e511117c34ae65"
},
{
"member": "gates/26-scc-transfer-release/command/inputs-before.json",
"bytes": 1755092,
"sha256": "67557a240c92ce4b7d9395dccf4d8c783c95012b5ed04b3836e511117c34ae65"
},
{
"member": "gates/26-scc-transfer-release/command/output.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "gates/26-scc-transfer-release/command/result.json",
"bytes": 4200,
"sha256": "1e531e586f3ee85a502186662fa97cd67119229554edd46ccbc2175d4af36bdc"
},
{
"member": "gates/26-scc-transfer-release/command/stderr.log",
"bytes": 179,
"sha256": "c09d2543f7352e8fa827be3f41debe0d84b7fec666e8b2d27f3f4d0693a6a07a"
},
{
"member": "gates/26-scc-transfer-release/environment.json",
"bytes": 9470,
"sha256": "1cda80470e5893747b1aad7eda5ef51d57069441e810698cd7f94f7a7521bfe5"
},
{
"member": "gates/26-scc-transfer-release/orchestration.log",
"bytes": 183,
"sha256": "39f7e83972586ac72325f0a1a9275c778b92af4e05c412c216c32c108657caca"
},
{
"member": "inputs/corpus/manifest.json",
"bytes": 10593,
"sha256": "a58a6956e26b414e88fafd4fdb92e006050653a4149178f08df84128e3917717"
},
{
"member": "inputs/corpus/mixed_dispatch.json",
"bytes": 32787,
"sha256": "81d25af021cbad18af4262a220ba60372e51ca19083b7e80f2b19196baf05990"
},
{
"member": "inputs/corpus/mixed_dispatch_edge_ids_reversed.json",
"bytes": 32787,
"sha256": "25c95be6b6e7ad9ebcdc83aacc13fbbaa5a56651ba2843f8d1658c075ed789f8"
},
{
"member": "inputs/corpus/subsystems_40_sparse.json",
"bytes": 124043,
"sha256": "ad0ee7a0ab9c9f3c5f26a6d839f6627a82aa38858a3d5cc1ca87f5a8d795533e"
},
{
"member": "inputs/corpus/workshop_sa_folded.json",
"bytes": 102922,
"sha256": "ea5fd285d11795e5e543e4144349c32c92a5b328b8c5e2d1be8b75b70703dc97"
},
{
"member": "inputs/corpus/workshop_sa_original.json",
"bytes": 102923,
"sha256": "cc9b26390594513c11b3d85b768d244b2df8e7bed8cb76c4bdf0dc24db1d2ef6"
},
{
"member": "inputs/prior-arrange-controls.jsonl",
"bytes": 1862455,
"sha256": "f924af4038ade0de2e0f44988fa28d2566019d8c4bc2bde70e61fe4813364d40"
},
{
"member": "inputs/released-route-control.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"member": "reviews/audit-scc-conservation-20260925.py",
"bytes": 11022,
"sha256": "7ebe5726c49c0918a9fbd55f74e16cac484ccec9d13f9cada7a7b36672ff1035"
},
{
"member": "reviews/audit-scc-conservation-v2-20260925.py",
"bytes": 14082,
"sha256": "66a1621ac04e73bf08637047ed623c7154c0219a3076be7246004e6bf134d4e2"
},
{
"member": "reviews/audit-scc-placement-20260925.py",
"bytes": 7233,
"sha256": "9990be4df625d3f6e566502c4abd1672fc1a8e0077017ef17b98e8c8dfdaa2f5"
},
{
"member": "reviews/audit-scc-placement-v3-20260925.py",
"bytes": 8729,
"sha256": "8b238f010eeb81720a59a0ad290544f87934acb8070e58a3fd25f9eda9f47a0d"
},
{
"member": "reviews/connection-corridor-design-20260925.md",
"bytes": 14520,
"sha256": "02953ef1ae84c83b8c2c7f3b539c6be147ca2ae43f7dd94cf3836ff6f8ee3b30"
},
{
"member": "reviews/connection-corridor-sharing-diagnosis-20260925.md",
"bytes": 7467,
"sha256": "506bbec69bbe229161547906452fe11fb00a7fa8e46023ed3dcb0e2301f8fecb"
},
{
"member": "reviews/prior-sharing-groups.json",
"bytes": 88110,
"sha256": "f9114eaafa22f1d618783b4a62a570d24387645451aafc2123561b53ed16968f"
},
{
"member": "reviews/scc-conservation-audit-20260925.json",
"bytes": 44150,
"sha256": "736d0269bf7cab453abc150a12eece22cb3bc2372c3a3a173638d8aa7a84817e"
},
{
"member": "reviews/scc-conservation-audit-final-20260925.json",
"bytes": 46033,
"sha256": "c9156b710323d940a712ca8973a2e823a422faf96ad9c509193968ecf2f7fdd9"
},
{
"member": "reviews/scc-conservation-audit-run02-20260925.json",
"bytes": 51903,
"sha256": "2897af5f3d131e2633a8dc5c9385307516c7c4db227349b374d4d062423a425e"
},
{
"member": "reviews/scc-conservation-audit-v2-20260925.json",
"bytes": 44876,
"sha256": "fc1a1b0c5a5b9905b54c28f4719fd5ae9c5fcc998939f146523a2296375c9013"
},
{
"member": "reviews/scc-conservation-review-20260925.md",
"bytes": 3912,
"sha256": "4fa505eb8fdcda3a9225b363cb127755ae241809a7a07212b80a8d52513ac681"
},
{
"member": "reviews/scc-conservation-review-run02-20260925.md",
"bytes": 2963,
"sha256": "bdcd203edf2ba002d530d6d7e72b7cb2baeec9207b5b4c8de409dfdb5348214b"
},
{
"member": "reviews/scc-failure-diagnosis-20260925.md",
"bytes": 8906,
"sha256": "7a866902303fb83d14a673e1cede028c5a15517499e8e5f284fced4212f9a536"
},
{
"member": "reviews/scc-placement-criteria-20260925.md",
"bytes": 10647,
"sha256": "f2872610e5f78e2ccec8b487c2ac873505ecab8ad5f876f741142299fefab993"
},
{
"member": "reviews/scc-placement-implementation-20260925.md",
"bytes": 4776,
"sha256": "3436bf1cb500a72b4625ecb022b2035f67d08d909e9d5c9249ea676bc25a30cb"
},
{
"member": "reviews/scc-placement-independent-audit-20260925.json",
"bytes": 184175,
"sha256": "10e53afa7e19cf90cd66524451a2bf4723d98abcca8b1b1c4503d466e19c3df2"
},
{
"member": "reviews/scc-placement-independent-audit-run02-20260925.json",
"bytes": 200406,
"sha256": "cb1caa9b87a02ec9cdc793360b1d699e646fbe89605cd09dd578fe77440aed39"
},
{
"member": "reviews/scc-placement-independent-audit-v2-20260925.json",
"bytes": 193211,
"sha256": "519baf9fa49238aaa1e2b61e44b1c0e6b9d420b2ed7dcafe7b489d9e01396682"
},
{
"member": "reviews/scc-placement-result-review-20260925.md",
"bytes": 8052,
"sha256": "48fbac747679069e0d1d3d713cba6c65cf3d4d3cde220ac8ca939525fd8eec89"
},
{
"member": "reviews/scc-placement-result-review-run02-20260925.md",
"bytes": 4300,
"sha256": "c07bb1c43f0666f59dd6fecdd63b806ea35e3485db197f9b99caa1ec551f947c"
},
{
"member": "reviews/scc-placement-source-review-20260925.md",
"bytes": 10597,
"sha256": "24e496c3050b4d5cbbd1abaf2bf4587642cdfc742e245a2f041ba43ed2cce114"
},
{
"member": "reviews/scc-placement-source-review-v2-20260925.md",
"bytes": 5402,
"sha256": "fb3ac17e52f2c3a6cbfded78d2d72d64b4b15b388f4fdb943d7eb5b28d5d45ca"
},
{
"member": "run01/capture.json",
"bytes": 4068,
"sha256": "060fbf28e59dc7fceba30b856b1877efab8058381a5ae9363e20129005208015"
},
{
"member": "run01/mixed_dispatch/receipt.json",
"bytes": 1102,
"sha256": "69721d3e295a9a987da0333840c3ba5355ee0f24669ff071223f48e149e8026d"
},
{
"member": "run01/mixed_dispatch/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch/stdout.jsonl",
"bytes": 93898,
"sha256": "28a7f598746f4c0c58afd0321861e417b2715976cde52bf55361dce8c35b4d74"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed/receipt.json",
"bytes": 1173,
"sha256": "548fe7ca1e8c40b837de8e0490793f44e42661b28486065161138ae3b5bb6026"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/mixed_dispatch_edge_ids_reversed/stdout.jsonl",
"bytes": 93308,
"sha256": "6a723a4899026c2df80327fb76c5dda8e5dc5e4e15e9e066991413c2246bade5"
},
{
"member": "run01/receipt.json",
"bytes": 15627,
"sha256": "f84bc9793636a9bb087d465d2d9bb22b39a3bc6ccae595fc60438db4b0c03f18"
},
{
"member": "run01/route-control/receipt.json",
"bytes": 1047,
"sha256": "6e744db4c7ceee5f93bfdbf3bfcdf3057443c7dbc42da385356f90239e6e982b"
},
{
"member": "run01/route-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/route-control/stdout.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"member": "run01/small-controls/receipt.json",
"bytes": 866,
"sha256": "4a3b959ea27cefd67989ded74d4b3990236e1261a70ee4b98aead65e33ef4074"
},
{
"member": "run01/small-controls/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/small-controls/stdout.jsonl",
"bytes": 425661,
"sha256": "0ec2bc1f51542b41b5df0b89d2a87306716a49a22951c4dfeb128dd75247d074"
},
{
"member": "run01/small-scc/receipt.json",
"bytes": 874,
"sha256": "553e8a1840e44f2e14b11d24397b2434e7d6b9d2d14ac5accb8b1a0233d0ebca"
},
{
"member": "run01/small-scc/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/small-scc/stdout.jsonl",
"bytes": 205873,
"sha256": "b35cbe482f8ad23da068da5761bdc61cfb88de3b1fa982f90ce78f5e379c9742"
},
{
"member": "run01/subsystems_40_sparse/receipt.json",
"bytes": 1125,
"sha256": "7b60517dc2323d9834aa765580c5b6ffadae22f10840d5a7db5c9d58f2108577"
},
{
"member": "run01/subsystems_40_sparse/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/subsystems_40_sparse/stdout.jsonl",
"bytes": 361147,
"sha256": "452690f23dda57f62d115b6d88e42d7f0283b4c86081d5149d8738ba6052e53b"
},
{
"member": "run01/workshop_sa_folded/receipt.json",
"bytes": 1118,
"sha256": "c03d5851dea753a00884763c1201e742ba1e53bf49e112d27c03ccd58e178cc8"
},
{
"member": "run01/workshop_sa_folded/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_folded/stdout.jsonl",
"bytes": 194613,
"sha256": "ddf05a2ca36950305090bd5d91ec2a6c617d2eae373c33ad84e9ff4157581c0c"
},
{
"member": "run01/workshop_sa_original/receipt.json",
"bytes": 1126,
"sha256": "109d91b60376fb5d040bf4502a438a343df438a760e6cdef2d61fdabe40f7edb"
},
{
"member": "run01/workshop_sa_original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run01/workshop_sa_original/stdout.jsonl",
"bytes": 198272,
"sha256": "e30a2a6a30d1522cb2f8e9377e7eb8f0a81d1fe8b5aa18550f78c4829b8cc408"
},
{
"member": "run02/capture.json",
"bytes": 4086,
"sha256": "f077c04496d69ed9b9dcc775cd9dfecd0155938d9a4dc85309d8d7a20e14f18b"
},
{
"member": "run02/mixed_dispatch/receipt.json",
"bytes": 1100,
"sha256": "15d3cc1d5885e19551dce4de7a49760551c2fd339326dbf3def9f578dd6a10da"
},
{
"member": "run02/mixed_dispatch/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch/stdout.jsonl",
"bytes": 93898,
"sha256": "28a7f598746f4c0c58afd0321861e417b2715976cde52bf55361dce8c35b4d74"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed/receipt.json",
"bytes": 1173,
"sha256": "04ccd337cc5faff73128a8878b68fa14ccc2df8587daaa20fe0dfd1be244c71e"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/mixed_dispatch_edge_ids_reversed/stdout.jsonl",
"bytes": 93308,
"sha256": "6a723a4899026c2df80327fb76c5dda8e5dc5e4e15e9e066991413c2246bade5"
},
{
"member": "run02/receipt.json",
"bytes": 15643,
"sha256": "30e39e35f606d81b280608c8091d8a93b6d3abf474cba98aac530ee438de5129"
},
{
"member": "run02/route-control/receipt.json",
"bytes": 1047,
"sha256": "6856288ab2bb710040764c08abab12aea3201315749259a8d59942a06dc96549"
},
{
"member": "run02/route-control/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/route-control/stdout.jsonl",
"bytes": 470144,
"sha256": "9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2"
},
{
"member": "run02/small-controls/receipt.json",
"bytes": 866,
"sha256": "eb8e2c5d6aaaf93c46e03a55329fc1cb412552e83e50cffbc735e835b6b662bd"
},
{
"member": "run02/small-controls/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/small-controls/stdout.jsonl",
"bytes": 425661,
"sha256": "0ec2bc1f51542b41b5df0b89d2a87306716a49a22951c4dfeb128dd75247d074"
},
{
"member": "run02/small-scc/receipt.json",
"bytes": 874,
"sha256": "129709582dc204fe281f89d4e6a2ff29ba43cb3991d9c5808ecd92e392a9ea3d"
},
{
"member": "run02/small-scc/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/small-scc/stdout.jsonl",
"bytes": 220188,
"sha256": "0c8b9ef7888cd5ba99733f15d22478cdb2878ef02e22d297d02c8b3eea2e9e15"
},
{
"member": "run02/subsystems_40_sparse/receipt.json",
"bytes": 1125,
"sha256": "4814cc9f9583f1a8994a6cb70b04c4a3fbbbf5d5bb5fa5259bb297e19241cae3"
},
{
"member": "run02/subsystems_40_sparse/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/subsystems_40_sparse/stdout.jsonl",
"bytes": 361147,
"sha256": "452690f23dda57f62d115b6d88e42d7f0283b4c86081d5149d8738ba6052e53b"
},
{
"member": "run02/workshop_sa_folded/receipt.json",
"bytes": 1118,
"sha256": "b943c33a5ae497a34186fcc5a7e5d0be12164977af254527f56ee96d8719f53f"
},
{
"member": "run02/workshop_sa_folded/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/workshop_sa_folded/stdout.jsonl",
"bytes": 194613,
"sha256": "ddf05a2ca36950305090bd5d91ec2a6c617d2eae373c33ad84e9ff4157581c0c"
},
{
"member": "run02/workshop_sa_original/receipt.json",
"bytes": 1126,
"sha256": "651545fe8696abb0b1ef33b606e619e3248c977c525387f1de7b89dd4353b82d"
},
{
"member": "run02/workshop_sa_original/stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"member": "run02/workshop_sa_original/stdout.jsonl",
"bytes": 198272,
"sha256": "e30a2a6a30d1522cb2f8e9377e7eb8f0a81d1fe8b5aa18550f78c4829b8cc408"
}
]
}
@@ -0,0 +1,23 @@
# SCC checkpoint final claim and archive review
Reviewed the current results.md and immutable evidence archive for tested source `2426d286483ab0445663221cd6010a3dadb89a97`. Verdict: **no blocking finding for this experimental checkpoint**. This is evidence/claim acceptance, not production Arrange or native usability acceptance.
## Verified facts
- Independently opened the ZIP and checked every member against manifest bytes and SHA256, exact membership and uniqueness, plus ZIP CRC readback (`testzip`). All 168 members pass. Archive: 6,041,259 bytes; SHA256 `fbf40882ed807a1b40db8b3b9b9c846b060db02cbcc60611c18f9620c1fd59c9`.
- Both run receipts bind unchanged before/after inputs, correct source pins, eight successful bounded children with no timeout, and exact captured stdout/stderr sizes/hashes. Both route-control byte streams hash to `9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2`.
- Independently matched **all 14** complete results-table rows against archived Arrange-reset controls and final candidate metrics, including crossings, raw shared length, all three label counts and rounded area ratios. The bipartite, folded, workshop and two-container regressions are disclosed, not hidden behind sparse-case gains.
- Compared all raw input Projects across runs: unchanged. All 13 previously supported complete candidate objects remain exactly equal. The original two-container `Final Rust projection differs from intended node geometry` rejection is retained; run02 supports that case. All 14 emitted repeat and JSON/source roundtrip checks pass. These emitted checks are correctly distinguished from independently retained repeated full Projects, which are not serialized.
- Gate receipts/logs support source 2426d286's 8 example tests, strict Clippy and optimized build (24–26); source 4dd764fa's 5 tests/Clippy/build (21–23); earlier packing tests; and the retained gate20 exit101 `needless_range_loop` failure. All gate input inventories report unchanged. No whole-workspace claim is made.
## Interpretation and limits
The transfer explanation agrees with the source review and independently derived run01 failure: preserve unchanged effective expanded minima only for qualifying position-exact, noncollapsed nodes that would otherwise shrink, then require one exact final projection. This restores the intended 308×446 parents without changing SCC packing/order/gaps. The unchanged 13 candidate objects strengthen this attribution; the newly supported two-container result still has 164 sharing and one label/node collision, so the correction is not presented as a quality improvement.
The quality verdict is proportionate. Sparse coherent SCCs remove the dominant shared corridor, while residual label conflicts, folded retrace, relation-ID-dependent routing and area costs remain. The evidence supports keeping the structural hypothesis and conducting a bounded next experiment; it does not establish engineer traceability, general lane separation, glyph readability or product acceptance. Proposed external-neighbor sibling ordering should preserve the SCC witness and the fixed full-corpus comparison; its benefit remains unverified.
Archive contents include both runs, failed gates, frozen five-case inputs, controls, scripts and independent reviews. Source is identified by commit; binaries are intentionally excluded but their capture hashes remain. Repository-relative build/CLI examples are suitable reproduction entry points after obtaining that source and locked dependencies. Archived supervisor scripts/receipts retain machine-local paths and Windows environment assumptions: they are provenance, not an automatically portable runner. Short observed runtimes are not performance guarantees; the work counter is weighted. Linux, native workflows, command/history integration, dormant-route translation and State-header coverage remain explicitly outside this checkpoint.
Minor optional wording: “failed flat lead-clearance repair” could read “flat lead-clearance repair rejected on readability grounds”; that earlier repair did remove the targeted lead incompatibility. The surrounding linked results and current non-adoption verdict make this nonblocking.
Review method: read-only archive/JSON/log/source-review inspection and offline comparisons. No compiler, router, GUI or test process rerun. No source/archive changes. Publication remains unconfirmed until parent obtains Gitea success and readback.
@@ -0,0 +1,34 @@
# SCC-block placement prototype
Research-only `examples/auto_layout_probe/condensed.rs`. APIs `candidate(&Project, Id)` and `candidate_with_diagnostics(&Project, Id)`; the latter returns `(Project, serde_json::Value)`. No compiler, formatter, engine or GUI run by implementation agent. Parent owns integration and execution.
The implementation freezes actual projected node minima and visual-parent forest. It rejects Scenario and graphs over256stored nodes/1024visible edges. Folded placements are opaque projected leaves; the authoritative parent import preserves their stored expanded size and moves hidden descendants. No semantic parents, edge direction, port anchors or route fields are directly edited by the module.
Process sibling groups bottom-up. Lift each visible endpoint to its immediate child subtree; form directed arcs only from directed edges. Bounded reachability computes exact SCCs of that **quotient graph**, which need not equal global semantic SCCs. Condensation longest-path ranks cannot interleave a component's members. Undirected links influence local spacing and deterministic same-rank proximity, never rank direction. Canonical alias/placement-ID order breaks ties, independent of edge IDs. Within each SCC, deterministic directed DFS successor walk chooses clockwise perimeter order.
For a multi-node SCC, enumerate finite integer perimeter grids with enough slots. Use maximum member dimensions and local internal edge-label gaps; select minimum bounding area among physical aspect ratios≤2, then area/rows/columns ties. If no such grid exists within the bounded enumeration, select closest aspect, then area/rows/columns. This near-square restriction was approved before execution; unconstrained area minimization would produce a strip. Singletons retain their size. Fixed one-pass prior-neighbour ordering plus a canonical same-rank adjacency walk affects component proximity without changing ranks.
Component and rank-cut gaps use relevant core-estimated label bounds plus32, minimum32, rather than one diagram-wide maximum. Each compound encloses its child layout with32horizontal/bottom padding and actual State header (otherwise64) plus32top separation, taking maxima against frozen projected minima. Absolute positions are accumulated through the visual forest at root origin40,40. Work cap20000000charged units, extent100000; no quality-score iteration or clearance repair loop.
Exactly one parent `import_placement` call applies final positions/sizes and authoritative original-to-final route/reset/hidden translation policy. Its final reprojection gate rejects automatic-capacity or container-size divergence rather than repairing indefinitely. The actual final lead diagnostic rejects incompatible mandatory leads explicitly; an empty diagnostic is necessary only, not full-route or readability acceptance. Diagnostics expose parent groups, SCC membership/DFS walk/rank/grid/gap, lifted directed and undirected pairs, component offsets/envelopes and work usage.
Two pure tests cover SCC separation across a one-way bridge and unique nonoverlapping ten-node perimeter slots. They are unexecuted. Repeat stability and meaningful preservation/geometry tests remain parent's run gates. Large local labels may still produce oversized SCCs; quotient cycles and cross-container semantic cycles are heuristic limitations, not equivalent semantic SCC claims. Routing used to obtain label bounds is bounded by existing core machinery but is not included in the prototype's own charged-loop count; this is not a runtime latency guarantee.
## Parent integration addendum
The preceding text is the implementation handoff before execution. Source
ea18adc0 corrects perimeter scoring to use occupied cells, includes single-row
and single-column candidates, and adds a two-node witness. It scores maximum
member-cell envelopes, not an exact aspect guarantee for heterogeneous nodes.
Source4dd764fa fixes a Clippy row-iteration warning; five example tests, strict
Clippy and the release build pass. Run01 supports13 of14 frozen cases.
Source2426d286 changes only the shared example importer and its tests, not SCC
placement. One bounded conditional restoration preserves intended unchanged
effective container minima after children move inward. Three regression tests
cover that failure, expanded/folded identity and inconsistent-plan rejection.
All eight example tests, strict Clippy and optimized build pass. Run02 supports
all14 cases and leaves all13 prior successful candidate objects exactly equal.
Independent quality reviews still reject production adoption. See the final
results, transfer diagnosis, source review v2 and run02 reviews for the complete
evidence and limitations; the early unexecuted status above is historical.
@@ -0,0 +1,82 @@
# Coherent cyclic-group placement experiment
Source evidence atae9dad54 and the independent grouped-corridor audit change the
next action. The old sparse candidate has four10-node strongly connected
components, but its alias cycle breaking interleaves them across16 ranks. The
single top corridor contributes38880/40522 pairwise shared units. Mixed has the
same defect:4006/4228 at the top boundary. Test coherent compact SCC blocks with
the released router before introducing a joint route-separation algorithm.
This is a structural candidate, not another penalty or gap-repair sweep.
## Fixed candidate
- Plan each sibling group of the actual projected visual forest. Lift oriented
connections to immediate child-subtree representatives, compute SCCs, then
rank their condensation DAG. Never break a cycle by choosing an arbitrary
vertex in another still-blocked component. Undirected edges impose no rank
direction. Preserve all semantic orientation/endpoints and authored hierarchy.
- Pack a multi-member SCC around a compact rectangular perimeter, using a
deterministic directed DFS successor order with alias/placement ties. Among
integer perimeter grids, prefer near-square physical aspect≤2 when feasible,
then minimum area; otherwise minimum aspect, with deterministic ties. This
rule is frozen before execution, not selected from measured corpus scores.
- Use local edge-label estimates for gaps inside and between blocks. Minimum
gaps and child-header clearance reserve at least the18+12 mandatory-lead
requirement. Recompute parent enclosure from frozen minima. Core estimates
are not native glyph measurements. No global longest label inflates every gap.
- Folded visible nodes are opaque with their exact compact projected footprint;
stored expanded sizes and latent descendants follow the audited original-to-
final import translation policy. Other omitted placements remain unchanged.
Final import alone reconstructs eligible route reset and retained translations.
- Check actual final projection and mandatory leads. Geometry mismatch, missing
owners, bounds/work exhaustion and infeasible leads remain explicit candidate
errors; no implicit repair loop or changed port anchors. Scenario remains
outside this Arrange operation. Nodes/edges/work and grid enumeration are
bounded and candidate failure leaves the original unchanged.
At a nested level these SCCs belong to the child-subtree quotient graph; they
are a placement heuristic, not a claim about original leaf semantic SCCs.
Cross-boundary edges and per-parent component/rank membership are reported.
Nested grouping must not rewrite user containment or silently flatten it.
## Evaluation and stop
Use the same five frozen independent cases and the original nine small fixtures.
Retain original/current Arrange-reset/old native results; add one SCC candidate,
without parameter sweeps or changing the router. Report unsupported/error cases.
Check complete Project conservation with only declared geometry/reset/retained
translation exceptions, exact port-anchor and hidden-subtree behavior, final
header/enclosure and node/route collisions, warnings, proper/T/bend contacts,
shared intervals and pair multiplicities, labels, area and length. Record
repeat-input equality and ten-call stability, including folded/compound cases.
The two relation-ID variants must expose any stable-ID routing sensitivity.
The structural witness is actual condensation order with compact component
members and reduced dominant shared top corridors. A lower shared total alone
is insufficient: preserve the full quality vector and identify any newly
ambiguous pair, port failure, label interference or disproportionate area cost.
Model/identity/history preservation is not evidence of readability. Do not
adopt after compilation or metric checks alone; a viable candidate still needs
production command/API/history integration and native route-tracing workflows.
Stop after this one structurally distinct candidate and independent review. If
coherent blocks only move sharing elsewhere or create hard failures, retain
the counterexample. Joint derived route separation and virtual long-edge
ordering remain distinct alternatives; choose the next action from the observed
failure, not from commitment to this prototype.
Windows only; Linux builds and the frozen published prerelease remain unchanged.
## Transfer correction after the first run
Run01 at 4dd764fa exposed a transfer bug in the unchanged-effective-size shortcut,
not an SCC placement choice: moving children inward removed part of a parent's
derived enclosure while the importer preserved its smaller authored size. The
parent was therefore projected smaller than the explicitly requested geometry.
Retain run01. Correct the importer with one simultaneous restoration of intended
unchanged effective minima for noncollapsed nodes whose first projection is
strictly smaller and at the exact intended position. Reject every other mismatch
before restoration; require an exact second projection. Add identity, inward-child
and inconsistent-plan regression checks. Then repeat the same corpus as run02.
The SCC ordering, gaps, packing, routing and quality criteria remain unchanged;
this is a correctness repair to faithfully execute the predeclared candidate.
@@ -0,0 +1,40 @@
# Independent SCC run02 review
Source2426d286; primary `scc-placement-20260925/run02`. Read-only audit using `audit-scc-placement-v3-20260925.py ROOT OUTPUT --previous RUN01`. No compiler, router, native or engine run. Original run01 reviews and both audit JSONs remain unchanged.
**The importer correction restores the previously rejected compound case without changing any of the13 prior successful candidate outputs. All14 cases now return results; this remains an experimental candidate, not an accepted Arrange replacement.**
## Exact regression and integrity checks
Verified root receipt/capture/build and every child source pin agree, bound inputs before/after are identical and their file hashes still match, all eight children exit0 without timeout, all stdout/stderr hashes match, and released-router control bytes remain exact. Compared run02 input Projects to run01 for all14 cases without tolerance. For each of the13 prior successes, the **entire candidate object** is exactly equal, including complete Project, full metrics/geometry, diagnostic plan, roundtrips, repeat results and lead report. The new source did not silently change those results or their prior limitations.
Independent SCC/condensation and grouped-sharing audits pass across all14 supported cases. Every emitted raw pairwise segment-sharing total is independently reproduced. The folded physical-sharing/raw-multiplicity distinction and six-unit retrace from run01 remain unchanged. All14 recorded same-input checks, nine subsequent candidate calls and both roundtrips are exact. Parent separately owns complete Project conservation against the allowed import/reset transformation; exact prior-candidate equality is not a substitute for that broader check.
## Newly admitted two-container result
`two_containers_reversed_children` previously rejected final projection mismatch. It now returns two308×446 parent boxes, with child SCCs all singleton rank0 and parent condensation ranks0→1; independently reconstructed membership/order agrees. Necessary lead report and warnings are empty, with zero unrelated node penetration or node overlap.
| Metric | Original input | Arrange/reset | Old layered | SCC run02 |
| --- | ---: | ---: | ---: | ---: |
| Proper crossings |0|0|0|0|
| Point contacts |2|2|0|2|
| Raw shared length |200|148|0|164|
| Label/node collisions |0|1|0|1|
| Label/label collisions |0|0|0|0|
| Label/stroke intersections |0|0|0|0|
| Route length |1512|872|372|788|
| Drawing area |485248|288512|272800|339852|
The entire164-unit sharing is vertical at x508; independent interval sweep agrees exactly. The importer fix makes geometry admissible, but it does not solve this fixture's child-order tracing problem. Old layered remains materially better on the displayed quality vector. Relative to reset, SCC shortens paths but worsens sharing and area while retaining the label/node collision. Do not present14 successful executions as14 improvements.
## Decision
Run01's strong sparse SCC compression evidence remains exact, as do workshop label regressions, bipartite sharing regression, relation-ID sensitivity and folded backtracking. The narrow projection-size correction is supported by the unchanged13 outcomes and newly admitted fourteenth geometry; it does not justify changing the quality verdict.
Stop this candidate as predeclared. The newly visible nested result points to cross-boundary child ordering as a concrete next witness: preserve coherent SCC ranks while determining sibling order using external neighbors, rather than returning to arbitrary alias ties or adding global gaps. Any follow-up must preserve the exact sparse improvement and existing semantic/reset/port constraints, and compare against the old layered fixture's zero-sharing witness. No parameter sweep, native readability, production integration or release acceptance is claimed.
- .local\audit-scc-placement-v3-20260925.py: SHA256 8b238f010eeb81720a59a0ad290544f87934acb8070e58a3fd25f9eda9f47a0d.
- .local\scc-placement-independent-audit-run02-20260925.json: SHA256 cb1caa9b87a02ec9cdc793360b1d699e646fbe89605cd09dd578fe77440aed39.
- .local\scc-placement-20260925\run02\receipt.json: SHA256 30e39e35f606d81b280608c8091d8a93b6d3abf474cba98aac530ee438de5129.
@@ -0,0 +1,68 @@
# Independent SCC placement result review
Source4dd764fa, primary run `scc-placement-20260925/run01`. Read-only recorded-result audit; no compiler, router, native or engine execution. **The structural hypothesis succeeds strongly on sparse40, but this candidate is not adoptable.** One compound case is rejected, several successful cases regress labels/sharing or area, and no native tracing acceptance exists.
## Admission and independent scope
Verified all bound input hashes against receipt, before/after binding equality, eight child exits0/not timed out, recorded stdout/stderr hashes, and exact released-router-control bytes. All14 candidate cases are accounted for:13 supported, one explicit failure. Parent separately owns full Project conservation; this review does not substitute geometric metrics for that check.
The standalone script reconstructs sibling-quotient directed edges from original projected nodes/edges, computes mutual reachability independently, verifies every reported SCC membership and condensation rank ordering, and measures final component extents. These checks pass for all13 supported cases. It also checks each perimeter walk contains exactly the component membership once. It does not claim that DFS order is an optimal cycle traversal.
Independent grouped collinear sweeps cover all available original/reset/old-layered/candidate scenes. Each sweep splits segments at interval endpoints and retains both distinct-edge physical sharing and raw segment-pair multiplicity. Raw multiplicity agrees with all emitted shared-length totals within0.001. Initial edge-deduplicated comparison exposed a folded route retrace, explained below; both definitions and the initial output are preserved. Candidate repeat-input equality, nine subsequent calls and both roundtrips report exact equality for all13 successes; no independently rerun semantic/history test is claimed.
## Complete outcomes
Sharing columns are reset / old layered / SCC, raw pairwise segment units.
| Case | Sharing | Result |
| --- | --- | --- |
| flat_chain_4 |0 /0 /0|Successful, fewer area units than reset, no recorded collision/warning.|
| chain_7_row_wrap |0 /0 /0|Successful; area523584→278256.|
| diamond |36 /82 /36|Restores reset sharing; no crossing.|
| crossed_bipartite |276 /344 /368|Worse sharing than both controls despite smaller area; no crossing.|
| nested_cross_boundary |0 /0 /0|Label/node1→0, area284096→455366.|
| authored_detour_and_label |0 /0 /0|Successful; reset semantics audited separately by parent.|
| fixed_ports |0 /0 /0|Successful, smaller area; anchor conservation separate.|
| two_containers_reversed_children |control retained /old retained /failed|Explicit “Final Rust projection differs from intended node geometry”; no candidate metrics or success inferred.|
| long_ordinary_labels |36 /36 /36|Label/node2→0, modest area growth.|
| workshop_sa_original |1832 /1467 /344|Sharing/contact gains; label/node1→3, label/stroke0→1, large area growth.|
| workshop_sa_folded |1194 /unsupported /726.5|New supported scope, but crossings7→8, contacts19→28, label/node0→3 and label/stroke0→2; four promoted warnings retained.|
| mixed_dispatch |716.4 /4228 /516.6|Crossings10→7, contacts25→16, no label collisions, larger area.|
| mixed reversed IDs |512.4 /4228 /462.6|Crossings9→6, contacts26→15; differs from corresponding unpermuted result.|
| sparse40 |1990 /40522 /32|Strong structural improvement; residual label/label1 and label/stroke3 remain.|
All successful cases report zero unrelated node penetration and zero unrelated node collision. Necessary lead reports are empty. These emitted facts are not claims of complete glyph or arrowhead clearance.
## Structural causal witness
Sparse independently has four ten-node SCCs; each now occupies720×1024 with a5-row/2-column perimeter. Condensation ranks are0,1,2,3 and every intercomponent arc respects increasing rank. Old members sprawled/interleaved across16 ranks. The old y28 top corridor contributed38880 units; the new result has no horizontal shared interval at all. Its entire32-unit sharing is one vertical group at x1510. Thus this result directly supports the diagnosed rank/SCC-locality cause, without any router cost change or lane allocator.
Sparse full vector versus reset: proper crossings94→15, contacts158→19, sharing1990→32, label/node14→0, label/stroke31→3, route length39660→18784; area3804920→4001536 (about5.2% larger). Label/label remains1. Compared with old native, crossings17→15 and sharing40522→32 with substantially less area. This is compelling experimental evidence for coherent SCC placement, not proof of universally separated lanes.
Mixed's six-node SCC occupies706×564 in3×2, with singleton condensation ranks around it. Its previous4006-unit y28 sharing vanishes; remaining sharing is local, largest216 vertical at x709. However its area rises1139880→1667490, and ID-permuted routing differs (sharing462.6 versus516.6, crossings6 versus7). The output therefore cannot be described as invariant to relation-ID permutation. Route length is7349.6 in both, versus10618.6 reset.
## Folded retrace: definitions matter
Folded SCC's emitted726.5 shared units are correct under the observer's raw segment-pair definition. Deduplicating edge occupancy per interval yields708.5. Promoted edge `a15f7dfd-ac0b-562a-a633-fadc9fb64176` follows:
(747,1052)→(747,1034)→(324,1034)→(324,106)→(330,106)→(312,106).
Its last two horizontal segments retrace x324..330, length6. Other edge overlaps count that span twice in the raw segment-pair sum, explaining the18-unit excess. Independent existing pairwise-segment evaluator also gives726.5. This is not an arithmetic bug; it is both a metric-definition distinction and a real derived backtracking witness relevant to tracing. No silent deduplication should erase it.
## Next distinct action and stopping point
Stop this frozen candidate as planned. Retain coherent SCC condensation as the supported structural direction. First diagnose the rejected two-container final-projection mismatch and align planned container/port-capacity geometry with the authoritative projection; do not weaken the equality check or flatten the hierarchy to gain a successful row. This is a concrete integration-contract failure, not a reason to sweep perimeter dimensions.
After that narrow mismatch is resolved, the next quality experiment should target local label/connection corridor placement or ordering on the actual residual witnesses, not global gaps or router penalty changes. Sparse's huge outside trunk is gone; workshop label interference, folded backtracking and bipartite local sharing are different problems. Virtual long-edge ordering is not justified merely by this successful SCC compression; use it only if a residual crossing witness actually involves rank-spanning order. A derived separation pass remains a candidate for fixed-geometry local sharing, with the previously stated stub/label/pin lifecycle constraints.
No production/native acceptance follows from this record. Header/label legibility, overview/navigation cost, selected workflow tracing, production command/history integration and full Project conservation remain separate checks. No additional candidate run or tuning was performed.
- .local\audit-scc-placement-20260925.py: SHA256 9990be4df625d3f6e566502c4abd1672fc1a8e0077017ef17b98e8c8dfdaa2f5.
- .local\scc-placement-independent-audit-20260925.json: SHA256 10e53afa7e19cf90cd66524451a2bf4723d98abcca8b1b1c4503d466e19c3df2.
- .local\scc-placement-independent-audit-v2-20260925.json: SHA256 519baf9fa49238aaa1e2b61e44b1c0e6b9d420b2ed7dcafe7b489d9e01396682.
- .local\scc-placement-20260925\run01\receipt.json: SHA256 f84bc9793636a9bb087d465d2d9bb22b39a3bc6ccae595fc60438db4b0c03f18.
- .local\elk-reference-20260925\rust-run03\arrange-corpus\stdout.jsonl: SHA256 f924af4038ade0de2e0f44988fa28d2566019d8c4bc2bde70e61fe4813364d40.
@@ -0,0 +1,155 @@
# Coherent cyclic-group placement result
Branch-specific issue32 experiment. **SCC condensation and compact cyclic groups
remove the dominant shared outside corridor, but this is not ready for production
Arrange.** The corrected transfer supports all 14 frozen cases, preserves the
declared model/geometry contract and is stable across ten calls. Local label
conflicts, folded-route backtracking, bipartite sharing and area costs remain.
No native tracing, command/history integration or release acceptance is claimed.
Independent evidence: [corrected source review](source-review-v2.md),
[run02 quality review](result-review-run02.md),
[run02 conservation review](conservation-review-run02.md), and
[transfer and label-conflict diagnosis](transfer-diagnosis.md).
Tested source: `2426d286483ab0445663221cd6010a3dadb89a97`. Run01 at
`4dd764fa6cfc6920350383e523ba5a597412ddf4` is retained, including its rejected
two-container case. Read the [predeclared plan](plan.md), [diagnosis](diagnosis.md)
and [design alternatives](design.md) for why this structural experiment followed
the flat lead-clearance repair rejected on readability grounds. Production routing is unchanged.
## What the structural witness establishes
Sparse 40 has four SCCs of ten nodes. Independent graph reconstruction confirms
four coherent 720×1024 blocks in condensation ranks 0–3, replacing the old
alias-cycle-break layout's interleaving across 16 ranks. The old prototype's y28
outside corridor contributed 38880 shared units; the new geometry has no
horizontal shared interval. Total raw pairwise sharing falls 40522→32 compared
with that old prototype, crossings 17→15, area 6020910→4001536. The remaining 32
units are one local vertical group. This improvement required no router penalty
or gap sweep and does not establish general lane separation.
Against current Arrange plus eligible-route reset, sparse crossings 94→15,
contacts 158→19, sharing 1990→32, label/node 14→0, label/stroke 31→3 and route
length 39660→18784. Area grows about 5.2%; label/label remains 1. Against the
original authored input, area and route length grow, so it is not a universal
improvement over every control. All controls remain in the raw evidence.
## Complete quality comparison
Each arrow compares the current Arrange-reset control with the SCC candidate.
Labels are node / other-label / unrelated-stroke collision counts. Area is
candidate/control. Sharing is raw segment-pair length, not unique physical ink.
|Case|Proper crossings|Shared length|Labels N/L/S|Area ratio|
|---|---:|---:|---:|---:|
|flat_chain_4|0→0|0→0|0/0/0→0/0/0|0.72×|
|chain_7_row_wrap|0→0|0→0|0/0/0→0/0/0|0.53×|
|diamond|0→0|36→36|0/0/0→0/0/0|0.91×|
|crossed_bipartite|0→0|276→368|0/0/0→0/0/0|0.57×|
|nested_cross_boundary|0→0|0→0|1/0/0→0/0/0|1.60×|
|authored_detour_and_label|0→0|0→0|0/0/0→0/0/0|0.93×|
|fixed_ports|0→0|0→0|0/0/0→0/0/0|0.94×|
|two_containers_reversed_children|0→0|148→164|1/0/0→1/0/0|1.18×|
|long_ordinary_labels|0→0|36→36|2/0/0→0/0/0|1.06×|
|workshop_sa_original|6→6|1832→344|1/0/0→3/0/1|1.81×|
|workshop_sa_folded|7→8|1194→726.5|0/0/0→3/0/2|1.35×|
|mixed_dispatch|10→7|716.4→516.6|0/0/0→0/0/0|1.46×|
|mixed_dispatch_edge_ids_reversed|9→6|512.4→462.6|0/0/0→0/0/0|1.40×|
|subsystems_40_sparse|94→15|1990→32|14/1/31→0/1/3|1.05×|
All 14 successful cases report zero unrelated node penetration, zero unrelated
node collision and no incompatible mandatory leads. Four folded-workshop
PromotedEndpoints warnings remain; no NoClearPath is reported. Those checks do
not establish arrowhead clearance, native glyph readability or usability.
Mixed's fixed relation-ID permutation leaves projected node/port geometry and
the SCC plan exactly equal, while final routes differ: crossings 7 versus 6 and
sharing 516.6 versus 462.6. The placement is stable under this permutation; the
whole routed drawing is not. Mixed area grows despite shorter routes.
The folded raw shared total 726.5 includes a promoted route that retraces 6 units.
Distinct-edge occupancy counts 708.5: the 18-unit difference is raw segment-pair
multiplicity, independently reconciled rather than silently discarded.
The remaining sparse label/label pair and three label/stroke pairs have no
positive shared route interval; one pair has no route point contact at all.
Thus label association needs its own treatment after structural placement.
See the independent reviews and failure diagnosis in the evidence archive.
## Correctness repair and preservation
Run01 rejected the two-container fixture because parents intended to retain
their old 308×446 effective dimensions instead shrank to 280×416 after children
moved inward. The importer preserved authored 224×94 sizes under an overly broad
identity shortcut. Source 2426d286 restores intended unchanged effective minima
only for noncollapsed nodes whose first final position is exact and whose
dimensions are smaller/equal. It rejects every other mismatch before making
all qualified writes simultaneously, then validates and requires one exact
second projection. There is no iteration or change to SCC ordering/gaps/packing.
The original13 successful candidate Projects, metrics and plans are exactly
unchanged in run02. The new two-container result confirms both intended 308×446
parent minima and all source-derived planned positions. All 14 report exact
same-input output, nine subsequent calls equal to first/previous, and exact
JSON and textual-source roundtrips. Repeated Projects/source strings are not
serialized, so independent audits distinguish emitted Rust checks from their
own raw structural comparisons.
Independent audits reconstruct complete expected Projects with only declared
positions, required sizes and eligible-route resets changed. Semantic records,
authored anchors, route identities/order, other diagrams and hidden metadata
remain exact. Three latent folded descendants move (-680,0) with their collapsed
owner. Current fixtures do not exercise surviving dormant authored-route
translations or State-specific headers; no such coverage is claimed. Exact
intended plan nodes are not emitted, so final transfer equality remains a source
gate supplemented by independent final enclosures and the reconstructed failure
witness. No history/Undo/Redo test applies to these example-only imports.
## Verification and reproduction
Windows Rust 1.98.1 gnullvm and LLVM-mingw 20260908, locked offline dependencies,
one build job. Source 2426d286 passes 8 example tests, strict example Clippy and an
optimized build (gates 24–26). Earlier source 4dd764fa passes 5 example tests,
Clippy and build (gates 21–23). Gate 20's needless-range-loop Clippy failure and
earlier packing tests are retained, with their exact source pins. Core code is
unchanged from the previously verified lead diagnostic; this is not a new
whole-workspace suite claim.
```
cargo test --locked --offline -p oa-core --example auto_layout_probe
cargo clippy --locked --offline -p oa-core --example auto_layout_probe -- -D warnings
cargo build --release --locked --offline -p oa-core --example auto_layout_probe
auto_layout_probe --scc-fixtures
auto_layout_probe --scc-placement PROJECT_JSON DIAGRAM_UUID
auto_layout_probe --route-corpus MANIFEST
```
Both runs capture the built executable before further compiler writes, verify
source/binary/input hashes, and complete eight bounded child processes. The
five-case released route-control output is byte-identical in both runs, SHA256
`9a31a676f23dea2f41daec39497f569d68231fa0fd66e5a1a476be97d5d61ac2`.
Output process success is separate from per-case support. No latency guarantee
is inferred from these short corpus runs. The planner work counter is weighted,
not an exact instruction or elapsed-time bound.
## Decision and evidence
Retain coherent SCC blocks as the supported structural direction. Do not adopt
this complete candidate yet. Next work should target the concrete local label
association, folded retrace and cross-container ordering witnesses. Preserve
model/port/fold contracts, fixed inputs and the full quality vector; do not tune
global gaps, rerun perimeter candidates to select a score, or weaken projection
equality. Production integration and native trace/overview workflows remain
required once a candidate satisfies those constraints.
The evidence archive contains both runs, failed and successful gate receipts,
frozen inputs, controls, executable capture hashes, scripts and independent
source/result/conservation reviews. Binaries are not embedded. Final claim and
archive review is [versioned separately](final-review.md) outside the immutable archive.
Archived supervisor scripts retain machine-local paths and Windows environment
assumptions; the repository-relative build and probe commands above are the
portable entry points after obtaining the source and locked dependencies.
Archive `evidence/scc-placement-2426d286.zip`: 6041259 bytes, SHA256 `fbf40882ed807a1b40db8b3b9b9c846b060db02cbcc60611c18f9620c1fd59c9`, 168 individually verified members.
This checkpoint is local-only until confirmed Gitea publication and byte readback. Linux builds remain excluded by the user; the frozen prerelease is unchanged.
@@ -0,0 +1,29 @@
# Independent review of the conditional placement transfer correction
2026-09-25. Reviewed exact `4dd764fa6cfc6920350383e523ba5a597412ddf4`→`2426d286483ab0445663221cd6010a3dadb89a97` diff. Only the example importer, its three new regression tests, and the experiment plan addendum change. `condensed.rs`, production model/projection/routing and SCC placement policy remain unchanged. No compiler, tests, router, candidate or GUI execution by this reviewer.
**Verdict: no material source blocker or accidental acceptance weakening found.** The correction implements the bounded predicate proposed in the run01 diagnosis and retains exact final-projection rejection. It is a faithful-transfer fix, not a new layout choice. Run01 and its source review/diagnosis remain valid records of the original failure. Gate24 and the unchanged-policy run02 are parent-owned pending evidence; this review does not claim they pass.
At `crates/oa-core/examples/auto_layout_probe.rs:975–1015`, the importer first requires the complete original visible identity set with no duplicate count. An already exact node is untouched. Every mismatching node must have exactly the intended position, be noncollapsed, retain an intended size equal to its original projected size, and have no first-projected dimension larger than intended. Because exact sizes were already skipped, a qualifying finite size has at least one strictly smaller dimension. Any other mismatch rejects before any restoration is applied.
All qualified minima are then written simultaneously to the private clone, followed by model validation and one additional projection. The existing exact comparison of all intended node positions/sizes remains the final gate; there is no retry loop, tolerance, clipping, or substitution of whatever projection happened to return. An invalid nested enclosure or additional port-capacity expansion still fails that comparison. Failure does not mutate the input Project.
The first projection already matches for a true identity transfer or a rigid family translation whose enclosure is unchanged, so those cases retain the old authored sizes. Inward child movement can instead remove a formerly derived minimum: writing the requested unchanged projected size as an explicit authored minimum is exactly the storage change needed to preserve the intended visible footprint. This can write both dimensions of the qualified node's Size, even when only one projected dimension shrank; the new conservation audit must allow exactly this declared intended Size on qualified nodes, not silently ignore every size difference.
Restoring multiple nested minima can make a final parent exceed its intended enclosure; the final exact check refuses rather than iterating. Restoring stored sizes can also alter automatic port side/slot choice. Those choices are derived from the returned Project and must be observed by the final port/lead/full-route checks; they are not fixed by this importer and do not authorize an anchor edit. `condensed::candidate` still performs its final actual-projection lead check after this transfer. A source-correct transfer still need not route successfully or improve readability.
Route reset eligibility remains captured from the original view. Original-to-final positional deltas, hidden descendant translations, route entry/order/attachments and other views are untouched by the correction. Since restoration changes only node sizes and requires exact positions, it does not require recomputing positional route translation. Eligible overrides remain cleared once by the existing policy; retained pins are not repurposed as generated layout constraints.
The three tests are meaningful and suitably bounded:
- `unchanged_effective_container_size_survives_inward_child_movement` at1054 moves the lower child in each parent inward20 units, constructs a full expected Project clone with precisely those positions and requested parent minima, and checks exact output plus all original effective dimensions. It distinguishes this bug from a normal new requested size.
- `identity_keeps_authored_expanded_and_folded_sizes` at1095 checks complete Project equality for both expanded and folded identity transfers, including hidden placements. The fixture has no authored routes; this is not a new hidden-pin lifecycle test.
- `inconsistent_smaller_container_plan_still_rejects` at1122 moves a child1000 units beyond its planned enclosure and requires rejection, exercising the larger-derived-size boundary rather than accepting arbitrary reprojection.
These do not exhaust position/ID/automatic-side/nested-restoration cases, but source predicates retain those guards and the fixed corpus rerun provides the next integration evidence. No broader fixture expansion or policy change is required before that run.
The plan addendum accurately preserves run01 and predeclares repeating the same frozen corpus with unchanged SCC ordering, gaps, packing, router and criteria. Do not pool a corrected transfer with a tuned layout or mark the first failure passed retroactively.
Reviewed importer SHA256: `13057d1961ab2b574d202538b11fe7d3173aa7ea288ab380c4e1fcc81b6d6e7d`.
Related unchanged run01 diagnosis: `.local/scc-failure-diagnosis-20260925.md`, SHA256 `7a866902303fb83d14a673e1cede028c5a15517499e8e5f284fced4212f9a536`. No native adoption, whole-layout acceptance or remote publication claim.
@@ -0,0 +1,54 @@
# Independent SCC-placement source review
2026-09-25. Reviewed the initial `condensed.rs` handoff and the formatted candidate at `5300a8c803119dd57d86424867d3107db0ef256d`, plus the parent CLI and plan. No compiler, router, engine or GUI execution; no candidate edits by reviewer. This report is pre-experiment and pending the accepted perimeter correction below.
Reviewed formatted hashes:
- `crates/oa-core/examples/auto_layout_probe/condensed.rs`: `3bb9bcf2ee96d0c0c5beb2b7173c4307c9c9571a38bde3c621f3b5eae0834f86`.
- `crates/oa-core/examples/auto_layout_probe.rs`: `36b81ec8c2ba58d1845f80e3afbfd16307035995893c5359c9e45c3db916ea96`.
## Finding requiring pre-experiment correction
**P2, bounded experiment contract — compact-grid scoring includes unused slots.** `condensed.rs:59` scores every nominal rows×columns perimeter envelope, then returns only its first n slots. For a two-node component, the nominal2×2 grid includes an unoccupied second row in its aspect ratio, while actual output places both nodes in a single horizontal strip. Consequently the advertised physical aspect≤2 preference does not describe the occupied cell envelope. This can affect the small cycle fixtures independently of the larger diagnosed SCCs.
Parent accepted a pre-execution correction: include valid single-row/single-column grids with unique slots, score the actual first n occupied cell slots, preserve the predeclared aspect/area/tie order, and document the maximum-member-cell approximation for heterogeneous sizes. Add the two-node compactness witness. This is a correction to the chosen rule before results, not permission for a later rotation/packing parameter search. No overlap or model corruption was identified in the old slots; the defect concerns the implementation's selection criterion. Closure requires inspection of the resulting patch and its eventual parent-owned gate result.
## Source findings without a blocker
**Graph identity is explicit and coherent.** `lift` maps an endpoint to the immediate child-subtree representative of the current planning parent. `components` computes mutual reachability and partitions canonical sibling indices; condensation removes internal edges and longest-path ranks are propagated in a real topological order. No arbitrary vertex breaks a still-cyclic component. On flat graphs this is the actual visible directed graph; on compounds it is the documented sibling-subtree quotient, which may differ from leaf semantic SCCs. Diagnostics retain parent, membership, rank, walk and lifted arcs. No semantic reparenting or endpoint rewriting occurs.
**Undirected policy is explicit.** Undirected links create no SCC/rank arcs, but remain in local gaps and deterministic neighbor proximity. Same-rank BFS reads all links; directed inter-component links cannot connect equal ranks, so this does not quietly assign a direction to an undirected edge. Relation-ID permutation does not change the alias/placement-based SCC traversal, although released routing order can still affect final paths.
**Boundary-neighbor influence is incomplete by design.** If either endpoint cannot be lifted into a sibling group, that edge is skipped at that group. It may affect an ancestor's block order but not the child's internal ordering relative to external neighbors. In particular, the two-container reversed-child witness need not improve simply because the parent-level condensation is coherent. Parent acknowledged this limit and chose to preserve failures/no-change results rather than append a new heuristic before the fixed experiment. Report it rather than claiming general cross-boundary ordering.
**Local bounds and container geometry are consistent in source.** Descendant groups are measured before their parents; block cells use maximum member dimensions, slots are disjoint, same-rank blocks are vertically separated, and ranks are horizontally separated. Expanded containers enclose their child blocks with32-unit side/bottom padding and header+32 at top. State projections use the core State header height; ordinary header64 agrees with the current architecture projection. Current core port footer is24, within the32 bottom padding. Original projected minima are retained; no shrink is introduced. Repeated calls must still check that saved container sizes and final reprojection do not ratchet or oscillate.
**Folded and stored metadata are delegated correctly.** A folded node is an opaque visible leaf with original projected compact size; a folded node unexpectedly having visible children errors. Final `import_placement` checks exact collapsed compact size while preserving stored expanded size, moves latent descendants under the nearest visible collapsed ancestor, retains unrelated omitted nodes, and performs original-to-final route reset/translation once. The candidate does not overwrite authored anchors or generated routes during intermediate packing. Other views remain untouched. The external result audit must compare full records; emitted broad conservation booleans alone do not establish hidden-route preservation.
**Final geometry is authoritative.** Accumulated offsets convert each nested position to diagram coordinates once. Import validates complete intended versus actual projected node geometry. The final lead diagnostic is run on that final projection and rejects a blocked endpoint pair; no iterative repair, lead shortening or port rewrite is introduced. An empty report still does not prove full-route success, node/header penetration absence, or label readability. The observer correctly emits final metrics and ten-call outcomes instead of a quality-pass Boolean.
**Association-role sizing was corrected before this review pin.** The initial handoff used only center-label dimensions. At `condensed.rs:231` the formatted candidate now takes maximum center and `association_end_geometry` dimensions, matching the earlier native policy. This sizes gaps conservatively by estimates; it does not independently measure or certify association-end label collisions. Existing main-label metric counts must not be presented as all-label native acceptance.
**Boundedness is adequate for this isolated test.** Stored nodes≤256, visible edges≤1024, finite positive minima,100000-unit final extent and a20-million weighted-work allowance bound candidate scope. Reachability, grid enumeration and parent walks have bounded domains; hierarchy cycles/missing parents error. The work count is not an exact CPU/projection/router-operation bound and original label estimation invokes the bounded existing router before much of this accounting. Parent process timeout remains separate. Failure drops the private candidate.
## Tests and interpretation
Current tests independently verify two directed cycles remain distinct across a one-way bridge and that ten perimeter slots are unique/disjoint. They do not establish full SCC placement, header/child enclosure, folded metadata, actual port feasibility or ID-permutation quality. The new two-node test should target the identified scoring defect rather than restate an implementation loop. The frozen five realistic plus nine small scenes, same-input duplication and ten repeated calls are the appropriate next evidence.
On candidate error, the CLI reports unsupported/error and original metrics; it does not retain the partial planning diagnostics or identify each final lead blocker in the error. That is an acknowledged diagnostic limitation, not evidence the input model was changed. Do not infer which SCC order or port caused a rejected result solely from the generic error text.
No further material source defect was identified in the reviewed pin. Keep production Arrange/router unchanged, preserve every unsupported/error case, and judge the full output vector. Source correctness does not establish the proposed compact-block hypothesis or engineer traceability.
## Perimeter finding closed in source
Independently inspected `ea18adc061f3bf8bb448b34e28be4266ffde1aa3` against5300a8c8 before any SCC diagram experiment output. `perimeter_slots` now handles single rows/columns without duplicate corners; enumeration includes those choices. Every score derives width/height from the maximum x/y of the actual first n occupied slots, with maximum-member cell sizes and the same aspect≤2/area/tie priority. The documentation accurately qualifies this as a cell-envelope heuristic; heterogeneous actual node envelopes can differ.
The added two-node witness distinguishes the defect: cells224×160 with gaps250×56 select2×1 and positions(0,0),(0,216), whose occupied envelope224×376 is compact; the competing horizontal envelope698×160 is not. The capacity/work charge includes generated perimeter slots. No production routing, metadata or import policy changes accompany this correction. The P2 source finding is closed; no remaining material source blocker for the fixed experiment was found. Parent gate19 is in progress at review time, so this closes static correctness only, not test execution or layout quality. A redundant constant assertion in the test is nonessential and can be removed if strict Clippy requires it without changing the meaningful witness.
## Exact follow-up through4dd764fa
Reviewed the complete `ea18adc061f3bf8bb448b34e28be4266ffde1aa3`→`4dd764fa6cfc6920350383e523ba5a597412ddf4` diff: one file, four insertions/five deletions. In `components`, `for start in 0..n` becomes `reach.iter_mut().enumerate()`, and reads/writes of `reach[start][...]` become accesses through that same mutable row. Every row is still visited once in ascending start order; start reachability, DFS stack behavior, adjacency iteration, charge calls and visited tests are unchanged. SCC membership/order and all planning policy are therefore unchanged in source. Removing the constant ratio assertion leaves the meaningful expected2×1 grid and exact two positions asserted.
Read gate20's retained receipt/log: strict Clippy at ea18adc0 exits101 with unchanged inputs because of `clippy::needless_range_loop` in that loop; it is not a passing gate. The4dd764fa change addresses the reported idiom without adding an allow attribute or weakening the diagnostic policy. Current `condensed.rs` SHA256 is `ef8050019ad4b436d28a8bbd83ba3addf0315ba021e2e6fe453b96aeb299e739`.
No new material source finding. Perimeter P2 remains closed through4dd764fa. Parent gate21 and later Clippy/build/diagram outcomes are pending for this review; no runtime, performance, geometric-quality or native acceptance is inferred from this static equivalence check.
@@ -0,0 +1,59 @@
# SCC transfer failure and residual sparse label conflicts
2026-09-25. Read-only diagnosis of frozen `scc-placement-20260925/run01` at source `4dd764fa6cfc6920350383e523ba5a597412ddf4`. No source edits, compiler, router, candidate or GUI rerun. The failed candidate does not emit its intermediate plan; the planned/final coordinates below are independently reconstructed from recorded input plus exact source rules, not a captured second Rust execution.
**The two-container refusal is explained by the importer's unchanged-effective-size shortcut, not new port capacity or a failure to find an SCC placement.** Sparse's remaining1 label/label and3 label/stroke relationships are separately identifiable: none of those four edge pairs shares positive collinear route length. The structural trunk improvement therefore leaves genuine label-association and crossing problems; it is not a complete readability result.
## Two-container exact reconstruction
Frozen row `two_containers_reversed_children` reports `Final Rust projection differs from intended node geometry`. Both parents store224×94 but originally project308×446 because their children are farther from the parent origin. Each child stores224×94 and projects224×132 from its single semantic port's core minimum. The recorded input has no authored routes or anchors.
At each parent's planning group, cross-container edges cannot lift their other endpoint into that group. The two children consequently become canonical singleton blocks in one rank, with32-unit vertical gap. Their required content envelope is224×296. Parent padding/header produces288×424, less than the original projected minimum308×446, so the SCC planner intentionally retains308×446 for each parent. At root level both edges lift left→right;114-unit center-label width gives146-unit inter-block gap. There is no association-end label contribution for these FunctionalExchanges.
Source-derived intended plan:
| Placement | Intended position | Intended size |
| --- | --- | --- |
| Left group (`...0002`) |(40,40)|308×446|
| Right group (`...0004`) |(494,40)|308×446|
| Left A (`...0006`) |(72,136)|224×132|
| Left B (`...0008`) |(72,300)|224×132|
| Right A (`...000a`) |(526,136)|224×132|
| Right B (`...000c`) |(526,300)|224×132|
`auto_layout_probe.rs:916–927` preserves authored node size whenever the intended size equals the original projected size. This protects true identity transfers from baking derived minima into storage, but here both parent intended sizes equal their old projected sizes even though their child positions changed. Their stored size therefore remains224×94.
Core enclosure in `projection.rs:549–576` uses24-unit right/bottom padding and64-unit header. For Left group, the new rightmost child boundary is72+224=296, so right=296+24=320 and final width=320−40=280. Lowest child boundary is300+132=432, so bottom=432+24=456 and final height=456−40=416. Right group has the same relative calculation: final280×416. Parent x/y remain exactly intended; child x/y and224×132 dimensions remain intended. Thus both parent dimensions shrink relative to the proposed308×446 and the importer's exact final-projection guard correctly rejects the mismatch.
This is not a new port-capacity expansion: each child has one port, capacity36 is below its existing132/224 dimensions, and the parents have no ports. The larger horizontal separation keeps the children facing their cross-container peers. The mismatch follows from less enclosure slack, not an enlarged port requirement. Because no intermediate candidate was emitted, the claim is this exact source-derived reconstruction; runtime confirmation belongs to the next parent-owned transfer check.
## Critique of the proposed bounded importer correction
The parent's proposed one-reprojection correction addresses an actual transfer defect without changing the SCC algorithm. Prefer its observed-geometry predicate over “write all intended expanded sizes when children move,” which would normalize authored sizes unnecessarily on ordinary rigid-family translations.
Before changing storage, require the complete final node identity set and exact final positions. For every mismatch, allow correction only when the node is noncollapsed, its intended size equals its original projected size, and its first final dimensions are no greater than intended with at least one strictly smaller. Reject any missing/extra identity, position mismatch, larger dimension, collapsed mismatch, or mismatch outside that original shortcut. If all mismatches are eligible, set their stored sizes to intended simultaneously, then validate and project exactly once more. Accept only exact complete intended geometry; no iterative size chase.
True identity and rigid-subtree translation continue preserving original authored sizes because their first projection already matches. This failed case would write308×446 as explicit parent minima only because that footprint would otherwise be lost after child rearrangement. This is a declared stored-geometry change, so full Project conservation auditing must allow exactly those written minima; it must not mask every node-size difference.
Nested repairs can restore child sizes that force a parent above its intended size. Automatic port sides/slots may also change after minima are written. Neither justifies looping: the exact second projection must reject any remaining geometry mismatch, and actual final port/lead/full-route observations must use the returned Project. The second projection is stateless for that final stored model; a repeat comparison still matters for the whole SCC candidate. Keep fixed anchors, hidden metadata, route reset and original-to-final translation unchanged.
Useful targeted checks before reinterpreting the failed row: complete true-identity equality; rigid-family translation preserving authored sizes; this two-parent contraction preserving the intended footprint; rejection of larger/position/collapsed mismatches; and a nested case that either succeeds exactly in that one pass or refuses without partial model changes. Retain run01, change only the importer boundary, and compare the unchanged frozen SCC algorithm's rerun; do not tune placement in response to this defect.
## Sparse label witnesses
Read complete candidate routes and label rectangles and independently intersected their coordinates. All rectangles below are estimated core bounds, not native glyph observations.
**Label/label:** `flow_10` “Communications Enrich to Aggregate” (`...03345a`) overlaps `flow_48` “Planning Enrich handoff to Delivery Validate” (`...033480`). The first label occupies x1662.800048828125..1902.800048828125,y430..454; the second x1520..1760,y428..452. Intersection is97.199951171875×22=2138.39892578125, exactly the emitted area. Their routes cross properly at(1640,460), but share zero positive collinear length. The label overlap is a distinct nearby association problem, not the intersection point itself.
**Label/stroke,1:** `flow_12` “Communications Decide to Package” (`...03345c`) crosses the label of `flow_11` “Communications Aggregate to Decide” (`...03345b`). Label rectangle is x2154..2394,y432..456. The stroke enters vertically at x2266 from y432 to444, then horizontally to x2394 at y444:12+128=140 units (emitted epsilon-inset139.9998). The two route polylines have no point contact and no positive shared interval. A raw route-intersection-only metric would miss this interference.
**Label/stroke,2:** that same `flow_12` stroke traverses the full212-unit width of `flow_25` “Planning Aggregate to Decide” (`...033469`), rectangle x2526..2738,y428..452, along y444. Emitted inset length211.9998 agrees. These routes also cross properly at(2632,444), but have no positive shared run.
**Label/stroke,3:** `flow_05` “Sensing Decide to Package” (`...033455`) traverses the212-unit width of `flow_32` “Delivery Aggregate to Decide” (`...033470`), rectangle x2526..2738,y860..884, along y876. Emitted inset length211.9998 agrees. Their proper crossing is(2632,876); again no positive shared run.
The candidate's whole sparse drawing reports shared length32,15 proper crossings,19 point contacts, zero label/node collisions, zero unrelated-node penetration and zero warnings. Those gains do not erase the explicit four label conflicts. The witnesses support retaining label association and occupied route/label space as separate evaluation criteria. They do not by themselves require changing the router, enlarging every gap, or adopting a joint engine; no such tuning or native acceptance follows from this diagnosis.
Evidence SHA256:
- `run01/small-scc/stdout.jsonl`: `b35cbe482f8ad23da068da5761bdc61cfb88de3b1fa982f90ce78f5e379c9742`.
- `run01/subsystems_40_sparse/stdout.jsonl`: `452690f23dda57f62d115b6d88e42d7f0283b4c86081d5149d8738ba6052e53b`.