Complete source 6 engineering workflows and preserve release validation evidence

This commit is contained in:
Codex
2026-09-06 21:49:04 -07:00
parent 2b2d2bc18b
commit 4b6b5fc197
290 changed files with 48271 additions and 1791 deletions
+104 -9
View File
@@ -226,8 +226,58 @@ pub fn project_view(p: &Project, diagram: Id) -> ProjectedView {
};
project_diagram(p, d)
}
/// Reuse an index built for this accepted semantic revision during presentation
/// previews. Callers must invalidate it when semantic records change.
pub fn project_view_with_index(
p: &Project,
diagram: Id,
index: &crate::view_options::ViewIndex,
) -> ProjectedView {
p.diagrams
.get(&diagram)
.map_or_else(ProjectedView::default, |d| {
project_diagram_with_index(p, d, index)
})
}
/// Project alternate placement geometry without copying or mutating semantics.
pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
let index = crate::view_options::ViewIndex::new(p);
project_diagram_with_index(p, d, &index)
}
pub fn project_diagram_with_index(
p: &Project,
d: &Diagram,
index: &crate::view_options::ViewIndex,
) -> ProjectedView {
project_diagram_impl(p, d, None, Some(index))
}
/// Unfiltered eligibility from the same projection/anchor/fold decisions used
/// for drawing. Compute once for a view-options editor, then combine with the
/// prepared filter's reasons; hidden lines remain geometrically eligible here.
pub fn edge_availability(
p: &Project,
d: &Diagram,
) -> BTreeMap<Id, crate::view_options::EdgeAvailability> {
let mut availability = p
.relations
.keys()
.chain(p.traces.keys())
.map(|id| {
(
*id,
crate::view_options::EdgeAvailability::OutsideProjection,
)
})
.collect();
project_diagram_impl(p, d, Some(&mut availability), None);
availability
}
fn project_diagram_impl(
p: &Project,
d: &Diagram,
mut availability: Option<&mut BTreeMap<Id, crate::view_options::EdgeAvailability>>,
index: Option<&crate::view_options::ViewIndex>,
) -> ProjectedView {
let parents = parents(p, d);
let mut nodes = Vec::new();
for n in d.nodes.values() {
@@ -354,6 +404,7 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
RelationKind::Interaction
| RelationKind::FunctionalExchange
| RelationKind::BoundaryExchange
| RelationKind::CommunicationMean
),
ProjectionKind::FunctionalDataflow => matches!(
r.kind(),
@@ -367,20 +418,36 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
| RelationKind::MissionCapability
| RelationKind::MissionInvolvement
| RelationKind::CapabilityInvolvement
| RelationKind::CommunicationMean
),
_ => true,
};
if !included {
continue;
}
if let (Some(source), Some(target)) = (anchor(r.source()), anchor(r.target()))
&& (source != target
|| ((d.projection.state_machine().is_some()
|| r.kind() == RelationKind::DataAssociation)
&& r.source() == r.target()
&& nodes
.iter()
.any(|n| n.id == source && n.element == r.source())))
let ends = (anchor(r.source()), anchor(r.target()));
let self_loop = (d.projection.state_machine().is_some()
|| r.kind() == RelationKind::DataAssociation)
&& r.source() == r.target()
&& nodes
.iter()
.any(|n| Some(n.id) == ends.0 && n.element == r.source());
if let Some(availability) = availability.as_deref_mut() {
use crate::view_options::EdgeAvailability as A;
availability.insert(
r.id,
match ends {
(Some(a), Some(b)) if a != b || self_loop => A::Visible,
(Some(_), Some(_)) => A::FoldedInternal,
(a, b) => A::EndpointNotShown {
source: a.is_none(),
target: b.is_none(),
},
},
);
}
if let (Some(source), Some(target)) = ends
&& (source != target || self_loop)
{
let (source_port, target_port) = match &r.body {
RelationBody::FunctionalExchange {
@@ -402,6 +469,9 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
RelationBody::BoundaryExchange {
oriented: false,
..
} | RelationBody::CommunicationMean {
oriented: false,
..
} | RelationBody::DataAssociation { .. }
),
source_port: source_port.filter(|id| visible_ports.contains(id)),
@@ -411,7 +481,22 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
}
if d.projection == ProjectionKind::Traceability {
for t in p.traces.values() {
if let (Some(source), Some(target)) = (anchor(t.oa), anchor(t.sa))
let ends = (anchor(t.oa), anchor(t.sa));
if let Some(availability) = availability.as_deref_mut() {
use crate::view_options::EdgeAvailability as A;
availability.insert(
t.id,
match ends {
(Some(a), Some(b)) if a != b => A::Visible,
(Some(_), Some(_)) => A::FoldedInternal,
(a, b) => A::EndpointNotShown {
source: a.is_none(),
target: b.is_none(),
},
},
);
}
if let (Some(source), Some(target)) = ends
&& source != target
{
edges.push(ProjectedEdge {
@@ -433,6 +518,16 @@ pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView {
} else {
port_layout::layout(p, d, &mut nodes, &edges)
};
// Port geometry uses every eligible edge. Presentation filters must never
// move visible ports when another line is hidden or a category is selected.
if let Some(index) = index {
let filter = if d.projection == ProjectionKind::Traceability {
index.prepare_cross_layer(d.layer, &d.view_options)
} else {
index.prepare(d.layer, &d.view_options)
};
edges.retain(|edge| filter.includes(edge.id));
}
ProjectedView {
nodes,
edges,