From c7101b970a9e7c21c304cf4aab439fb585504db8 Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Sat, 5 Sep 2026 17:58:46 +0300 Subject: [PATCH] Preserve nested architecture during authoring and distinguish allocation summaries --- README.md | 4 +- crates/oa-core/examples/generate_demo.rs | 23 + crates/oa-core/src/projection.rs | 72 +- crates/oa-core/src/session.rs | 4 +- crates/oa-core/tests/release_diagrams.rs | 71 + crates/oa-desktop/src/app.rs | 128 +- crates/oa-desktop/src/diagram.rs | 364 +++- crates/oa-desktop/src/guide.rs | 10 +- crates/oa-desktop/src/tests.rs | 296 +++ crates/oa-desktop/src/views.rs | 17 + examples/coastal-rescue.arcadia | 1217 +++++++------ examples/coastal-rescue.json | 2085 ++++++++++++---------- harness/STATE.md | 81 +- 13 files changed, 2719 insertions(+), 1653 deletions(-) create mode 100644 crates/oa-core/examples/generate_demo.rs diff --git a/README.md b/README.md index f422382c..f1cb4668 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,12 @@ V2 release bundles are `dist/ArcadiaStudio-Windows.zip` and `dist/ArcadiaStudio- The coastal rescue example combines people, an organization, a System of Interest, information and physical exchange items, normal/degraded behavior and code/CAD evidence. Choose **New** to start an empty project. +The example opens in an architecture view with work nested inside its performers. Each layer also has dedicated functional dataflow and mission/capability views. Regenerate both example formats with matching identities using `cargo run --locked -p oa-core --example generate_demo`; the command verifies both saved models. Historical migration fixtures remain separate. + 1. In **Operational Analysis**, create entities, actors, activities and capabilities. Use **In selected** for semantic decomposition and **Allocated** for new leaf work performed by a participant. Activities can decompose independently of their performer; roles capture shared operational responsibility. 2. Switch to **System Analysis**. Define one System of Interest and external Actors, then functions, missions, capabilities and functional chains. The system boundary has no internal LA/PA components in this version. 3. Use **Create relationship** for allocations, interactions/functional exchanges, capability involvement, mission links, state transitions and interface relationships. Add exchange items, typed data, ports and provided/required interfaces in **Data & interfaces**. -4. Create multiple architecture views. **Decomposition** nests semantic children; **Allocation** nests work within performers, including computed summaries. Placement dragging changes geometry. **Hide** removes a placement; **Delete from model** removes semantics and dependent references. Use **Placement** and **View properties** for exact values. +4. Create focused views. **Containment** nests semantic children; **Architecture · allocated work** nests work within performers; **Functional dataflow** shows work decomposition and exchanges; **Missions & capabilities** shows objectives and participation. Dashed, italic parent work denotes an allocation summary inferred from its leaves. Ports appear on their owner's boundary. Placement dragging changes geometry. **Hide** removes a placement; **Delete from model** removes semantics and dependent references. Use **Placement** and **View properties** for exact values. 5. In **Behavior & scenarios**, author processes/chains, scenario lifelines and ordered occurrences, including repeated uses of the same exchange and explicit fragments/branches. State machines contain regions and states/modes with guarded transitions, availability and state-action links. Conditions are descriptive, not executable simulation code. Creating records in Behavior or Data preserves your architecture layouts; **Show in this diagram** adds an explicit placement when desired. 6. Select an OA or SA element and choose **Create / update counterpart**. Review dependency scope and counterpart choices, then apply one undoable transaction. Existing counterparts retain their structural choices; reviewed updates compare names/descriptions. Manual traces link other engineering correspondences. **Traceability** also edits artifact URI, revision and fragment metadata. 7. Review **Model checks**, then save `.arcadia` source or `.json`. Warnings allow incomplete authoring; structural errors preserve the committed model and rejected draft. diff --git a/crates/oa-core/examples/generate_demo.rs b/crates/oa-core/examples/generate_demo.rs new file mode 100644 index 00000000..75cd36db --- /dev/null +++ b/crates/oa-core/examples/generate_demo.rs @@ -0,0 +1,23 @@ +//! Regenerate both distributable forms from one model, preserving shared IDs. +use oa_core::{Project, persistence}; +use std::path::PathBuf; + +fn main() -> Result<(), Box> { + let directory = std::env::args_os() + .nth(1) + .map(PathBuf::from) + .unwrap_or_else(|| PathBuf::from("examples")); + let project = Project::demo(); + let source = directory.join("coastal-rescue.arcadia"); + let json = directory.join("coastal-rescue.json"); + persistence::save(&source, &project)?; + persistence::save(&json, &project)?; + assert_eq!(persistence::load(&source)?, project); + assert_eq!(persistence::load(&json)?, project); + println!( + "Wrote and verified {} and {}", + source.display(), + json.display() + ); + Ok(()) +} diff --git a/crates/oa-core/src/projection.rs b/crates/oa-core/src/projection.rs index b5a2299a..a1915a3a 100644 --- a/crates/oa-core/src/projection.rs +++ b/crates/oa-core/src/projection.rs @@ -11,6 +11,8 @@ pub struct ProjectedNode { pub visual_parent: Option, pub depth: usize, pub collapsed: bool, + /// The work is grouped by its allocated leaves, not by a direct allocation. + pub allocation_summary: bool, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ProjectedEdge { @@ -42,6 +44,17 @@ pub(crate) fn minimum_node_size(p: &Project, element: Id, mut size: Size) -> Siz } size } +pub(crate) fn port_footer(p: &Project, element: Id) -> f32 { + let count = p + .children(element) + .filter(|e| e.kind() == Kind::Port) + .count(); + if count == 0 { + 24. + } else { + 28. * count as f32 + 24. + } +} pub(crate) fn parents(p: &Project, d: &Diagram) -> BTreeMap> { let placed: BTreeMap<_, _> = d @@ -62,12 +75,22 @@ pub(crate) fn parents(p: &Project, d: &Diagram) -> BTreeMap> { if d.projection == ProjectionKind::Allocation && let Some(performer) = crate::validation::allocation_summary(p, n.element) { - let keep_parent = semantic.is_some_and(|parent| { - crate::validation::allocation_summary(p, parent) == Some(performer) - }); - if !keep_parent { - semantic = Some(performer); + let mut candidate = semantic; + let mut visible_work_parent = None; + let mut seen = BTreeSet::new(); + while let Some(id) = candidate { + if !seen.insert(id) + || crate::validation::allocation_summary(p, id) != Some(performer) + { + break; + } + if placed.contains_key(&id) { + visible_work_parent = Some(id); + break; + } + candidate = p.elements.get(&id).and_then(|e| e.parent); } + semantic = visible_work_parent.or(Some(performer)); } if d.projection == ProjectionKind::Traceability { return (n.id, None); @@ -117,6 +140,10 @@ pub fn project_view(p: &Project, diagram: Id) -> ProjectedView { let Some(d) = p.diagrams.get(&diagram) else { return ProjectedView::default(); }; + project_diagram(p, d) +} +/// Project alternate placement geometry without copying or mutating semantics. +pub fn project_diagram(p: &Project, d: &Diagram) -> ProjectedView { let parents = parents(p, d); let mut nodes = Vec::new(); for n in d.nodes.values() { @@ -145,7 +172,18 @@ pub fn project_view(p: &Project, diagram: Id) -> ProjectedView { current = parents.get(&id).copied().flatten(); } if !hidden { - let size = minimum_node_size(p, e.id, n.size); + let size = minimum_node_size( + p, + e.id, + if n.collapsed { + Size { + width: n.size.width, + height: 94., + } + } else { + n.size + }, + ); nodes.push(ProjectedNode { id: n.id, element: n.element, @@ -154,6 +192,12 @@ pub fn project_view(p: &Project, diagram: Id) -> ProjectedView { visual_parent: parents.get(&n.id).copied().flatten(), depth, collapsed: n.collapsed, + allocation_summary: d.projection == ProjectionKind::Allocation + && crate::validation::allocation_summary(p, e.id).is_some() + && !p + .relations + .values() + .any(|r| r.kind() == RelationKind::Allocation && r.target() == e.id), }); } } @@ -164,11 +208,12 @@ pub fn project_view(p: &Project, diagram: Id) -> ProjectedView { .visual_parent .and_then(|id| nodes.iter().position(|n| n.id == id)) { + let footer = port_footer(p, nodes[parent].element); let p = &mut nodes[parent]; let right = (p.position.x + p.size.width).max(child.position.x + child.size.width + 24.); let bottom = - (p.position.y + p.size.height).max(child.position.y + child.size.height + 24.); + (p.position.y + p.size.height).max(child.position.y + child.size.height + footer); p.position.x = p.position.x.min(child.position.x - 24.); // Reserve two readable header lines above the first nested card. p.position.y = p.position.y.min(child.position.y - 64.); @@ -209,14 +254,23 @@ pub fn project_view(p: &Project, diagram: Id) -> ProjectedView { let side: Vec<_> = children.iter().filter(|e| matches!(e.shared(), Some(SharedBody::Port {direction: d, ..}) if *d == direction)).collect(); for (index, port) in side.iter().enumerate() { let fraction = (index + 1) as f32 / (side.len() + 1) as f32; + let y = if p.elements[&node.element].kind().is_performer() + || nodes + .iter() + .any(|child| child.visual_parent == Some(node.id)) + { + node.position.y + node.size.height - 24. - index as f32 * 28. + } else { + node.position.y + 64. + (node.size.height - 76.).max(0.) * fraction + }; let position = match direction { PortDirection::In => Position { x: node.position.x, - y: node.position.y + 64. + (node.size.height - 76.).max(0.) * fraction, + y, }, PortDirection::Out => Position { x: node.position.x + node.size.width, - y: node.position.y + 64. + (node.size.height - 76.).max(0.) * fraction, + y, }, PortDirection::InOut => Position { x: node.position.x + node.size.width * fraction, diff --git a/crates/oa-core/src/session.rs b/crates/oa-core/src/session.rs index b6666c4a..1237ed1e 100644 --- a/crates/oa-core/src/session.rs +++ b/crates/oa-core/src/session.rs @@ -680,7 +680,7 @@ fn layout(p: &mut Project, diagram: Id) -> Result<(), ModelError> { width = width.max(size.width + 48.); height += size.height + 16.; } - height += 8.; + height += crate::projection::port_footer(p, d.nodes[&id].element) - 16.; } else { height = own.height; } @@ -779,7 +779,7 @@ fn layout(p: &mut Project, diagram: Id) -> Result<(), ModelError> { row_height = 0.; } place(*id, Position { x, y }, &children, &sizes, &mut positions); - x += sizes[id].width + 60.; + x += sizes[id].width + 240.; row_height = row_height.max(sizes[id].height); } let d = p.diagrams.get_mut(&diagram).unwrap(); diff --git a/crates/oa-core/tests/release_diagrams.rs b/crates/oa-core/tests/release_diagrams.rs index c1525e0e..32a9c5e3 100644 --- a/crates/oa-core/tests/release_diagrams.rs +++ b/crates/oa-core/tests/release_diagrams.rs @@ -1,5 +1,76 @@ use oa_core::{projection::*, *}; +#[test] +fn unplaced_work_parent_cannot_detach_a_leaf_from_its_visible_performer() { + let mut p = Project::empty(); + let performer = p + .add_element(Kind::Entity, Layer::Oa, "Rescue team", None) + .unwrap(); + let work = p + .add_element(Kind::Activity, Layer::Oa, "Respond", None) + .unwrap(); + let leaf = p + .add_element(Kind::Activity, Layer::Oa, "Dispatch", Some(work)) + .unwrap(); + p.relate(RelationKind::Allocation, "Performs", performer, leaf); + let diagram = p.ensure_diagram(Layer::Oa); + p.diagrams.get_mut(&diagram).unwrap().projection = ProjectionKind::Allocation; + let owner = p.place(diagram, performer, Position { x: 0., y: 0. }); + let child = p.place(diagram, leaf, Position { x: 40., y: 80. }); + let view = project_view(&p, diagram); + assert_eq!( + view.nodes + .iter() + .find(|n| n.id == child) + .unwrap() + .visual_parent, + Some(owner) + ); + let summary = p.place(diagram, work, Position { x: 24., y: 64. }); + let view = project_view(&p, diagram); + assert!( + view.nodes + .iter() + .find(|n| n.id == summary) + .unwrap() + .allocation_summary + ); + assert!( + !view + .nodes + .iter() + .find(|n| n.id == child) + .unwrap() + .allocation_summary + ); + assert_eq!( + view.nodes + .iter() + .find(|n| n.id == child) + .unwrap() + .visual_parent, + Some(summary) + ); + p.diagrams.get_mut(&diagram).unwrap().projection = ProjectionKind::FunctionalDataflow; + assert!( + project_view(&p, diagram) + .nodes + .iter() + .all(|n| !n.allocation_summary) + ); + p.diagrams.get_mut(&diagram).unwrap().projection = ProjectionKind::Allocation; + p.diagrams.get_mut(&diagram).unwrap().nodes.remove(&summary); + let view = project_view(&p, diagram); + assert_eq!( + view.nodes + .iter() + .find(|n| n.id == child) + .unwrap() + .visual_parent, + Some(owner) + ); +} + #[test] fn architecture_is_nested_exchange_context_and_ports_attach_without_placements() { let p = Project::demo(); diff --git a/crates/oa-desktop/src/app.rs b/crates/oa-desktop/src/app.rs index 507b192e..ceba0099 100644 --- a/crates/oa-desktop/src/app.rs +++ b/crates/oa-desktop/src/app.rs @@ -873,7 +873,17 @@ impl App { .relations .get(&selected) .map(|r| vec![r.source(), r.target()]) - .unwrap_or_else(|| vec![selected]); + .unwrap_or_else(|| vec![selected]) + .into_iter() + .map(|id| { + self.project() + .elements + .get(&id) + .filter(|e| e.kind() == Kind::Port) + .and_then(|e| e.parent) + .unwrap_or(id) + }) + .collect::>(); let nodes = view .nodes .values() @@ -1076,11 +1086,15 @@ impl App { .cloned() { n.collapsed = !n.collapsed; - self.execute(Command::EditNode { + let selected = self.selected; + if self.execute(Command::EditNode { diagram, original: n.id, node: n, - }); + }) { + self.selected = selected; + self.refresh_draft(); + } } } Message::MoveNode(node, position) => { @@ -1421,28 +1435,35 @@ impl App { let id = e.id; let mut commands = vec![Command::CreateElement(e)]; let mut diagram_target = self.active_diagram; + let preferred = if self.create_kind.is_work() || self.create_kind.is_performer() { + Some(ProjectionKind::Allocation) + } else if ProjectionKind::Capabilities.includes(self.create_kind) { + Some(ProjectionKind::Capabilities) + } else { + None + }; if self.page == Page::Diagram && self .active_diagram .and_then(|id| self.project().diagrams.get(&id)) .is_some_and(|d| !d.projection.includes(self.create_kind)) - && ProjectionKind::Capabilities.includes(self.create_kind) + && let Some(preferred) = preferred { diagram_target = self .project() .diagrams .values() - .find(|d| d.layer == self.layer && d.projection == ProjectionKind::Capabilities) + .find(|d| d.layer == self.layer && d.projection == preferred) .map(|d| d.id); if diagram_target.is_none() { let view = Id::new_v4(); commands.push(Command::CreateDiagram(Diagram { id: view, - alias: self.project().fresh_alias("capabilities", "view", view), - name: format!("{} missions and capabilities", self.layer), + alias: self.project().fresh_alias("engineering_view", "view", view), + name: format!("{} {preferred}", self.layer), description: String::new(), layer: self.layer, - projection: ProjectionKind::Capabilities, + projection: preferred, nodes: Default::default(), })); diagram_target = Some(view); @@ -1486,25 +1507,98 @@ impl App { _ => unreachable!(), }, ); - let count = p.diagrams[&diagram].nodes.len(); - let node = p.place( - diagram, - id, - Position { - x: 60. + (count % 3) as f32 * 280., - y: 60. + (count / 3) as f32 * 150., - }, - ); + let owner = if allocated { + Some(self.selected) + } else { + parent + }; + // Insertion measures an expanded owner path and commits that reveal + // with the new child, so folded contents cannot overlap the new row. + if let Some(owner) = owner { + let mut expanded = p.diagrams[&diagram].clone(); + for node in expanded.nodes.values_mut() { + node.collapsed = false; + } + let expanded_view = oa_core::projection::project_diagram(&p, &expanded); + let mut current = expanded_view + .nodes + .iter() + .find(|n| n.element == owner) + .map(|n| n.id); + while let Some(id) = current { + let node = p + .diagrams + .get_mut(&diagram) + .unwrap() + .nodes + .get_mut(&id) + .unwrap(); + if node.collapsed { + node.collapsed = false; + commands.push(Command::EditNode { + diagram, + original: id, + node: node.clone(), + }); + } + current = expanded_view + .nodes + .iter() + .find(|n| n.id == id) + .and_then(|n| n.visual_parent); + } + } + // Reserve the expanded size of folded child containers so inserting + // a sibling does not overlap their contents when they are unfolded. + let mut expanded = p.diagrams[&diagram].clone(); + for node in expanded.nodes.values_mut() { + node.collapsed = false; + } + let view = oa_core::projection::project_diagram(&p, &expanded); + let position = + if let Some(container) = view.nodes.iter().find(|n| Some(n.element) == owner) { + let y = view + .nodes + .iter() + .filter(|n| n.visual_parent == Some(container.id)) + .map(|n| n.position.y + n.size.height + 16.) + .fold(container.position.y + 64., f32::max); + Position { + x: container.position.x + 24., + y, + } + } else { + Position { + x: view + .nodes + .iter() + .map(|n| n.position.x + n.size.width + 240.) + .fold(60., f32::max), + y: 60., + } + }; + let node = p.place(diagram, id, position); commands.push(Command::CreateNode { diagram, node: p.diagrams[&diagram].nodes[&node].clone(), }); } + if self.page == Page::Diagram + && let Some(diagram) = diagram_target + && let Ok(candidate) = execute_batch(self.project(), &commands) + { + commands.extend(crate::diagram::insertion_adjustments( + &candidate, diagram, id, + )); + } if self.execute(Command::Batch(commands)) { self.active_diagram = diagram_target; self.selected = id; self.inspector_tab = crate::navigation::InspectorTab::Properties; self.refresh_draft(); + if self.page == Page::Diagram { + self.fit(); + } self.status = "Element created · enter its engineering name and properties".into(); } } diff --git a/crates/oa-desktop/src/diagram.rs b/crates/oa-desktop/src/diagram.rs index 04130d54..c1334b5b 100644 --- a/crates/oa-desktop/src/diagram.rs +++ b/crates/oa-desktop/src/diagram.rs @@ -25,6 +25,101 @@ pub struct State { preview: Option, pan_start: Option, } +/// Make room along the inserted node's containment path, moving only colliding +/// later siblings and their descendants. Existing semantic ownership is unchanged. +pub fn insertion_adjustments(p: &Project, diagram_id: Id, element: Id) -> Vec { + let mut diagram = p.diagrams[&diagram_id].clone(); + // Reflow folded subtrees at their expanded size, without changing the + // user's fold state. Their hidden placements move with their container. + for node in diagram.nodes.values_mut() { + node.collapsed = false; + } + let view = oa_core::projection::project_diagram(p, &diagram); + let Some(inserted) = view.nodes.iter().find(|n| n.element == element) else { + return vec![]; + }; + let mut groups = Vec::new(); + let mut affected = inserted.id; + let mut parent = inserted.visual_parent; + loop { + groups.push((parent, affected)); + let Some(id) = parent else { + break; + }; + affected = id; + parent = view + .nodes + .iter() + .find(|n| n.id == id) + .and_then(|n| n.visual_parent); + } + for (group, affected) in groups { + let view = oa_core::projection::project_diagram(p, &diagram); + let mut siblings: Vec<_> = view + .nodes + .iter() + .filter(|n| n.visual_parent == group) + .collect(); + siblings.sort_by(|a, b| { + a.position + .y + .total_cmp(&b.position.y) + .then(a.position.x.total_cmp(&b.position.x)) + .then(a.id.cmp(&b.id)) + }); + let ids: Vec<_> = siblings.iter().map(|n| n.id).collect(); + let mut settled: Vec<(Rectangle, bool)> = Vec::new(); + for id in ids { + let current = oa_core::projection::project_diagram(p, &diagram); + let node = current.nodes.iter().find(|n| n.id == id).unwrap(); + let mut rect = Rectangle::new( + Point::new(node.position.x, node.position.y), + Size::new(node.size.width, node.size.height), + ); + let original_y = rect.y; + let displaced = id == affected + || settled + .iter() + .any(|(other, moved)| *moved && rect.intersects(other)); + if displaced { + loop { + let next_y = settled + .iter() + .filter(|(other, _)| rect.intersects(other)) + .map(|(other, _)| other.y + other.height + 24.) + .fold(rect.y, f32::max); + if next_y == rect.y { + break; + } + rect.y = next_y; + } + } + let dy = rect.y - original_y; + if dy > 0. { + let mut moved = oa_core::projection::descendant_nodes(p, diagram_id, id); + moved.push(id); + for moved in moved { + diagram.nodes.get_mut(&moved).unwrap().position.y += dy; + } + } + settled.push((rect, displaced)); + } + } + diagram + .nodes + .into_values() + .map(|mut node| { + node.collapsed = p.diagrams[&diagram_id].nodes[&node.id].collapsed; + node + }) + .filter(|n| p.diagrams[&diagram_id].nodes[&n.id] != *n) + .map(|node| Command::EditNode { + diagram: diagram_id, + original: node.id, + node, + }) + .collect() +} impl DiagramCanvas<'_> { fn world(&self, p: Point) -> Point { Point::new( @@ -68,30 +163,21 @@ impl DiagramCanvas<'_> { }) } fn preview_view(&self, state: &State) -> ProjectedView { - let mut view = project_view(self.project, self.diagram); if let (Some((id, _, original)), Some(preview)) = (state.drag, state.preview) { let dx = preview.x - original.x; let dy = preview.y - original.y; - let mut moved = BTreeSet::from([id]); - for n in &view.nodes { - if n.visual_parent.is_some_and(|p| moved.contains(&p)) { - moved.insert(n.id); - } - } - for n in &mut view.nodes { - if moved.contains(&n.id) { + let mut diagram = self.project.diagrams[&self.diagram].clone(); + let mut moved = oa_core::projection::descendant_nodes(self.project, self.diagram, id); + moved.push(id); + for id in moved { + if let Some(n) = diagram.nodes.get_mut(&id) { n.position.x += dx; n.position.y += dy; } } - for port in &mut view.ports { - if moved.contains(&port.owner) { - port.position.x += dx; - port.position.y += dy; - } - } + return oa_core::projection::project_diagram(self.project, &diagram); } - view + project_view(self.project, self.diagram) } } impl canvas::Program for DiagramCanvas<'_> { @@ -250,20 +336,7 @@ impl canvas::Program for DiagramCanvas<'_> { } else { Color::from_rgb8(144, 158, 173) }; - let capability_label = - self.project - .relations - .get(&edge.id) - .and_then(|r| match r.kind() { - RelationKind::CapabilityInclude => Some("«include»"), - RelationKind::CapabilityExtend => Some("«extend»"), - RelationKind::CapabilityGeneralization => Some("specializes"), - RelationKind::MissionCapability => Some("exploits"), - RelationKind::MissionInvolvement | RelationKind::CapabilityInvolvement => { - Some("participates") - } - _ => None, - }); + let capability_label = relationship_stereotype(self.project, edge.id); let mut stroke = Stroke::default() .with_color(color) @@ -418,23 +491,23 @@ fn paint_node(f: &mut Frame, p: &Project, n: &ProjectedNode, selected: Id, conta a: 1., }; f.fill(&path, if container { tint } else { Color::WHITE }); - f.stroke( - &path, - Stroke::default() - .with_color(if e.id == selected { color } else { style::LINE }) - .with_width(if e.id == selected { 2.6 } else { 1.2 }), - ); + let mut stroke = Stroke::default() + .with_color(if e.id == selected { color } else { style::LINE }) + .with_width(if e.id == selected { 2.6 } else { 1.2 }); + if n.allocation_summary { + stroke.line_dash = canvas::LineDash { + segments: &[6., 4.], + offset: 0, + }; + } + f.stroke(&path, stroke); f.fill_rectangle( Point::new(origin.x + 14., origin.y + 15.), Size::new(4., 12.), color, ); f.fill_text(Text { - content: format!( - "{}{}", - e.kind().label().to_uppercase(), - if n.collapsed { " +" } else { "" } - ), + content: node_header(e.kind(), n), position: Point::new(origin.x + 25., origin.y + 14.), color, size: 11.into(), @@ -447,19 +520,32 @@ fn paint_node(f: &mut Frame, p: &Project, n: &ProjectedNode, selected: Id, conta position: Point::new(origin.x + 14., origin.y + 35.), color: style::INK, size: 16.into(), + font: iced::Font { + style: if n.allocation_summary { + iced::font::Style::Italic + } else { + iced::font::Style::Normal + }, + ..iced::Font::DEFAULT + }, max_width: f32::INFINITY, ..Default::default() }); - if !container && size.height >= 86. { - f.fill_text(Text { - content: format!("@{}", short(&e.alias, max_chars + 6)), - position: Point::new(origin.x + 14., origin.y + 66.), - color: style::MUTED, - size: 10.5.into(), - max_width: f32::INFINITY, - ..Default::default() - }); - } +} +fn node_header(kind: Kind, node: &ProjectedNode) -> String { + let header = if node.allocation_summary { + format!( + "{} · SUMMARY", + if kind == Kind::Function { + "FUNCTION" + } else { + "ACTIVITY" + } + ) + } else { + kind.label().to_uppercase() + }; + format!("{header}{}", if node.collapsed { " +" } else { "" }) } fn highlighted_exchanges(p: &Project, selected: Id) -> BTreeSet { p.elements @@ -489,6 +575,18 @@ fn edge_endpoints(view: &ProjectedView, edge: &ProjectedEdge) -> Option<(Point, port_point(edge.target_port).unwrap_or(end), )) } +fn relationship_stereotype(p: &Project, id: Id) -> Option<&'static str> { + match p.relations.get(&id)?.kind() { + RelationKind::CapabilityInclude => Some("«include»"), + RelationKind::CapabilityExtend => Some("«extend»"), + RelationKind::CapabilityGeneralization => Some("specializes"), + RelationKind::MissionCapability => Some("exploits"), + RelationKind::MissionInvolvement | RelationKind::CapabilityInvolvement => { + Some("participates") + } + _ => None, + } +} fn endpoints(a: &ProjectedNode, b: &ProjectedNode) -> (Point, Point) { let ax = a.position.x + a.size.width / 2.; let ay = a.position.y + a.size.height / 2.; @@ -594,8 +692,13 @@ pub fn export_svg(p: &Project, diagram: Id) -> String { let color = hex(style::kind_color(e.kind())); let x = n.position.x; let y = n.position.y; + let (border, name_style) = if n.allocation_summary { + (" stroke-dasharray=\"6 4\"", " font-style=\"italic\"") + } else { + ("", "") + }; format!( - "{}{}", + "{}{}", n.size.width, n.size.height, if containers.contains(&n.id) { @@ -605,7 +708,7 @@ pub fn export_svg(p: &Project, diagram: Id) -> String { }, x + 14., y + 25., - escape(e.kind().label()), + escape(&node_header(e.kind(), n)), x + 14., y + 51., escape(&short( @@ -622,7 +725,27 @@ pub fn export_svg(p: &Project, diagram: Id) -> String { for edge in &view.edges { if let Some((a, b)) = edge_endpoints(&view, edge) { let mid = (a.x + b.x) / 2.; - svg.push_str(&format!("{}",a.x,a.y,a.y,b.y,b.x,b.y,escape(p.named(edge.id)))); + let stereotype = relationship_stereotype(p, edge.id); + let dashed = if matches!(stereotype, Some("«include»" | "«extend»")) { + " stroke-dasharray=\"6 4\"" + } else { + "" + }; + svg.push_str(&format!("{}",a.x,a.y,a.y,b.y,b.x,b.y,escape(p.named(edge.id)))); + if stereotype.is_some() + || matches!( + p.relations.get(&edge.id).map(|r| r.kind()), + Some( + RelationKind::Interaction + | RelationKind::FunctionalExchange + | RelationKind::BoundaryExchange + ) + ) + { + let label = stereotype.unwrap_or_else(|| p.named(edge.id)); + let center = curve_point(a, b, 0.5); + svg.push_str(&format!("{}",center.x-112.,center.y-30.,center.x,center.y-8.,escape(&short(label,32)))); + } } } for n in &view.nodes { @@ -632,6 +755,9 @@ pub fn export_svg(p: &Project, diagram: Id) -> String { } for port in &view.ports { svg.push_str(&format!("{}",escape(p.named(port.element)),port.position.x-7.,port.position.y-7.,port.position.x-4.,port.position.y)); + if port.direction == PortDirection::InOut { + svg.push_str(&format!("",port.position.x+4.,port.position.y,port.position.x,port.position.y)); + } } svg.push_str(""); svg @@ -641,6 +767,136 @@ pub fn export_svg(p: &Project, diagram: Id) -> String { mod tests { use super::*; #[test] + fn svg_distinguishes_inferred_work_allocation_from_direct_allocation() { + for (layer, performer_kind, work_kind, header) in [ + ( + Layer::Oa, + Kind::Entity, + Kind::Activity, + "ACTIVITY · SUMMARY", + ), + ( + Layer::Sa, + Kind::System, + Kind::Function, + "FUNCTION · SUMMARY", + ), + ] { + let mut p = Project::empty(); + let owner = p + .add_element(performer_kind, layer, "Performer", None) + .unwrap(); + let parent = p + .add_element(work_kind, layer, "Grouped work", None) + .unwrap(); + let child = p + .add_element(work_kind, layer, "Allocated leaf", Some(parent)) + .unwrap(); + p.relate(RelationKind::Allocation, "Performs", owner, child); + let diagram = p.ensure_diagram(layer); + p.diagrams.get_mut(&diagram).unwrap().projection = ProjectionKind::Allocation; + for id in [owner, parent, child] { + p.place(diagram, id, Position { x: 60., y: 60. }); + } + let p = execute_batch(&p, &[Command::Layout(diagram)]).unwrap(); + let svg = export_svg(&p, diagram); + let group = svg + .split("") + .find(|g| g.contains(">Grouped work")) + .unwrap(); + assert!(group.contains(&format!(">{header}"))); + assert!(group.contains("stroke-dasharray=\"6 4\"")); + assert!(group.contains("font-style=\"italic\"")); + let leaf = svg + .split("") + .find(|g| g.contains(">Allocated leaf")) + .unwrap(); + assert!(!leaf.contains("SUMMARY")); + assert!(!leaf.contains("stroke-dasharray")); + assert!(!leaf.contains("font-style=\"italic\"")); + assert!( + !p.relations + .values() + .any(|r| r.kind() == RelationKind::Allocation && r.target() == parent) + ); + } + } + #[test] + fn dragging_a_child_previews_the_same_enclosure_and_ports_as_commit() { + let p = Project::demo(); + let diagram = p + .diagrams + .values() + .find(|d| d.layer == Layer::Sa && d.projection == ProjectionKind::Allocation) + .unwrap() + .id; + let view = project_view(&p, diagram); + let child = view + .nodes + .iter() + .find(|n| n.visual_parent.is_some()) + .unwrap() + .id; + let original = p.diagrams[&diagram].nodes[&child].position; + let target = Position { + x: original.x - 400., + y: original.y - 200., + }; + let canvas = DiagramCanvas { + project: &p, + diagram, + selected: p.id, + zoom: 1., + pan: Vector::ZERO, + }; + let state = State { + drag: Some((child, Point::ORIGIN, original)), + preview: Some(target), + ..State::default() + }; + let preview = canvas.preview_view(&state); + let committed = execute_batch( + &p, + &[Command::MoveNode { + diagram, + node: child, + position: target, + with_descendants: true, + }], + ) + .unwrap(); + assert_eq!(preview, project_view(&committed, diagram)); + } + #[test] + fn svg_preserves_visible_exchange_labels_and_capability_stereotypes() { + let mut p = Project::demo(); + let diagram = p + .diagrams + .values() + .find(|d| d.layer == Layer::Sa && d.projection == ProjectionKind::Allocation) + .unwrap() + .id; + let view = project_view(&p, diagram); + let svg = export_svg(&p, diagram); + for edge in &view.edges { + assert!(svg.contains(&format!(">{}", escape(&short(p.named(edge.id), 32))))); + } + let a = p + .add_element(Kind::Capability, Layer::Oa, "Primary", None) + .unwrap(); + let b = p + .add_element(Kind::Capability, Layer::Oa, "Included", None) + .unwrap(); + let d = p.ensure_diagram(Layer::Oa); + p.diagrams.get_mut(&d).unwrap().projection = ProjectionKind::Capabilities; + p.place(d, a, Position { x: 0., y: 0. }); + p.place(d, b, Position { x: 400., y: 0. }); + p.relate(RelationKind::CapabilityInclude, "Uses", a, b); + let svg = export_svg(&p, d); + assert!(svg.contains("«include»")); + assert!(svg.contains("stroke-dasharray=\"6 4\"")); + } + #[test] fn implicit_port_click_selects_semantics_and_drag_preview_svg_share_anchors() { let p = Project::demo(); let diagram = p diff --git a/crates/oa-desktop/src/guide.rs b/crates/oa-desktop/src/guide.rs index ee654280..c2df6cdb 100644 --- a/crates/oa-desktop/src/guide.rs +++ b/crates/oa-desktop/src/guide.rs @@ -173,7 +173,7 @@ fn article(topic: Topic) -> Article { "Create an operational context", &[ "Choose New in the top bar. Use Project properties to name the model and describe its purpose. Apply changes commits the property draft.", - "On Architecture, choose Create architecture view. The initial Allocation projection shows work inside its performer.", + "On Architecture, choose Create architecture view. Architecture · allocated work shows work inside its performer.", "Choose Entity under Create element, then + At root. Name it Rescue coordinator and Apply changes. Use Actor for an external participant such as a Vessel in distress.", "Select Rescue coordinator, choose Activity, then + Allocated. Name the new activity Assess incident. It appears inside its performer; an Allocation relationship records that responsibility.", "Add a second activity for another participant. Select an activity, choose + Relationship, select Interaction and choose the compatible target. Name the exchange after what is conveyed.", @@ -239,7 +239,7 @@ fn article(topic: Topic) -> Article { "Choose the Operational or System perspective. Create participants using Entity/Actor in OA or System/System actor in SA.", "Create Activity in OA or Function in SA. Select existing work and use + In selected to decompose it into smaller work units.", "To create work for a participant, select the participant, choose Activity or Function, then + Allocated. To allocate existing work, use + Relationship with Allocation from the participant to the leaf work.", - "Open the Allocation projection to review responsibilities. Open Decomposition to review the activity/function hierarchy independently.", + "Choose Architecture · allocated work to review responsibilities. Choose Functional dataflow to review the activity/function hierarchy and its exchanges independently.", ], ), explain( @@ -274,7 +274,7 @@ fn article(topic: Topic) -> Article { "Choose and edit the relationship you mean", &[ "Use the diagram selector or + View to work with a focused diagram. View properties edits its name, perspective and projection.", - "Choose Decomposition to nest semantic children, or Allocation to nest work under its performer. Overview keeps a broader view; OA → SA displays counterpart traces.", + "Choose Containment for semantic children, Architecture · allocated work for responsibilities, Functional dataflow for work and exchanges, or Missions & capabilities for outcomes. All relationships is a broader exploration view; OA ↔ SA traceability displays counterparts.", "Select an element and edit Semantic parent to change ownership. Use an Allocation relationship to change responsibility. Apply changes validates the semantic change.", "Drag nodes to arrange the current view, scroll to zoom and use Fit to frame its contents. Arrange changes diagram geometry. Export SVG produces a shareable view.", "Select a diagram node to access Placement, Fold / unfold and Hide. Hide removes its view placement; Delete from model removes model records and requires review of the affected references.", @@ -284,6 +284,10 @@ fn article(topic: Topic) -> Article { "Keep diagrams readable", "Use separate views for responsibility, decomposition and cross-layer coverage. Place existing elements with Show in this diagram. A placement's Diagram field can relocate it while preserving its identity and artifact references. Do not duplicate a semantic element merely to show it in another view.", ), + explain( + "Read allocation summaries and ports", + "A dashed parent activity/function with an italic name and SUMMARY heading groups leaves assigned to the same performer. It has no direct allocation of its own; its inspector explains the leaf performer. Small ports belong to the boundary of their visible owner and are selectable model elements. Folding a container hides its inner work and ports; summary exchange lines do not invent new ports on the container.", + ), explain( "What nesting does not imply", "Containment in an allocation projection expresses a performer relationship. It is not a physical deployment statement. Physical deployment is a different architectural concern; do not infer hardware installation from an OA/SA box layout.", diff --git a/crates/oa-desktop/src/tests.rs b/crates/oa-desktop/src/tests.rs index 9a828417..e19cedb5 100644 --- a/crates/oa-desktop/src/tests.rs +++ b/crates/oa-desktop/src/tests.rs @@ -936,3 +936,299 @@ fn behavior_and_data_authoring_do_not_place_nodes_in_unrelated_architecture_view } } } + +#[test] +fn revealing_an_implicit_function_port_unfolds_its_visible_architecture_owner() { + let mut p = Project::demo(); + let diagram = p + .diagrams + .values() + .find(|d| d.layer == Layer::Sa && d.projection == ProjectionKind::Allocation) + .unwrap() + .id; + let view = oa_core::projection::project_view(&p, diagram); + let function = view + .nodes + .iter() + .find(|n| p.elements[&n.element].kind() == Kind::Function && n.visual_parent.is_some()) + .unwrap(); + let ancestor = function.visual_parent.unwrap(); + let port = p + .children(function.element) + .find(|e| e.kind() == Kind::Port) + .unwrap() + .id; + p.diagrams + .get_mut(&diagram) + .unwrap() + .nodes + .get_mut(&ancestor) + .unwrap() + .collapsed = true; + assert!(crate::navigation::diagrams_containing(&p, port).contains(&diagram)); + let mut app = App::with_project(p); + send(&mut app, Message::RevealInDiagram(diagram, port)); + assert_eq!(app.selected, port); + assert_eq!(app.active_diagram, Some(diagram)); + assert!(!app.project().diagrams[&diagram].nodes[&ancestor].collapsed); + assert!( + oa_core::projection::project_view(app.project(), diagram) + .ports + .iter() + .any(|p| p.element == port) + ); +} + +#[test] +fn creation_from_capabilities_routes_work_to_architecture_and_folded_allocation_inserts_below_existing_work() + { + let p = Project::demo(); + let system = p + .elements + .values() + .find(|e| e.kind() == Kind::System) + .unwrap() + .id; + let capabilities = p + .diagrams + .values() + .find(|d| d.layer == Layer::Sa && d.projection == ProjectionKind::Capabilities) + .unwrap() + .id; + let mut app = App::with_project(p); + send(&mut app, Message::Layer(Layer::Sa)); + send( + &mut app, + Message::Diagram(crate::app::Choice { + id: capabilities, + label: String::new(), + }), + ); + send(&mut app, Message::CreateKind(Kind::Function)); + send(&mut app, Message::Add(false)); + let diagram = app.active_diagram.unwrap(); + assert_eq!( + app.project().diagrams[&diagram].projection, + ProjectionKind::Allocation + ); + assert!( + app.project().diagrams[&diagram] + .nodes + .values() + .any(|n| n.element == app.selected) + ); + send(&mut app, Message::Select(system)); + let owner = app.selected_node.unwrap(); + send(&mut app, Message::ToggleCollapse); + assert!(app.project().diagrams[&diagram].nodes[&owner].collapsed); + assert_eq!( + app.selected, system, + "Folding must retain semantic selection" + ); + let before = app.project().clone(); + send(&mut app, Message::Add(true)); + let created = app.selected; + let view = oa_core::projection::project_view(app.project(), diagram); + let child = view + .nodes + .iter() + .find(|n| n.element == created) + .unwrap_or_else(|| panic!("Created work is not visible: {}", app.status)); + assert_eq!(child.visual_parent, Some(owner)); + assert!(!app.project().diagrams[&diagram].nodes[&owner].collapsed); + assert!( + view.nodes + .iter() + .filter(|n| n.visual_parent == Some(owner) && n.id != child.id) + .all(|n| n.position.y + n.size.height <= child.position.y) + ); + let parent = view.nodes.iter().find(|n| n.id == owner).unwrap(); + assert!( + view.nodes + .iter() + .filter(|n| n.visual_parent.is_none() && n.id != owner) + .all(|n| n.position.x + n.size.width <= parent.position.x + || parent.position.x + parent.size.width <= n.position.x + || n.position.y + n.size.height <= parent.position.y + || parent.position.y + parent.size.height <= n.position.y) + ); + send(&mut app, Message::Undo); + assert_eq!(app.project(), &before); +} + +#[test] +fn nested_allocation_insertion_reflows_sibling_subtrees_and_preserves_fold_state() { + use oa_core::projection::{project_diagram, project_view}; + for folded in [false, true] { + let mut p = Project::empty(); + let root = p + .add_element(Kind::Entity, Layer::Oa, "Root", None) + .unwrap(); + let a = p + .add_element(Kind::Entity, Layer::Oa, "A", Some(root)) + .unwrap(); + let b = p + .add_element(Kind::Entity, Layer::Oa, "B", Some(root)) + .unwrap(); + let other = p + .add_element(Kind::Entity, Layer::Oa, "Other root", None) + .unwrap(); + let a_work = p + .add_element(Kind::Activity, Layer::Oa, "A work", None) + .unwrap(); + let b_work = p + .add_element(Kind::Activity, Layer::Oa, "B work", None) + .unwrap(); + let b_port = p + .add_element(Kind::Port, Layer::Oa, "B boundary", Some(b)) + .unwrap(); + p.relate(RelationKind::Allocation, "A performs", a, a_work); + p.relate(RelationKind::Allocation, "B performs", b, b_work); + let diagram = p.ensure_diagram(Layer::Oa); + p.diagrams.get_mut(&diagram).unwrap().projection = ProjectionKind::Allocation; + for id in [root, a, b, other, a_work, b_work] { + p.place(diagram, id, Position { x: 60., y: 60. }); + } + let mut p = execute_batch(&p, &[Command::Layout(diagram)]).unwrap(); + let view = project_view(&p, diagram); + let root_node = view.nodes.iter().find(|n| n.element == root).unwrap(); + let a_node = view.nodes.iter().find(|n| n.element == a).unwrap(); + let b_node = view.nodes.iter().find(|n| n.element == b).unwrap(); + // Layout's UUID order is intentionally irrelevant to this scenario: + // explicitly put A before B, as a user can arrange these participants. + p = execute_batch( + &p, + &[ + Command::MoveNode { + diagram, + node: a_node.id, + position: Position { + x: root_node.position.x + 24., + y: root_node.position.y + 64., + }, + with_descendants: true, + }, + Command::MoveNode { + diagram, + node: b_node.id, + position: Position { + x: root_node.position.x + 24., + y: root_node.position.y + 64. + a_node.size.height + 16., + }, + with_descendants: true, + }, + ], + ) + .unwrap(); + let view = project_view(&p, diagram); + let root_node = view.nodes.iter().find(|n| n.element == root).unwrap(); + let other_node = view.nodes.iter().find(|n| n.element == other).unwrap().id; + let b_node = view.nodes.iter().find(|n| n.element == b).unwrap().id; + let b_work_node = view.nodes.iter().find(|n| n.element == b_work).unwrap().id; + p.diagrams + .get_mut(&diagram) + .unwrap() + .nodes + .get_mut(&other_node) + .unwrap() + .position = Position { + x: root_node.position.x, + y: root_node.position.y + root_node.size.height + 24., + }; + p.diagrams + .get_mut(&diagram) + .unwrap() + .nodes + .get_mut(&b_node) + .unwrap() + .collapsed = folded; + // Deliberately overlapping unrelated roots must not be rearranged. + let mut unrelated = Vec::new(); + for name in ["Unrelated one", "Unrelated two"] { + let id = p.add_element(Kind::Entity, Layer::Oa, name, None).unwrap(); + unrelated.push(p.place(diagram, id, Position { x: 2000., y: 1000. })); + } + let before = p.clone(); + let mut expanded = p.diagrams[&diagram].clone(); + expanded.nodes.get_mut(&b_node).unwrap().collapsed = false; + let before_view = project_diagram(&p, &expanded); + let before_port = before_view + .ports + .iter() + .find(|p| p.element == b_port) + .unwrap() + .position; + let mut app = App::with_project(p); + send(&mut app, Message::Select(a)); + send(&mut app, Message::CreateKind(Kind::Activity)); + send(&mut app, Message::Add(true)); + let created = app.selected; + assert_eq!( + app.project().elements[&created].kind(), + Kind::Activity, + "{}", + app.status + ); + let after = &app.project().diagrams[&diagram]; + assert_eq!(after.nodes[&b_node].collapsed, folded); + let dy = + after.nodes[&b_node].position.y - before.diagrams[&diagram].nodes[&b_node].position.y; + assert!(dy > 0., "B must move below the enlarged A"); + assert_eq!( + after.nodes[&b_work_node].position.y, + before.diagrams[&diagram].nodes[&b_work_node].position.y + dy + ); + assert!( + after.nodes[&other_node].position.y + > before.diagrams[&diagram].nodes[&other_node].position.y + ); + for id in unrelated { + assert_eq!(after.nodes[&id], before.diagrams[&diagram].nodes[&id]); + } + let mut expanded = after.clone(); + expanded.nodes.get_mut(&b_node).unwrap().collapsed = false; + let view = project_diagram(app.project(), &expanded); + let after_port = view + .ports + .iter() + .find(|p| p.element == b_port) + .unwrap() + .position; + assert_eq!( + after_port, + Position { + x: before_port.x, + y: before_port.y + dy + } + ); + for (left, right) in [(a, b), (root, other), (a_work, created)] { + let left = view.nodes.iter().find(|n| n.element == left).unwrap(); + let right = view.nodes.iter().find(|n| n.element == right).unwrap(); + assert!(left.position.y + left.size.height <= right.position.y); + } + assert!(crate::diagram::insertion_adjustments(app.project(), diagram, created).is_empty()); + send(&mut app, Message::Undo); + assert_eq!( + app.project(), + &before, + "Creation and all reflow must undo together" + ); + + if folded { + send(&mut app, Message::Select(root)); + send(&mut app, Message::CreateKind(Kind::Entity)); + send(&mut app, Message::Add(true)); + let mut expanded = app.project().diagrams[&diagram].clone(); + expanded.nodes.get_mut(&b_node).unwrap().collapsed = false; + let view = project_diagram(app.project(), &expanded); + let b = view.nodes.iter().find(|n| n.id == b_node).unwrap(); + let created = view + .nodes + .iter() + .find(|n| n.element == app.selected) + .unwrap(); + assert!(b.position.y + b.size.height <= created.position.y); + assert!(app.project().diagrams[&diagram].nodes[&b_node].collapsed); + } + } +} diff --git a/crates/oa-desktop/src/views.rs b/crates/oa-desktop/src/views.rs index 3dc71441..3f7fb3fa 100644 --- a/crates/oa-desktop/src/views.rs +++ b/crates/oa-desktop/src/views.rs @@ -599,6 +599,23 @@ fn inspector(app: &App) -> View<'_, Message> { .width(Fill), ); } + if !p + .relations + .values() + .any(|r| r.kind() == RelationKind::Allocation && r.target() == e.id) + && let Some(performer) = oa_core::validation::allocation_summary(p, e.id) + { + body = body.push(label( + "Allocation summary: all leaf activities or functions belong to the same performer. The parent has no direct allocation.", + )); + body = body.push( + action( + &format!("Leaf performer: {}", short(p.named(performer), 24)), + Message::Select(performer), + ) + .width(Fill), + ); + } if e.kind() == Kind::Port { body = body.push(label( "Shown automatically on the boundary of its visible owner.", diff --git a/examples/coastal-rescue.arcadia b/examples/coastal-rescue.arcadia index 13395396..cb117a65 100644 --- a/examples/coastal-rescue.arcadia +++ b/examples/coastal-rescue.arcadia @@ -1,93 +1,16 @@ arcadia 2; -project mission "Coastal rescue — operational need to system behavior" id "eceea6cd-108b-45a9-9505-8b7fa462af96" { +project mission "Coastal rescue — operational need to system behavior" id "7fd2d957-d964-4cc5-a3f3-3f42aa6f04ca" { description "A worked OA/SA example. Compare allocation and functional decomposition views; inspect traces, repeated scenario messages, interface contracts, degraded modes, and external engineering artifacts."; - sa_lifeline vessel_service_lifeline "Vessel service lifeline" id "03b71dc5-435f-4c7f-923a-cb6e672212ba" { - description ""; - parent @repeated_distress_reports; - represented @vessel_communication_service; - } - - sa_initial start_reporting "Start reporting" id "0deb4c4c-d7cc-4dd9-bcc5-f357387cf978" { - description ""; - do_activity ""; - entry ""; - exit ""; - kind Initial; - parent @reporting_quality_region; - } - - sa_state_machine reporting_operation_modes "Reporting operation modes" id "1a1b215a-c102-4948-9c88-dabfadc8e08e" { - description ""; - parent @rescue_coordination_system; - } - - sa_exchange_item backup_electrical_energy "Backup electrical energy" id "1b81d963-06e7-42d3-af31-bf5236829477" { - description ""; - kind Energy; - parent none; - } - - sa_lifeline coordination_system_lifeline "Coordination system lifeline" id "1f7da722-c91e-4d0e-a344-c1a2511dd96b" { - description ""; - parent @repeated_distress_reports; - represented @rescue_coordination_system; - } - - sa_mission support_timely_rescue_decisions "Support timely rescue decisions" id "218e9ac0-1fdb-4ce8-bbcb-4cc5c36b3746" { - description ""; - parent none; - } - - sa_occurrence updated_distress_report "Updated distress report" id "28b8e56d-7ddf-4950-8c30-7385c044cc72" { - body { - Exchange { - exchange @validated_distress_report; - receiver @coordination_system_lifeline; - sender @vessel_service_lifeline; - }; - }; - description ""; - parent @repeated_distress_reports; - postcondition "The incident position is refreshed without creating a second incident."; - precondition "The vessel has more recent position information."; - } - - oa_activity assess_incident "Assess incident" id "3388cc0d-0abc-4479-a948-6740266ec236" { - description ""; - parent @respond_to_distress; - } - - sa_constraint response_time_budget "Response time budget" id "3584d050-0b4e-4620-bbea-8c3c87d2a19f" { - constrained [@classify_incident_and_alert_operator, @validated_distress_report]; - description ""; - expression "incident_alert_latency <= 120 s"; - parent none; - } - - sa_system rescue_coordination_system "Rescue coordination system" id "47e28c63-803b-4ea6-af92-e778f62ecc3e" { - description ""; - parent none; - } - - sa_functional_chain digital_distress_handling "Digital distress handling" id "49743116-7777-4df8-9601-74fd4cba22c0" { - description ""; - parent none; - steps [@report_handled]; - } - - oa_process distress_to_response "Distress to response" id "51c8ed9f-93ea-45fe-8829-e4ec88f09ce5" { - description ""; - parent none; - steps [@distress_received]; - } - - oa_occurrence distress_received "Distress received" id "5e0c0d0e-5eb5-467c-bc35-dfe29d534703" { + oa_occurrence distress_received "Distress received" id "1c1b700a-45e2-418d-8f1c-40e57e409434" { body { Exchange { exchange @distress_signal; + message_kind Asynchronous; receiver none; + reply_to none; sender none; + values []; }; }; description ""; @@ -96,58 +19,151 @@ project mission "Coastal rescue — operational need to system behavior" id "ece precondition ""; } - sa_exchange_item digital_distress_report "Digital distress report" id "5e16affb-7fa4-4a3d-8bfe-6340586ab83f" { - description ""; - kind Information; - parent none; - } - - oa_capability protect_life_at_sea "Protect life at sea" id "6ca5efd6-2e92-4508-a02d-4013793743cb" { + sa_system rescue_coordination_system "Rescue coordination system" id "2027bca4-204e-40fe-a6af-fa2f74e4ce0e" { description ""; parent none; } - sa_port report_function_output "Report function output" id "6ecf32ed-4009-48ba-b374-3bf156f6c355" { + sa_initial start_reporting "Start reporting" id "26df594f-d55c-4d83-9907-fabad1e27572" { + description ""; + do_activity ""; + entry ""; + exit ""; + kind Initial; + parent @reporting_quality_region; + } + + sa_region reporting_quality_region "Reporting quality region" id "27c7dfaa-6a65-41e9-bf1a-1b1ba58912d5" { + description ""; + parent @reporting_operation_modes; + } + + sa_port vessel_reporting_output "Vessel reporting output" id "2a9f2d3a-45eb-4a9b-b2aa-284d8ccb961b" { description ""; direction Out; interface @distress_reporting_interface; - parent @transmit_distress_report; + parent @vessel_communication_service; } - oa_entity rescue_coordination "Rescue coordination" id "721b68ab-5136-408e-890d-925215d5661e" { + oa_capability protect_life_at_sea "Protect life at sea" id "334793e5-fdfd-427e-89d5-7cc91283c75a" { description ""; parent none; } - sa_capability coordinate_rescue_response "Coordinate rescue response" id "7781bd9f-e788-4049-9af4-9a3eab40d377" { + sa_functional_chain digital_distress_handling "Digital distress handling" id "34f9ddb2-bb79-4658-8932-c8393b9f5022" { + description ""; + parent none; + steps [@report_handled]; + } + + oa_role incident_coordinator "Incident coordinator" id "39ba0d44-3f9d-4d98-bf9a-6c9b8c5ed041" { description ""; parent none; } - oa_actor vessel_in_distress "Vessel in distress" id "7e8ea298-1c68-4c9e-994d-6008d47f62ce" { + oa_activity report_distress "Report distress" id "3e0a28ce-335f-4d39-80ac-5c04a0a22a7f" { + description ""; + parent @respond_to_distress; + } + + sa_mission support_timely_rescue_decisions "Support timely rescue decisions" id "42bc4bd3-dab1-4b5b-9815-a5fd36a939f0" { description ""; parent none; } - oa_exchange_item distress_report "Distress report" id "835c2e84-f4e9-4592-b5df-d205803d97b7" { + sa_constraint response_time_budget "Response time budget" id "434a0fad-4e61-4211-839e-5f6fde77f1b1" { + constrained [@classify_incident_and_alert_operator, @validated_distress_report]; + description ""; + expression "incident_alert_latency <= 120 s"; + parent none; + } + + sa_capability coordinate_rescue_response "Coordinate rescue response" id "521b8f60-174d-47a4-a672-efff675ebf82" { + description ""; + parent none; + } + + oa_entity rescue_coordination "Rescue coordination" id "5b8669e9-5071-4ef5-a7c4-ebb45f662841" { + description ""; + parent none; + } + + sa_exchange_item digital_distress_report "Digital distress report" id "5de7b2ef-8012-484a-be40-5b4ce883223f" { description ""; kind Information; parent none; } - sa_port system_reporting_input "System reporting input" id "8477d19d-4a62-43bb-a7e3-845b9b3d1002" { - description ""; - direction In; - interface @distress_reporting_interface; - parent @rescue_coordination_system; - } - - sa_occurrence initial_distress_report "Initial distress report" id "84a0db92-ac74-493a-af29-74ec7715d7fa" { + sa_occurrence updated_distress_report "Updated distress report" id "5f09f99a-584a-4917-8b5d-4fda45f4932e" { body { Exchange { exchange @validated_distress_report; + message_kind Asynchronous; receiver @coordination_system_lifeline; + reply_to none; sender @vessel_service_lifeline; + values []; + }; + }; + description ""; + parent @repeated_distress_reports; + postcondition "The incident position is refreshed without creating a second incident."; + precondition "The vessel has more recent position information."; + } + + sa_exchange_item rescue_supply_package "Rescue supply package" id "75399008-b0ef-49c7-b403-35337b3b2c40" { + description ""; + kind Material; + parent none; + } + + sa_event report_timeout "Report timeout" id "7d7a7b65-c6df-42fc-bc94-3162261ad107" { + body { + Time { + expression "30 s"; + kind After; + }; + }; + description ""; + parent none; + } + + sa_lifeline coordination_system_lifeline "Coordination system lifeline" id "80f59f52-26ae-486c-8e9a-5ba032223362" { + description ""; + parent @repeated_distress_reports; + represented @rescue_coordination_system; + } + + oa_process distress_to_response "Distress to response" id "86aa4bf3-6543-4e81-929b-f0fc3482ff77" { + description ""; + parent none; + steps [@distress_received]; + } + + sa_event validated_report_received "Validated report received" id "8be42c58-6486-4038-aaa9-5aea2dce3b65" { + body { + Signal { + items [@digital_distress_report]; + }; + }; + description ""; + parent none; + } + + sa_actor vessel_communication_service "Vessel communication service" id "8cda5e33-5731-40af-91d1-9060ea723935" { + description ""; + parent none; + } + + sa_occurrence initial_distress_report "Initial distress report" id "90d07c73-a950-4a68-8b65-c3964dfe5d19" { + body { + Exchange { + exchange @validated_distress_report; + message_kind Asynchronous; + receiver @coordination_system_lifeline; + reply_to none; + sender @vessel_service_lifeline; + values []; }; }; description ""; @@ -156,57 +172,12 @@ project mission "Coastal rescue — operational need to system behavior" id "ece precondition ""; } - sa_port vessel_reporting_output "Vessel reporting output" id "a0e18d73-a9ce-4e9e-8ecf-0a54b1412932" { - description ""; - direction Out; - interface @distress_reporting_interface; - parent @vessel_communication_service; - } - - sa_function transmit_distress_report "Transmit distress report" id "b0a649d6-0558-48f5-8437-161be8329159" { - description ""; - parent @manage_distress_response; - } - - sa_function classify_incident_and_alert_operator "Classify incident and alert operator" id "b1cc95c7-1d2f-42d0-9d93-587954bd563b" { - description ""; - parent @manage_distress_response; - } - - sa_occurrence report_handled "Report handled" id "bcdb57f1-5fa8-46ce-9498-b467cea5d98f" { - body { - Exchange { - exchange @validated_distress_report; - receiver none; - sender none; - }; - }; - description ""; - parent @digital_distress_handling; - postcondition ""; - precondition ""; - } - - sa_function manage_distress_response "Manage distress response" id "c64f93a7-bf47-42b5-b432-7589b9144f2c" { + oa_activity respond_to_distress "Respond to distress" id "9526e01a-1936-48fc-9b84-4639f63b9370" { description ""; parent none; } - sa_actor vessel_communication_service "Vessel communication service" id "cfb45cf5-bebe-4632-9bde-0ee023c42583" { - description ""; - parent none; - } - - sa_mode normal_reporting "Normal reporting" id "d00b5d17-8660-4955-a70d-988a6e6b6c4e" { - description ""; - do_activity ""; - entry ""; - exit ""; - kind Mode; - parent @reporting_quality_region; - } - - sa_data_field reported_latitude "Reported latitude" id "d0f0b612-f0b9-451e-b0d2-5e74eedb2f36" { + sa_data_field reported_latitude "Reported latitude" id "9bd00e8c-125f-4b38-bd15-16571af01d89" { description ""; maximum 1; minimum 1; @@ -215,12 +186,36 @@ project mission "Coastal rescue — operational need to system behavior" id "ece unit "degrees north"; } - oa_activity report_distress "Report distress" id "d50e92c4-840e-4822-bcf7-033feb2eb879" { + sa_lifeline vessel_service_lifeline "Vessel service lifeline" id "9bdd35fb-5bb7-41a7-a909-a3a97d07ae33" { description ""; - parent @respond_to_distress; + parent @repeated_distress_reports; + represented @vessel_communication_service; } - sa_mode degraded_reporting "Degraded reporting" id "d7fad7e9-d799-4fa6-b49f-1304d3285b5e" { + sa_port assessment_function_input "Assessment function input" id "a1bd6431-2823-45b6-b669-27a2f6ecee24" { + description ""; + direction In; + interface @distress_reporting_interface; + parent @classify_incident_and_alert_operator; + } + + sa_exchange_item backup_electrical_energy "Backup electrical energy" id "b00cb246-cbde-49cd-b9c3-f22d7bdd96ec" { + description ""; + kind Energy; + parent none; + } + + sa_function classify_incident_and_alert_operator "Classify incident and alert operator" id "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d" { + description ""; + parent @manage_distress_response; + } + + oa_actor vessel_in_distress "Vessel in distress" id "b9dd4745-a110-4ff0-a599-f00f9e45bb88" { + description ""; + parent none; + } + + sa_mode degraded_reporting "Degraded reporting" id "bf5895c7-565c-4181-a604-6d338c019b12" { description ""; do_activity ""; entry ""; @@ -229,157 +224,206 @@ project mission "Coastal rescue — operational need to system behavior" id "ece parent @reporting_quality_region; } - sa_exchange_item rescue_supply_package "Rescue supply package" id "eb8cf40e-8194-403f-9896-f968790a9504" { + sa_state_machine reporting_operation_modes "Reporting operation modes" id "c3945ca6-698b-4e7c-888d-2bb3788caffc" { description ""; - kind Material; - parent none; + parent @rescue_coordination_system; } - sa_region reporting_quality_region "Reporting quality region" id "edc1ad70-8fc9-42a1-a668-05c4738bb225" { + sa_port system_reporting_input "System reporting input" id "c68d6903-8ebe-4976-9f0c-835553fabd72" { description ""; - parent @reporting_operation_modes; + direction In; + interface @distress_reporting_interface; + parent @rescue_coordination_system; } - sa_interface distress_reporting_interface "Distress reporting interface" id "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4" { + sa_occurrence report_handled "Report handled" id "d48ccc42-f422-4026-b5c2-68bbe830abf6" { + body { + Exchange { + exchange @validated_distress_report; + message_kind Asynchronous; + receiver none; + reply_to none; + sender none; + values []; + }; + }; description ""; - items [@digital_distress_report]; - parent none; + parent @digital_distress_handling; + postcondition ""; + precondition ""; } - oa_role incident_coordinator "Incident coordinator" id "f59b18f3-aa83-4050-9bc8-06ea0efaaa4b" { + sa_function transmit_distress_report "Transmit distress report" id "d6b99909-2b10-41d5-8423-40afb3905673" { description ""; - parent none; + parent @manage_distress_response; } - sa_scenario repeated_distress_reports "Repeated distress reports" id "f7514a9c-933c-4133-8b77-37c0dccd935f" { + sa_scenario repeated_distress_reports "Repeated distress reports" id "df3b4429-398d-4d66-869b-784183e1e62d" { context @coordinate_rescue_response; description ""; parent none; postcondition "The operator has a classified incident with the latest vessel report."; precondition "A vessel has detected an emergency and the reporting service is available."; steps [@initial_distress_report, @updated_distress_report]; + viewpoint BoundaryInterface; } - oa_activity respond_to_distress "Respond to distress" id "fa23a2a8-6f13-49e3-be47-f757f26d5c9f" { + sa_interface distress_reporting_interface "Distress reporting interface" id "e13f9bc0-b8c7-4e91-b481-3732d6c08168" { + description ""; + items [@digital_distress_report]; + parent none; + } + + sa_mode normal_reporting "Normal reporting" id "e5c72171-cd6a-49c6-be3d-db3bd48bc978" { + description ""; + do_activity ""; + entry ""; + exit ""; + kind Mode; + parent @reporting_quality_region; + } + + oa_exchange_item distress_report "Distress report" id "e74f3d77-766b-4a94-85cb-4a1e6fe4cf10" { + description ""; + kind Information; + parent none; + } + + oa_activity assess_incident "Assess incident" id "ebea3af4-39f1-4582-91ee-52fbdbd03b9f" { + description ""; + parent @respond_to_distress; + } + + sa_port report_function_output "Report function output" id "f32ed660-9ef2-45a6-ab83-9ae0db133fda" { + description ""; + direction Out; + interface @distress_reporting_interface; + parent @transmit_distress_report; + } + + sa_function manage_distress_response "Manage distress response" id "fea9acb1-fa3a-4001-9677-784caf97c15b" { description ""; parent none; } - sa_port assessment_function_input "Assessment function input" id "fa6051e1-0e60-4a1e-bfa1-f7111e06b74f" { + allocation assesses_incident "Assesses incident" id "01605431-cd83-4db9-aa81-a230ba6a2bf6" { description ""; - direction In; - interface @distress_reporting_interface; - parent @classify_incident_and_alert_operator; + source @rescue_coordination; + target @assess_incident; } - state_transition signal_restored "Signal restored" id "00e36d6e-78e8-476a-bbd6-a6e3bcd5a018" { + boundary_exchange distress_reporting_connection "Distress reporting connection" id "03b5cafa-6560-495e-9ad3-c7069e75a44e" { description ""; - effect "Clear the degraded-reporting alert."; - guard "position_is_current"; - source @degraded_reporting; - target @normal_reporting; - trigger "validated_report_received"; + items [@digital_distress_report]; + source @vessel_reporting_output; + target @system_reporting_input; } - state_action review_on_degraded_entry "Review on degraded entry" id "044cdc5f-a34a-4e51-9774-c1774a33dc91" { + mission_capability mission_capability "Mission capability" id "084e26f6-d26b-4de5-8560-8eb19bc7b3dc" { + description ""; + source @support_timely_rescue_decisions; + target @coordinate_rescue_response; + } + + chain_involvement functional_chain_support "Functional chain support" id "0b00c34d-bf48-46cf-bb46-43556b575fbc" { + description ""; + source @digital_distress_handling; + target @coordinate_rescue_response; + } + + state_action review_on_degraded_entry "Review on degraded entry" id "0eca6687-28a9-479e-9fe0-485bf1a7a22e" { description ""; phase Entry; source @degraded_reporting; target @classify_incident_and_alert_operator; } - allocation assesses_incident "Assesses incident" id "17fef4ab-acc7-4f21-b70d-5d64f6ad1261" { - description ""; - source @rescue_coordination; - target @assess_incident; - } - - availability assessment_in_degraded_mode "Assessment in degraded mode" id "2c092728-eafb-47e3-bcc7-8b795e36a25e" { - description ""; - source @classify_incident_and_alert_operator; - target @degraded_reporting; - } - - state_transition signal_degraded "Signal degraded" id "331c78a2-b6b3-452f-a238-84a6a3df3547" { + state_transition signal_degraded "Signal degraded" id "3fced0b9-2362-4ac4-8caa-45aac3674412" { description ""; effect "Flag the incident and request an operator review."; + effects []; guard "seconds_since_last_report > 30"; source @normal_reporting; target @degraded_reporting; + transition_kind External; trigger "report_timeout"; + triggers [@report_timeout]; } - capability_involvement system_capability_support "System capability support" id "39ff3786-d94c-40ad-90fa-c009ab6f53f9" { + availability assessment_in_normal_mode "Assessment in normal mode" id "401033be-3111-4e4f-a66a-4ff56d61670c" { description ""; source @classify_incident_and_alert_operator; - target @coordinate_rescue_response; - } - - chain_involvement operational_realization "Operational realization" id "41d934ba-76f7-4425-b433-2d4d293ab0df" { - description ""; - source @distress_to_response; - target @protect_life_at_sea; - } - - role_realization fulfils_coordinator_role "Fulfils coordinator role" id "4cf85b5a-eb4c-40f1-8bfc-06b30b24a9ef" { - description ""; - source @rescue_coordination; - target @incident_coordinator; - } - - state_transition initialize_reporting "Initialize reporting" id "5d34a01d-0dad-4a68-9b3b-998dce0d6e9b" { - description ""; - effect ""; - guard ""; - source @start_reporting; target @normal_reporting; - trigger ""; } - capability_involvement operational_contribution "Operational contribution" id "64ab242b-6043-4452-9b28-7205fec309df" { - description ""; - source @assess_incident; - target @protect_life_at_sea; - } - - interaction distress_signal "Distress signal" id "689a8e09-b7ca-4d97-b551-a21e3b438bfe" { + interaction distress_signal "Distress signal" id "56fdbdda-a9a7-48b4-9512-d0cec7f9066d" { description ""; items [@distress_report]; source @report_distress; target @assess_incident; } - allocation vessel_transmission "Vessel transmission" id "6a82e148-d38e-4103-8481-046b4c474952" { + role_realization fulfils_coordinator_role "Fulfils coordinator role" id "65c050ec-af57-449f-a3d6-5f867c9d121a" { description ""; - source @vessel_communication_service; - target @transmit_distress_report; + source @rescue_coordination; + target @incident_coordinator; } - interface_requirement reporting_service_required "Reporting service required" id "7c32cbe5-0821-4793-a37f-9f017fc8a3f4" { - description ""; - source @rescue_coordination_system; - target @distress_reporting_interface; - } - - chain_involvement functional_chain_support "Functional chain support" id "92468388-63c2-4f2c-a1fd-2c3f27b76398" { - description ""; - source @digital_distress_handling; - target @coordinate_rescue_response; - } - - allocation system_assessment "System assessment" id "93e3a60d-33c0-4110-83d9-63f2902d5eeb" { - description ""; - source @rescue_coordination_system; - target @classify_incident_and_alert_operator; - } - - role_assignment coordinates_assessment "Coordinates assessment" id "a06f90b9-361b-4da2-86a9-0447df519e0c" { + role_assignment coordinates_assessment "Coordinates assessment" id "6cafacbd-4a72-44d6-a3b2-587b246e202c" { description ""; source @incident_coordinator; target @assess_incident; } - functional_exchange validated_distress_report "Validated distress report" id "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d" { + capability_involvement operational_contribution "Operational contribution" id "6d8cd148-e950-4f1d-978f-43e66ad00cd9" { + description ""; + source @assess_incident; + target @protect_life_at_sea; + } + + availability assessment_in_degraded_mode "Assessment in degraded mode" id "75701d38-2c85-4f67-9ccd-c48e4ad77420" { + description ""; + source @classify_incident_and_alert_operator; + target @degraded_reporting; + } + + allocation system_assessment "System assessment" id "94234700-0f4c-4233-9fc4-c90df4dc7b61" { + description ""; + source @rescue_coordination_system; + target @classify_incident_and_alert_operator; + } + + interface_provision reporting_service_provided "Reporting service provided" id "97c41496-b02a-4d9c-88c9-c3bb2332b7a2" { + description ""; + source @vessel_communication_service; + target @distress_reporting_interface; + } + + chain_involvement operational_realization "Operational realization" id "a990b96f-52be-4d71-ac0e-83e01a23a69a" { + description ""; + source @distress_to_response; + target @protect_life_at_sea; + } + + allocation reports_distress "Reports distress" id "b29fbe37-6543-4d89-826b-015dff8da216" { + description ""; + source @vessel_in_distress; + target @report_distress; + } + + state_transition initialize_reporting "Initialize reporting" id "b93bac52-2a1a-47ac-92ff-3a7268b6b476" { + description ""; + effect ""; + effects []; + guard ""; + source @start_reporting; + target @normal_reporting; + transition_kind External; + trigger ""; + triggers []; + } + + functional_exchange validated_distress_report "Validated distress report" id "b9fa9d19-c1a5-4569-bef2-58ce788a75a3" { description ""; items [@digital_distress_report]; source @transmit_distress_report; @@ -388,50 +432,49 @@ project mission "Coastal rescue — operational need to system behavior" id "ece target_port @assessment_function_input; } - availability assessment_in_normal_mode "Assessment in normal mode" id "bce2587e-f47c-4d85-ac6d-a098170bbaa5" { - description ""; - source @classify_incident_and_alert_operator; - target @normal_reporting; - } - - exchange_allocation report_carried_by_connection "Report carried by connection" id "d6a2c8d2-2a4f-4d90-a490-c2c661db4423" { + exchange_allocation report_carried_by_connection "Report carried by connection" id "cb767431-e196-4abf-9c7e-5b415caf2e53" { description ""; source @distress_reporting_connection; target @validated_distress_report; } - mission_capability mission_capability "Mission capability" id "e88a9747-0d1c-4813-8273-e6710f622e9b" { + interface_requirement reporting_service_required "Reporting service required" id "cf7aaa0b-71f6-4e6b-8c83-8ac87423c1fb" { description ""; - source @support_timely_rescue_decisions; - target @coordinate_rescue_response; - } - - boundary_exchange distress_reporting_connection "Distress reporting connection" id "eb7ae249-165c-4717-bebc-da476eebb05e" { - description ""; - items [@digital_distress_report]; - source @vessel_reporting_output; - target @system_reporting_input; - } - - interface_provision reporting_service_provided "Reporting service provided" id "ec3f9e3f-5134-49af-9969-29f818dfcb46" { - description ""; - source @vessel_communication_service; + source @rescue_coordination_system; target @distress_reporting_interface; } - allocation reports_distress "Reports distress" id "f844c555-b407-402c-81c9-4928245249ca" { + allocation vessel_transmission "Vessel transmission" id "df07c2ae-cee6-4ca9-8433-809aee36f6bd" { description ""; - source @vessel_in_distress; - target @report_distress; + source @vessel_communication_service; + target @transmit_distress_report; } - diagram sa_system_boundary_and_functions "SA system boundary and functions" id "064d0c1c-5db0-4516-ab6f-5bbf18d02e6a" { + capability_involvement system_capability_support "System capability support" id "e72da212-c2ac-476a-b083-ace00756b5e1" { + description ""; + source @classify_incident_and_alert_operator; + target @coordinate_rescue_response; + } + + state_transition signal_restored "Signal restored" id "fc699be4-387c-4b6a-9514-3a9e54aa101e" { + description ""; + effect "Clear the degraded-reporting alert."; + effects []; + guard "position_is_current"; + source @degraded_reporting; + target @normal_reporting; + transition_kind External; + trigger "validated_report_received"; + triggers [@validated_report_received]; + } + + diagram sa_system_boundary_and_functions "SA system boundary and functions" id "181c5d1c-9b20-4223-b0d7-0465cfcdd988" { description "A focused projection of the shared engineering model."; layer Sa; projection Allocation; } - node view_vessel_communication_service id "00edf6bc-b857-439a-8747-f1f66c1675e2" { + node view_vessel_communication_service id "1e59932f-3c3f-4ff7-b3d7-a56ea45a8757" { collapsed false; diagram @sa_system_boundary_and_functions; element @vessel_communication_service; @@ -440,122 +483,66 @@ project mission "Coastal rescue — operational need to system behavior" id "ece y 60.0; }; size { - height 166.0; + height 248.0; width 272.0; }; } - node view_transmit_distress_report id "035dab75-ef9e-4ca3-a107-87262e3c680b" { + node view_transmit_distress_report id "3dbe9ac3-4058-47f8-a112-94f81da8b113" { collapsed false; diagram @sa_system_boundary_and_functions; element @transmit_distress_report; position { x 84.0; - y 108.0; + y 124.0; }; size { - height 94.0; + height 132.0; width 224.0; }; } - node view_support_timely_rescue_decisions id "16b5055a-c98b-4276-b564-85b7fe1f020f" { - collapsed false; - diagram @sa_system_boundary_and_functions; - element @support_timely_rescue_decisions; - position { - x 392.0; - y 60.0; - }; - size { - height 94.0; - width 224.0; - }; - } - - node view_digital_distress_handling id "4aa2fb09-b367-402c-a438-d4f918f04e08" { - collapsed false; - diagram @sa_system_boundary_and_functions; - element @digital_distress_handling; - position { - x 676.0; - y 60.0; - }; - size { - height 94.0; - width 224.0; - }; - } - - node view_rescue_coordination_system id "5a6d6a1c-9915-4e33-8299-b512c50b18f5" { + node view_rescue_coordination_system id "5113e074-4e3b-4e6e-8b33-4081cdedb02a" { collapsed false; diagram @sa_system_boundary_and_functions; element @rescue_coordination_system; position { - x 960.0; + x 572.0; y 60.0; }; size { - height 166.0; + height 248.0; width 272.0; }; } - node view_manage_distress_response id "621e0e5e-d1be-4693-b95a-7c48d36e07b4" { - collapsed false; - diagram @sa_system_boundary_and_functions; - element @manage_distress_response; - position { - x 60.0; - y 286.0; - }; - size { - height 94.0; - width 224.0; - }; - } - - node view_coordinate_rescue_response id "9f41eaff-3456-494b-b136-9f6f01afd90f" { - collapsed false; - diagram @sa_system_boundary_and_functions; - element @coordinate_rescue_response; - position { - x 344.0; - y 286.0; - }; - size { - height 94.0; - width 224.0; - }; - } - - node view_classify_incident_and_alert_operator id "e75a6c26-dc64-4fa3-bc8f-a1a38e1f9b68" { + node view_classify_incident_and_alert_operator id "d7cfae62-b32f-44e0-a98e-89765da3d4e2" { collapsed false; diagram @sa_system_boundary_and_functions; element @classify_incident_and_alert_operator; position { - x 984.0; - y 108.0; + x 596.0; + y 124.0; }; size { - height 94.0; + height 132.0; width 224.0; }; } - diagram sa_functional_decomposition "SA functional decomposition" id "a67786d6-5b08-4b06-a0c8-584a04f179ef" { + diagram sa_missions_and_capabilities "SA missions and capabilities" id "78fe5575-54ec-4898-840b-db3fe0bbcea1" { description "A focused projection of the shared engineering model."; layer Sa; - projection Decomposition; + projection Capabilities; } - node view_classify_incident_and_alert_operator_5ae489f2 id "5ae489f2-4be1-4842-b464-37900983e333" { + node view_coordinate_rescue_response id "15f17f55-b5ac-48f5-8476-c96ec4ba4707" { collapsed false; - diagram @sa_functional_decomposition; - element @classify_incident_and_alert_operator; + diagram @sa_missions_and_capabilities; + element @coordinate_rescue_response; position { - x 84.0; - y 108.0; + x 988.0; + y 60.0; }; size { height 94.0; @@ -563,27 +550,27 @@ project mission "Coastal rescue — operational need to system behavior" id "ece }; } - node view_manage_distress_response_80ab61e0 id "80ab61e0-d1f2-4008-9858-0759bdaa02e3" { + node view_rescue_coordination_system_3db00caf id "3db00caf-b5bb-4241-bb69-017497c20340" { collapsed false; - diagram @sa_functional_decomposition; - element @manage_distress_response; + diagram @sa_missions_and_capabilities; + element @rescue_coordination_system; position { x 60.0; y 60.0; }; size { - height 276.0; - width 272.0; + height 132.0; + width 224.0; }; } - node view_transmit_distress_report_e02431fd id "e02431fd-c27e-4b48-9c94-37b8e3d55375" { + node view_support_timely_rescue_decisions id "7508ba39-d8bb-45d8-92df-f22764c8536e" { collapsed false; - diagram @sa_functional_decomposition; - element @transmit_distress_report; + diagram @sa_missions_and_capabilities; + element @support_timely_rescue_decisions; position { - x 84.0; - y 218.0; + x 524.0; + y 60.0; }; size { height 94.0; @@ -591,75 +578,33 @@ project mission "Coastal rescue — operational need to system behavior" id "ece }; } - diagram oa_participants_and_activities "OA participants and activities" id "d7f59b88-4a9b-4906-b859-1c6d044bbb52" { + node view_vessel_communication_service_dd551ce6 id "dd551ce6-a062-476f-82f9-44b0549e0459" { + collapsed false; + diagram @sa_missions_and_capabilities; + element @vessel_communication_service; + position { + x 1452.0; + y 60.0; + }; + size { + height 132.0; + width 224.0; + }; + } + + diagram oa_participants_and_activities "OA participants and activities" id "7fdd7f39-a225-442f-8588-05d77284ba6b" { description "A focused projection of the shared engineering model."; layer Oa; projection Allocation; } - node view_rescue_coordination id "2f5fed31-e2dc-419d-9ebc-a5c9e9682277" { - collapsed false; - diagram @oa_participants_and_activities; - element @rescue_coordination; - position { - x 60.0; - y 60.0; - }; - size { - height 166.0; - width 272.0; - }; - } - - node view_protect_life_at_sea id "91fe2d63-0083-4df2-9c29-563766e1b706" { - collapsed false; - diagram @oa_participants_and_activities; - element @protect_life_at_sea; - position { - x 392.0; - y 60.0; - }; - size { - height 94.0; - width 224.0; - }; - } - - node view_distress_to_response id "a045fd40-84ea-48f3-a6d4-95641492d960" { - collapsed false; - diagram @oa_participants_and_activities; - element @distress_to_response; - position { - x 676.0; - y 60.0; - }; - size { - height 94.0; - width 224.0; - }; - } - - node view_report_distress id "a2cabc9f-c12c-4eff-8acf-0e9b86829cbe" { + node view_report_distress id "07438ef3-fedd-409d-8d39-3e4a712a8dce" { collapsed false; diagram @oa_participants_and_activities; element @report_distress; - position { - x 984.0; - y 108.0; - }; - size { - height 94.0; - width 224.0; - }; - } - - node view_assess_incident id "acaa5a3d-51c4-45da-b5aa-4825bccd747c" { - collapsed false; - diagram @oa_participants_and_activities; - element @assess_incident; position { x 84.0; - y 108.0; + y 124.0; }; size { height 94.0; @@ -667,58 +612,207 @@ project mission "Coastal rescue — operational need to system behavior" id "ece }; } - node view_vessel_in_distress id "af3a61b3-db02-400f-bd18-b4422e2db7a7" { + node view_rescue_coordination id "0e9765db-e564-49e8-8c4e-8cf94c06b9d4" { collapsed false; diagram @oa_participants_and_activities; - element @vessel_in_distress; + element @rescue_coordination; position { - x 960.0; + x 572.0; y 60.0; }; size { - height 166.0; + height 182.0; width 272.0; }; } - node view_respond_to_distress id "e4c687d7-4a44-4dee-a2d8-bdbe6a5cf649" { + node view_vessel_in_distress id "20c607f1-1c2b-4fef-8cff-6e122fc7939b" { collapsed false; diagram @oa_participants_and_activities; + element @vessel_in_distress; + position { + x 60.0; + y 60.0; + }; + size { + height 182.0; + width 272.0; + }; + } + + node view_assess_incident id "3e5163ae-436f-45e6-9130-b3d3781a2f03" { + collapsed false; + diagram @oa_participants_and_activities; + element @assess_incident; + position { + x 596.0; + y 124.0; + }; + size { + height 94.0; + width 224.0; + }; + } + + diagram oa_capabilities_and_participants "OA capabilities and participants" id "b1b0a28b-5a92-46e4-ba35-9637d6b9720d" { + description "A focused projection of the shared engineering model."; + layer Oa; + projection Capabilities; + } + + node view_rescue_coordination_91ff9ff9 id "91ff9ff9-3f1b-42e5-8754-1c280cf9d3bf" { + collapsed false; + diagram @oa_capabilities_and_participants; + element @rescue_coordination; + position { + x 988.0; + y 60.0; + }; + size { + height 94.0; + width 224.0; + }; + } + + node view_incident_coordinator id "96abcbf4-fe39-41a2-bc7a-896260b0e6f5" { + collapsed false; + diagram @oa_capabilities_and_participants; + element @incident_coordinator; + position { + x 60.0; + y 60.0; + }; + size { + height 94.0; + width 224.0; + }; + } + + node view_vessel_in_distress_e4aaf25f id "e4aaf25f-ae0d-49d0-93c2-c481d2770f09" { + collapsed false; + diagram @oa_capabilities_and_participants; + element @vessel_in_distress; + position { + x 1452.0; + y 60.0; + }; + size { + height 94.0; + width 224.0; + }; + } + + node view_protect_life_at_sea id "f14d122d-32ca-42e4-bf2c-1d34be1b2bcc" { + collapsed false; + diagram @oa_capabilities_and_participants; + element @protect_life_at_sea; + position { + x 524.0; + y 60.0; + }; + size { + height 94.0; + width 224.0; + }; + } + + diagram oa_activity_dataflow "OA activity dataflow" id "bdfa2607-3900-45f8-9382-3065573942dd" { + description "A focused projection of the shared engineering model."; + layer Oa; + projection FunctionalDataflow; + } + + node view_assess_incident_4fb9673b id "4fb9673b-b13d-4f29-9bc1-73db1004d0df" { + collapsed false; + diagram @oa_activity_dataflow; + element @assess_incident; + position { + x 84.0; + y 124.0; + }; + size { + height 94.0; + width 224.0; + }; + } + + node view_report_distress_9e6cc97a id "9e6cc97a-cc88-4630-894e-4ddb9dbf8c23" { + collapsed false; + diagram @oa_activity_dataflow; + element @report_distress; + position { + x 84.0; + y 234.0; + }; + size { + height 94.0; + width 224.0; + }; + } + + node view_respond_to_distress id "c9f9d743-d1e0-4672-a874-29fb98296507" { + collapsed false; + diagram @oa_activity_dataflow; element @respond_to_distress; position { x 60.0; - y 286.0; + y 60.0; }; size { - height 94.0; - width 224.0; + height 292.0; + width 272.0; }; } - node view_incident_coordinator id "fcbda72a-5478-4d77-8330-16f89cdefc37" { + diagram sa_functional_decomposition "SA functional decomposition" id "d8764c63-336d-4558-ac58-dba9dfa74c87" { + description "A focused projection of the shared engineering model."; + layer Sa; + projection FunctionalDataflow; + } + + node view_transmit_distress_report_4444f7de id "4444f7de-c924-429f-8703-f484a8ee4dce" { collapsed false; - diagram @oa_participants_and_activities; - element @incident_coordinator; + diagram @sa_functional_decomposition; + element @transmit_distress_report; position { - x 344.0; - y 286.0; + x 84.0; + y 124.0; }; size { - height 94.0; + height 132.0; width 224.0; }; } - artifact console_enclosure_cad "Console enclosure CAD" id "091b5a40-1631-49ef-8b53-1471c016a13f" { - description "Illustrative external engineering reference; opening a model does not fetch it."; - fragment none; - owner @rescue_coordination_system; - relation References; - revision "B.3"; - uri "cad://rescue-console/enclosure.step"; + node view_manage_distress_response id "96fbd2d9-a6f2-4889-8e0e-a664eba39e07" { + collapsed false; + diagram @sa_functional_decomposition; + element @manage_distress_response; + position { + x 60.0; + y 60.0; + }; + size { + height 368.0; + width 272.0; + }; } - artifact response_implementation "Response implementation" id "0b09f95e-0545-44c3-b687-84489ce1422b" { + node view_classify_incident_and_alert_operator_e8dbf569 id "e8dbf569-226f-4004-bd24-cee2a2072b2c" { + collapsed false; + diagram @sa_functional_decomposition; + element @classify_incident_and_alert_operator; + position { + x 84.0; + y 272.0; + }; + size { + height 132.0; + width 224.0; + }; + } + + artifact response_implementation "Response implementation" id "2c11e575-9636-426b-8a46-8d696c25c9e0" { description "Illustrative external engineering reference; opening a model does not fetch it."; fragment none; owner @classify_incident_and_alert_operator; @@ -727,109 +821,16 @@ project mission "Coastal rescue — operational need to system behavior" id "ece uri "git+https://example.org/rescue/control?path=src/response.rs"; } - trace trace_respond_to_distress "Respond to distress ↔ Manage distress response" id "1d0a908f-9e22-42b7-9aac-26bbe3f5df78" { - baseline { - oa { - description ""; - name "Respond to distress"; - }; - sa { - description ""; - name "Manage distress response"; - }; - }; - description "Reviewed OA/SA correspondence in the coastal rescue example."; - kind Refinement; - oa @respond_to_distress; - sa @manage_distress_response; + artifact console_enclosure_cad "Console enclosure CAD" id "b6003fcd-a5d6-4b22-b17b-9110759d8064" { + description "Illustrative external engineering reference; opening a model does not fetch it."; + fragment none; + owner @rescue_coordination_system; + relation References; + revision "B.3"; + uri "cad://rescue-console/enclosure.step"; } - trace trace_rescue_coordination "Rescue coordination ↔ Rescue coordination system" id "49f2b55a-6dcc-44ba-a68f-a305942db7c9" { - baseline { - oa { - description ""; - name "Rescue coordination"; - }; - sa { - description ""; - name "Rescue coordination system"; - }; - }; - description "Reviewed OA/SA correspondence in the coastal rescue example."; - kind Participant; - oa @rescue_coordination; - sa @rescue_coordination_system; - } - - trace trace_distress_to_response "Distress to response ↔ Digital distress handling" id "4ac98979-6c84-4a66-b043-373b70bb5203" { - baseline { - oa { - description ""; - name "Distress to response"; - }; - sa { - description ""; - name "Digital distress handling"; - }; - }; - description "Reviewed OA/SA correspondence in the coastal rescue example."; - kind Sequence; - oa @distress_to_response; - sa @digital_distress_handling; - } - - trace trace_protect_life_at_sea "Protect life at sea ↔ Coordinate rescue response" id "4b6acf23-dab3-462d-b45f-066aea916932" { - baseline { - oa { - description ""; - name "Protect life at sea"; - }; - sa { - description ""; - name "Coordinate rescue response"; - }; - }; - description "Reviewed OA/SA correspondence in the coastal rescue example."; - kind Capability; - oa @protect_life_at_sea; - sa @coordinate_rescue_response; - } - - trace trace_distress_signal "Distress signal ↔ Validated distress report" id "587cca51-69e8-47e7-9674-32ff49926a22" { - baseline { - oa { - description ""; - name "Distress signal"; - }; - sa { - description ""; - name "Validated distress report"; - }; - }; - description "Reviewed OA/SA correspondence in the coastal rescue example."; - kind Exchange; - oa @distress_signal; - sa @validated_distress_report; - } - - trace trace_distress_report "Distress report ↔ Digital distress report" id "7790684b-220f-443d-8754-52c29414367f" { - baseline { - oa { - description ""; - name "Distress report"; - }; - sa { - description ""; - name "Digital distress report"; - }; - }; - description "Reviewed OA/SA correspondence in the coastal rescue example."; - kind Item; - oa @distress_report; - sa @digital_distress_report; - } - - trace trace_vessel_in_distress "Vessel in distress ↔ Vessel communication service" id "9a8101e4-ebce-4836-a0e3-63440c2e1e87" { + trace trace_vessel_in_distress "Vessel in distress ↔ Vessel communication service" id "268f4a8f-0ba1-4218-9698-31e76cbd38ec" { baseline { oa { description ""; @@ -846,41 +847,24 @@ project mission "Coastal rescue — operational need to system behavior" id "ece sa @vessel_communication_service; } - trace trace_assess_incident "Assess incident ↔ Classify incident and alert operator" id "b8fee65b-21da-4a27-9b42-575d417bd942" { + trace trace_respond_to_distress "Respond to distress ↔ Manage distress response" id "3d77a609-3426-4317-83c4-74dfa6558e6c" { baseline { oa { description ""; - name "Assess incident"; + name "Respond to distress"; }; sa { description ""; - name "Classify incident and alert operator"; + name "Manage distress response"; }; }; description "Reviewed OA/SA correspondence in the coastal rescue example."; kind Refinement; - oa @assess_incident; - sa @classify_incident_and_alert_operator; + oa @respond_to_distress; + sa @manage_distress_response; } - trace trace_distress_received "Distress received ↔ Report handled" id "be4365d6-2a43-433c-935f-c039b266242f" { - baseline { - oa { - description ""; - name "Distress received"; - }; - sa { - description ""; - name "Report handled"; - }; - }; - description "Reviewed OA/SA correspondence in the coastal rescue example."; - kind Scenario; - oa @distress_received; - sa @report_handled; - } - - trace trace_report_distress "Report distress ↔ Transmit distress report" id "d3f224a5-0b2d-4eba-93c9-232b9e84e742" { + trace trace_report_distress "Report distress ↔ Transmit distress report" id "4b5f05e7-fa2f-4281-a046-d358a0ac03d5" { baseline { oa { description ""; @@ -897,4 +881,123 @@ project mission "Coastal rescue — operational need to system behavior" id "ece sa @transmit_distress_report; } + trace trace_protect_life_at_sea "Protect life at sea ↔ Coordinate rescue response" id "4ca472c7-de50-4217-96e0-7dee7d8bcb3a" { + baseline { + oa { + description ""; + name "Protect life at sea"; + }; + sa { + description ""; + name "Coordinate rescue response"; + }; + }; + description "Reviewed OA/SA correspondence in the coastal rescue example."; + kind Capability; + oa @protect_life_at_sea; + sa @coordinate_rescue_response; + } + + trace trace_distress_report "Distress report ↔ Digital distress report" id "6c3fe0b0-b7b0-4d66-8450-3736349f935f" { + baseline { + oa { + description ""; + name "Distress report"; + }; + sa { + description ""; + name "Digital distress report"; + }; + }; + description "Reviewed OA/SA correspondence in the coastal rescue example."; + kind Item; + oa @distress_report; + sa @digital_distress_report; + } + + trace trace_assess_incident "Assess incident ↔ Classify incident and alert operator" id "ad41088e-62b6-4e52-b63a-970a939ea77a" { + baseline { + oa { + description ""; + name "Assess incident"; + }; + sa { + description ""; + name "Classify incident and alert operator"; + }; + }; + description "Reviewed OA/SA correspondence in the coastal rescue example."; + kind Refinement; + oa @assess_incident; + sa @classify_incident_and_alert_operator; + } + + trace trace_distress_signal "Distress signal ↔ Validated distress report" id "e3d46af5-47b7-42a5-b92f-48ebbe0b9a1d" { + baseline { + oa { + description ""; + name "Distress signal"; + }; + sa { + description ""; + name "Validated distress report"; + }; + }; + description "Reviewed OA/SA correspondence in the coastal rescue example."; + kind Exchange; + oa @distress_signal; + sa @validated_distress_report; + } + + trace trace_rescue_coordination "Rescue coordination ↔ Rescue coordination system" id "e5ea9201-6fb6-4e9e-b3c6-e9d0bc167c21" { + baseline { + oa { + description ""; + name "Rescue coordination"; + }; + sa { + description ""; + name "Rescue coordination system"; + }; + }; + description "Reviewed OA/SA correspondence in the coastal rescue example."; + kind Participant; + oa @rescue_coordination; + sa @rescue_coordination_system; + } + + trace trace_distress_received "Distress received ↔ Report handled" id "ea6c8ccb-2822-42bc-968e-41a3960bff28" { + baseline { + oa { + description ""; + name "Distress received"; + }; + sa { + description ""; + name "Report handled"; + }; + }; + description "Reviewed OA/SA correspondence in the coastal rescue example."; + kind Scenario; + oa @distress_received; + sa @report_handled; + } + + trace trace_distress_to_response "Distress to response ↔ Digital distress handling" id "ebf036d6-1504-4386-bbe2-87e0b12338f6" { + baseline { + oa { + description ""; + name "Distress to response"; + }; + sa { + description ""; + name "Digital distress handling"; + }; + }; + description "Reviewed OA/SA correspondence in the coastal rescue example."; + kind Sequence; + oa @distress_to_response; + sa @digital_distress_handling; + } + } diff --git a/examples/coastal-rescue.json b/examples/coastal-rescue.json index b98ce427..85e85e2f 100644 --- a/examples/coastal-rescue.json +++ b/examples/coastal-rescue.json @@ -1,32 +1,53 @@ { "schema_version": 2, - "id": "eceea6cd-108b-45a9-9505-8b7fa462af96", + "id": "7fd2d957-d964-4cc5-a3f3-3f42aa6f04ca", "alias": "mission", "name": "Coastal rescue — operational need to system behavior", "description": "A worked OA/SA example. Compare allocation and functional decomposition views; inspect traces, repeated scenario messages, interface contracts, degraded modes, and external engineering artifacts.", "elements": { - "03b71dc5-435f-4c7f-923a-cb6e672212ba": { - "id": "03b71dc5-435f-4c7f-923a-cb6e672212ba", - "alias": "vessel_service_lifeline", - "name": "Vessel service lifeline", + "1c1b700a-45e2-418d-8f1c-40e57e409434": { + "id": "1c1b700a-45e2-418d-8f1c-40e57e409434", + "alias": "distress_received", + "name": "Distress received", "description": "", - "parent": "f7514a9c-933c-4133-8b77-37c0dccd935f", + "parent": "86aa4bf3-6543-4e81-929b-f0fc3482ff77", "body": { - "Sa": { + "Oa": { "Shared": { - "Lifeline": { - "represented": "cfb45cf5-bebe-4632-9bde-0ee023c42583" + "Occurrence": { + "body": { + "Exchange": { + "exchange": "56fdbdda-a9a7-48b4-9512-d0cec7f9066d", + "sender": null, + "receiver": null, + "message_kind": "Asynchronous", + "reply_to": null, + "values": [] + } + }, + "precondition": "", + "postcondition": "" } } } } }, - "0deb4c4c-d7cc-4dd9-bcc5-f357387cf978": { - "id": "0deb4c4c-d7cc-4dd9-bcc5-f357387cf978", + "2027bca4-204e-40fe-a6af-fa2f74e4ce0e": { + "id": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", + "alias": "rescue_coordination_system", + "name": "Rescue coordination system", + "description": "", + "parent": null, + "body": { + "Sa": "System" + } + }, + "26df594f-d55c-4d83-9907-fabad1e27572": { + "id": "26df594f-d55c-4d83-9907-fabad1e27572", "alias": "start_reporting", "name": "Start reporting", "description": "", - "parent": "edc1ad70-8fc9-42a1-a668-05c4738bb225", + "parent": "27c7dfaa-6a65-41e9-bf1a-1b1ba58912d5", "body": { "Sa": { "Shared": { @@ -40,52 +61,83 @@ } } }, - "1a1b215a-c102-4948-9c88-dabfadc8e08e": { - "id": "1a1b215a-c102-4948-9c88-dabfadc8e08e", - "alias": "reporting_operation_modes", - "name": "Reporting operation modes", + "27c7dfaa-6a65-41e9-bf1a-1b1ba58912d5": { + "id": "27c7dfaa-6a65-41e9-bf1a-1b1ba58912d5", + "alias": "reporting_quality_region", + "name": "Reporting quality region", "description": "", - "parent": "47e28c63-803b-4ea6-af92-e778f62ecc3e", + "parent": "c3945ca6-698b-4e7c-888d-2bb3788caffc", "body": { "Sa": { - "Shared": "StateMachine" + "Shared": "Region" } } }, - "1b81d963-06e7-42d3-af31-bf5236829477": { - "id": "1b81d963-06e7-42d3-af31-bf5236829477", - "alias": "backup_electrical_energy", - "name": "Backup electrical energy", + "2a9f2d3a-45eb-4a9b-b2aa-284d8ccb961b": { + "id": "2a9f2d3a-45eb-4a9b-b2aa-284d8ccb961b", + "alias": "vessel_reporting_output", + "name": "Vessel reporting output", + "description": "", + "parent": "8cda5e33-5731-40af-91d1-9060ea723935", + "body": { + "Sa": { + "Shared": { + "Port": { + "direction": "Out", + "interface": "e13f9bc0-b8c7-4e91-b481-3732d6c08168" + } + } + } + } + }, + "334793e5-fdfd-427e-89d5-7cc91283c75a": { + "id": "334793e5-fdfd-427e-89d5-7cc91283c75a", + "alias": "protect_life_at_sea", + "name": "Protect life at sea", + "description": "", + "parent": null, + "body": { + "Oa": "Capability" + } + }, + "34f9ddb2-bb79-4658-8932-c8393b9f5022": { + "id": "34f9ddb2-bb79-4658-8932-c8393b9f5022", + "alias": "digital_distress_handling", + "name": "Digital distress handling", "description": "", "parent": null, "body": { "Sa": { - "Shared": { - "ExchangeItem": { - "kind": "Energy" - } + "FunctionalChain": { + "steps": [ + "d48ccc42-f422-4026-b5c2-68bbe830abf6" + ] } } } }, - "1f7da722-c91e-4d0e-a344-c1a2511dd96b": { - "id": "1f7da722-c91e-4d0e-a344-c1a2511dd96b", - "alias": "coordination_system_lifeline", - "name": "Coordination system lifeline", + "39ba0d44-3f9d-4d98-bf9a-6c9b8c5ed041": { + "id": "39ba0d44-3f9d-4d98-bf9a-6c9b8c5ed041", + "alias": "incident_coordinator", + "name": "Incident coordinator", "description": "", - "parent": "f7514a9c-933c-4133-8b77-37c0dccd935f", + "parent": null, "body": { - "Sa": { - "Shared": { - "Lifeline": { - "represented": "47e28c63-803b-4ea6-af92-e778f62ecc3e" - } - } - } + "Oa": "Role" } }, - "218e9ac0-1fdb-4ce8-bbcb-4cc5c36b3746": { - "id": "218e9ac0-1fdb-4ce8-bbcb-4cc5c36b3746", + "3e0a28ce-335f-4d39-80ac-5c04a0a22a7f": { + "id": "3e0a28ce-335f-4d39-80ac-5c04a0a22a7f", + "alias": "report_distress", + "name": "Report distress", + "description": "", + "parent": "9526e01a-1936-48fc-9b84-4639f63b9370", + "body": { + "Oa": "Activity" + } + }, + "42bc4bd3-dab1-4b5b-9815-a5fd36a939f0": { + "id": "42bc4bd3-dab1-4b5b-9815-a5fd36a939f0", "alias": "support_timely_rescue_decisions", "name": "Support timely rescue decisions", "description": "", @@ -94,42 +146,8 @@ "Sa": "Mission" } }, - "28b8e56d-7ddf-4950-8c30-7385c044cc72": { - "id": "28b8e56d-7ddf-4950-8c30-7385c044cc72", - "alias": "updated_distress_report", - "name": "Updated distress report", - "description": "", - "parent": "f7514a9c-933c-4133-8b77-37c0dccd935f", - "body": { - "Sa": { - "Shared": { - "Occurrence": { - "body": { - "Exchange": { - "exchange": "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d", - "sender": "03b71dc5-435f-4c7f-923a-cb6e672212ba", - "receiver": "1f7da722-c91e-4d0e-a344-c1a2511dd96b" - } - }, - "precondition": "The vessel has more recent position information.", - "postcondition": "The incident position is refreshed without creating a second incident." - } - } - } - } - }, - "3388cc0d-0abc-4479-a948-6740266ec236": { - "id": "3388cc0d-0abc-4479-a948-6740266ec236", - "alias": "assess_incident", - "name": "Assess incident", - "description": "", - "parent": "fa23a2a8-6f13-49e3-be47-f757f26d5c9f", - "body": { - "Oa": "Activity" - } - }, - "3584d050-0b4e-4620-bbea-8c3c87d2a19f": { - "id": "3584d050-0b4e-4620-bbea-8c3c87d2a19f", + "434a0fad-4e61-4211-839e-5f6fde77f1b1": { + "id": "434a0fad-4e61-4211-839e-5f6fde77f1b1", "alias": "response_time_budget", "name": "Response time budget", "description": "", @@ -140,82 +158,36 @@ "Constraint": { "expression": "incident_alert_latency <= 120 s", "constrained": [ - "b1cc95c7-1d2f-42d0-9d93-587954bd563b", - "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d" + "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "b9fa9d19-c1a5-4569-bef2-58ce788a75a3" ] } } } } }, - "47e28c63-803b-4ea6-af92-e778f62ecc3e": { - "id": "47e28c63-803b-4ea6-af92-e778f62ecc3e", - "alias": "rescue_coordination_system", - "name": "Rescue coordination system", + "521b8f60-174d-47a4-a672-efff675ebf82": { + "id": "521b8f60-174d-47a4-a672-efff675ebf82", + "alias": "coordinate_rescue_response", + "name": "Coordinate rescue response", "description": "", "parent": null, "body": { - "Sa": "System" + "Sa": "Capability" } }, - "49743116-7777-4df8-9601-74fd4cba22c0": { - "id": "49743116-7777-4df8-9601-74fd4cba22c0", - "alias": "digital_distress_handling", - "name": "Digital distress handling", + "5b8669e9-5071-4ef5-a7c4-ebb45f662841": { + "id": "5b8669e9-5071-4ef5-a7c4-ebb45f662841", + "alias": "rescue_coordination", + "name": "Rescue coordination", "description": "", "parent": null, "body": { - "Sa": { - "FunctionalChain": { - "steps": [ - "bcdb57f1-5fa8-46ce-9498-b467cea5d98f" - ] - } - } + "Oa": "Entity" } }, - "51c8ed9f-93ea-45fe-8829-e4ec88f09ce5": { - "id": "51c8ed9f-93ea-45fe-8829-e4ec88f09ce5", - "alias": "distress_to_response", - "name": "Distress to response", - "description": "", - "parent": null, - "body": { - "Oa": { - "Process": { - "steps": [ - "5e0c0d0e-5eb5-467c-bc35-dfe29d534703" - ] - } - } - } - }, - "5e0c0d0e-5eb5-467c-bc35-dfe29d534703": { - "id": "5e0c0d0e-5eb5-467c-bc35-dfe29d534703", - "alias": "distress_received", - "name": "Distress received", - "description": "", - "parent": "51c8ed9f-93ea-45fe-8829-e4ec88f09ce5", - "body": { - "Oa": { - "Shared": { - "Occurrence": { - "body": { - "Exchange": { - "exchange": "689a8e09-b7ca-4d97-b551-a21e3b438bfe", - "sender": null, - "receiver": null - } - }, - "precondition": "", - "postcondition": "" - } - } - } - } - }, - "5e16affb-7fa4-4a3d-8bfe-6340586ab83f": { - "id": "5e16affb-7fa4-4a3d-8bfe-6340586ab83f", + "5de7b2ef-8012-484a-be40-5b4ce883223f": { + "id": "5de7b2ef-8012-484a-be40-5b4ce883223f", "alias": "digital_distress_report", "name": "Digital distress report", "description": "", @@ -230,270 +202,35 @@ } } }, - "6ca5efd6-2e92-4508-a02d-4013793743cb": { - "id": "6ca5efd6-2e92-4508-a02d-4013793743cb", - "alias": "protect_life_at_sea", - "name": "Protect life at sea", + "5f09f99a-584a-4917-8b5d-4fda45f4932e": { + "id": "5f09f99a-584a-4917-8b5d-4fda45f4932e", + "alias": "updated_distress_report", + "name": "Updated distress report", "description": "", - "parent": null, - "body": { - "Oa": "Capability" - } - }, - "6ecf32ed-4009-48ba-b374-3bf156f6c355": { - "id": "6ecf32ed-4009-48ba-b374-3bf156f6c355", - "alias": "report_function_output", - "name": "Report function output", - "description": "", - "parent": "b0a649d6-0558-48f5-8437-161be8329159", - "body": { - "Sa": { - "Shared": { - "Port": { - "direction": "Out", - "interface": "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4" - } - } - } - } - }, - "721b68ab-5136-408e-890d-925215d5661e": { - "id": "721b68ab-5136-408e-890d-925215d5661e", - "alias": "rescue_coordination", - "name": "Rescue coordination", - "description": "", - "parent": null, - "body": { - "Oa": "Entity" - } - }, - "7781bd9f-e788-4049-9af4-9a3eab40d377": { - "id": "7781bd9f-e788-4049-9af4-9a3eab40d377", - "alias": "coordinate_rescue_response", - "name": "Coordinate rescue response", - "description": "", - "parent": null, - "body": { - "Sa": "Capability" - } - }, - "7e8ea298-1c68-4c9e-994d-6008d47f62ce": { - "id": "7e8ea298-1c68-4c9e-994d-6008d47f62ce", - "alias": "vessel_in_distress", - "name": "Vessel in distress", - "description": "", - "parent": null, - "body": { - "Oa": "Actor" - } - }, - "835c2e84-f4e9-4592-b5df-d205803d97b7": { - "id": "835c2e84-f4e9-4592-b5df-d205803d97b7", - "alias": "distress_report", - "name": "Distress report", - "description": "", - "parent": null, - "body": { - "Oa": { - "Shared": { - "ExchangeItem": { - "kind": "Information" - } - } - } - } - }, - "8477d19d-4a62-43bb-a7e3-845b9b3d1002": { - "id": "8477d19d-4a62-43bb-a7e3-845b9b3d1002", - "alias": "system_reporting_input", - "name": "System reporting input", - "description": "", - "parent": "47e28c63-803b-4ea6-af92-e778f62ecc3e", - "body": { - "Sa": { - "Shared": { - "Port": { - "direction": "In", - "interface": "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4" - } - } - } - } - }, - "84a0db92-ac74-493a-af29-74ec7715d7fa": { - "id": "84a0db92-ac74-493a-af29-74ec7715d7fa", - "alias": "initial_distress_report", - "name": "Initial distress report", - "description": "", - "parent": "f7514a9c-933c-4133-8b77-37c0dccd935f", + "parent": "df3b4429-398d-4d66-869b-784183e1e62d", "body": { "Sa": { "Shared": { "Occurrence": { "body": { "Exchange": { - "exchange": "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d", - "sender": "03b71dc5-435f-4c7f-923a-cb6e672212ba", - "receiver": "1f7da722-c91e-4d0e-a344-c1a2511dd96b" + "exchange": "b9fa9d19-c1a5-4569-bef2-58ce788a75a3", + "sender": "9bdd35fb-5bb7-41a7-a909-a3a97d07ae33", + "receiver": "80f59f52-26ae-486c-8e9a-5ba032223362", + "message_kind": "Asynchronous", + "reply_to": null, + "values": [] } }, - "precondition": "", - "postcondition": "" + "precondition": "The vessel has more recent position information.", + "postcondition": "The incident position is refreshed without creating a second incident." } } } } }, - "a0e18d73-a9ce-4e9e-8ecf-0a54b1412932": { - "id": "a0e18d73-a9ce-4e9e-8ecf-0a54b1412932", - "alias": "vessel_reporting_output", - "name": "Vessel reporting output", - "description": "", - "parent": "cfb45cf5-bebe-4632-9bde-0ee023c42583", - "body": { - "Sa": { - "Shared": { - "Port": { - "direction": "Out", - "interface": "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4" - } - } - } - } - }, - "b0a649d6-0558-48f5-8437-161be8329159": { - "id": "b0a649d6-0558-48f5-8437-161be8329159", - "alias": "transmit_distress_report", - "name": "Transmit distress report", - "description": "", - "parent": "c64f93a7-bf47-42b5-b432-7589b9144f2c", - "body": { - "Sa": "Function" - } - }, - "b1cc95c7-1d2f-42d0-9d93-587954bd563b": { - "id": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", - "alias": "classify_incident_and_alert_operator", - "name": "Classify incident and alert operator", - "description": "", - "parent": "c64f93a7-bf47-42b5-b432-7589b9144f2c", - "body": { - "Sa": "Function" - } - }, - "bcdb57f1-5fa8-46ce-9498-b467cea5d98f": { - "id": "bcdb57f1-5fa8-46ce-9498-b467cea5d98f", - "alias": "report_handled", - "name": "Report handled", - "description": "", - "parent": "49743116-7777-4df8-9601-74fd4cba22c0", - "body": { - "Sa": { - "Shared": { - "Occurrence": { - "body": { - "Exchange": { - "exchange": "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d", - "sender": null, - "receiver": null - } - }, - "precondition": "", - "postcondition": "" - } - } - } - } - }, - "c64f93a7-bf47-42b5-b432-7589b9144f2c": { - "id": "c64f93a7-bf47-42b5-b432-7589b9144f2c", - "alias": "manage_distress_response", - "name": "Manage distress response", - "description": "", - "parent": null, - "body": { - "Sa": "Function" - } - }, - "cfb45cf5-bebe-4632-9bde-0ee023c42583": { - "id": "cfb45cf5-bebe-4632-9bde-0ee023c42583", - "alias": "vessel_communication_service", - "name": "Vessel communication service", - "description": "", - "parent": null, - "body": { - "Sa": "Actor" - } - }, - "d00b5d17-8660-4955-a70d-988a6e6b6c4e": { - "id": "d00b5d17-8660-4955-a70d-988a6e6b6c4e", - "alias": "normal_reporting", - "name": "Normal reporting", - "description": "", - "parent": "edc1ad70-8fc9-42a1-a668-05c4738bb225", - "body": { - "Sa": { - "Shared": { - "State": { - "kind": "Mode", - "entry": "", - "exit": "", - "do_activity": "" - } - } - } - } - }, - "d0f0b612-f0b9-451e-b0d2-5e74eedb2f36": { - "id": "d0f0b612-f0b9-451e-b0d2-5e74eedb2f36", - "alias": "reported_latitude", - "name": "Reported latitude", - "description": "", - "parent": "5e16affb-7fa4-4a3d-8bfe-6340586ab83f", - "body": { - "Sa": { - "Shared": { - "DataField": { - "type_ref": "Real", - "minimum": 1, - "maximum": 1, - "unit": "degrees north" - } - } - } - } - }, - "d50e92c4-840e-4822-bcf7-033feb2eb879": { - "id": "d50e92c4-840e-4822-bcf7-033feb2eb879", - "alias": "report_distress", - "name": "Report distress", - "description": "", - "parent": "fa23a2a8-6f13-49e3-be47-f757f26d5c9f", - "body": { - "Oa": "Activity" - } - }, - "d7fad7e9-d799-4fa6-b49f-1304d3285b5e": { - "id": "d7fad7e9-d799-4fa6-b49f-1304d3285b5e", - "alias": "degraded_reporting", - "name": "Degraded reporting", - "description": "", - "parent": "edc1ad70-8fc9-42a1-a668-05c4738bb225", - "body": { - "Sa": { - "Shared": { - "State": { - "kind": "Mode", - "entry": "", - "exit": "", - "do_activity": "" - } - } - } - } - }, - "eb8cf40e-8194-403f-9896-f968790a9504": { - "id": "eb8cf40e-8194-403f-9896-f968790a9504", + "75399008-b0ef-49c7-b403-35337b3b2c40": { + "id": "75399008-b0ef-49c7-b403-35337b3b2c40", "alias": "rescue_supply_package", "name": "Rescue supply package", "description": "", @@ -508,20 +245,326 @@ } } }, - "edc1ad70-8fc9-42a1-a668-05c4738bb225": { - "id": "edc1ad70-8fc9-42a1-a668-05c4738bb225", - "alias": "reporting_quality_region", - "name": "Reporting quality region", + "7d7a7b65-c6df-42fc-bc94-3162261ad107": { + "id": "7d7a7b65-c6df-42fc-bc94-3162261ad107", + "alias": "report_timeout", + "name": "Report timeout", "description": "", - "parent": "1a1b215a-c102-4948-9c88-dabfadc8e08e", + "parent": null, "body": { "Sa": { - "Shared": "Region" + "Shared": { + "Event": { + "body": { + "Time": { + "kind": "After", + "expression": "30 s" + } + } + } + } } } }, - "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4": { - "id": "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4", + "80f59f52-26ae-486c-8e9a-5ba032223362": { + "id": "80f59f52-26ae-486c-8e9a-5ba032223362", + "alias": "coordination_system_lifeline", + "name": "Coordination system lifeline", + "description": "", + "parent": "df3b4429-398d-4d66-869b-784183e1e62d", + "body": { + "Sa": { + "Shared": { + "Lifeline": { + "represented": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e" + } + } + } + } + }, + "86aa4bf3-6543-4e81-929b-f0fc3482ff77": { + "id": "86aa4bf3-6543-4e81-929b-f0fc3482ff77", + "alias": "distress_to_response", + "name": "Distress to response", + "description": "", + "parent": null, + "body": { + "Oa": { + "Process": { + "steps": [ + "1c1b700a-45e2-418d-8f1c-40e57e409434" + ] + } + } + } + }, + "8be42c58-6486-4038-aaa9-5aea2dce3b65": { + "id": "8be42c58-6486-4038-aaa9-5aea2dce3b65", + "alias": "validated_report_received", + "name": "Validated report received", + "description": "", + "parent": null, + "body": { + "Sa": { + "Shared": { + "Event": { + "body": { + "Signal": { + "items": [ + "5de7b2ef-8012-484a-be40-5b4ce883223f" + ] + } + } + } + } + } + } + }, + "8cda5e33-5731-40af-91d1-9060ea723935": { + "id": "8cda5e33-5731-40af-91d1-9060ea723935", + "alias": "vessel_communication_service", + "name": "Vessel communication service", + "description": "", + "parent": null, + "body": { + "Sa": "Actor" + } + }, + "90d07c73-a950-4a68-8b65-c3964dfe5d19": { + "id": "90d07c73-a950-4a68-8b65-c3964dfe5d19", + "alias": "initial_distress_report", + "name": "Initial distress report", + "description": "", + "parent": "df3b4429-398d-4d66-869b-784183e1e62d", + "body": { + "Sa": { + "Shared": { + "Occurrence": { + "body": { + "Exchange": { + "exchange": "b9fa9d19-c1a5-4569-bef2-58ce788a75a3", + "sender": "9bdd35fb-5bb7-41a7-a909-a3a97d07ae33", + "receiver": "80f59f52-26ae-486c-8e9a-5ba032223362", + "message_kind": "Asynchronous", + "reply_to": null, + "values": [] + } + }, + "precondition": "", + "postcondition": "" + } + } + } + } + }, + "9526e01a-1936-48fc-9b84-4639f63b9370": { + "id": "9526e01a-1936-48fc-9b84-4639f63b9370", + "alias": "respond_to_distress", + "name": "Respond to distress", + "description": "", + "parent": null, + "body": { + "Oa": "Activity" + } + }, + "9bd00e8c-125f-4b38-bd15-16571af01d89": { + "id": "9bd00e8c-125f-4b38-bd15-16571af01d89", + "alias": "reported_latitude", + "name": "Reported latitude", + "description": "", + "parent": "5de7b2ef-8012-484a-be40-5b4ce883223f", + "body": { + "Sa": { + "Shared": { + "DataField": { + "type_ref": "Real", + "minimum": 1, + "maximum": 1, + "unit": "degrees north" + } + } + } + } + }, + "9bdd35fb-5bb7-41a7-a909-a3a97d07ae33": { + "id": "9bdd35fb-5bb7-41a7-a909-a3a97d07ae33", + "alias": "vessel_service_lifeline", + "name": "Vessel service lifeline", + "description": "", + "parent": "df3b4429-398d-4d66-869b-784183e1e62d", + "body": { + "Sa": { + "Shared": { + "Lifeline": { + "represented": "8cda5e33-5731-40af-91d1-9060ea723935" + } + } + } + } + }, + "a1bd6431-2823-45b6-b669-27a2f6ecee24": { + "id": "a1bd6431-2823-45b6-b669-27a2f6ecee24", + "alias": "assessment_function_input", + "name": "Assessment function input", + "description": "", + "parent": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "body": { + "Sa": { + "Shared": { + "Port": { + "direction": "In", + "interface": "e13f9bc0-b8c7-4e91-b481-3732d6c08168" + } + } + } + } + }, + "b00cb246-cbde-49cd-b9c3-f22d7bdd96ec": { + "id": "b00cb246-cbde-49cd-b9c3-f22d7bdd96ec", + "alias": "backup_electrical_energy", + "name": "Backup electrical energy", + "description": "", + "parent": null, + "body": { + "Sa": { + "Shared": { + "ExchangeItem": { + "kind": "Energy" + } + } + } + } + }, + "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d": { + "id": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "alias": "classify_incident_and_alert_operator", + "name": "Classify incident and alert operator", + "description": "", + "parent": "fea9acb1-fa3a-4001-9677-784caf97c15b", + "body": { + "Sa": "Function" + } + }, + "b9dd4745-a110-4ff0-a599-f00f9e45bb88": { + "id": "b9dd4745-a110-4ff0-a599-f00f9e45bb88", + "alias": "vessel_in_distress", + "name": "Vessel in distress", + "description": "", + "parent": null, + "body": { + "Oa": "Actor" + } + }, + "bf5895c7-565c-4181-a604-6d338c019b12": { + "id": "bf5895c7-565c-4181-a604-6d338c019b12", + "alias": "degraded_reporting", + "name": "Degraded reporting", + "description": "", + "parent": "27c7dfaa-6a65-41e9-bf1a-1b1ba58912d5", + "body": { + "Sa": { + "Shared": { + "State": { + "kind": "Mode", + "entry": "", + "exit": "", + "do_activity": "" + } + } + } + } + }, + "c3945ca6-698b-4e7c-888d-2bb3788caffc": { + "id": "c3945ca6-698b-4e7c-888d-2bb3788caffc", + "alias": "reporting_operation_modes", + "name": "Reporting operation modes", + "description": "", + "parent": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", + "body": { + "Sa": { + "Shared": "StateMachine" + } + } + }, + "c68d6903-8ebe-4976-9f0c-835553fabd72": { + "id": "c68d6903-8ebe-4976-9f0c-835553fabd72", + "alias": "system_reporting_input", + "name": "System reporting input", + "description": "", + "parent": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", + "body": { + "Sa": { + "Shared": { + "Port": { + "direction": "In", + "interface": "e13f9bc0-b8c7-4e91-b481-3732d6c08168" + } + } + } + } + }, + "d48ccc42-f422-4026-b5c2-68bbe830abf6": { + "id": "d48ccc42-f422-4026-b5c2-68bbe830abf6", + "alias": "report_handled", + "name": "Report handled", + "description": "", + "parent": "34f9ddb2-bb79-4658-8932-c8393b9f5022", + "body": { + "Sa": { + "Shared": { + "Occurrence": { + "body": { + "Exchange": { + "exchange": "b9fa9d19-c1a5-4569-bef2-58ce788a75a3", + "sender": null, + "receiver": null, + "message_kind": "Asynchronous", + "reply_to": null, + "values": [] + } + }, + "precondition": "", + "postcondition": "" + } + } + } + } + }, + "d6b99909-2b10-41d5-8423-40afb3905673": { + "id": "d6b99909-2b10-41d5-8423-40afb3905673", + "alias": "transmit_distress_report", + "name": "Transmit distress report", + "description": "", + "parent": "fea9acb1-fa3a-4001-9677-784caf97c15b", + "body": { + "Sa": "Function" + } + }, + "df3b4429-398d-4d66-869b-784183e1e62d": { + "id": "df3b4429-398d-4d66-869b-784183e1e62d", + "alias": "repeated_distress_reports", + "name": "Repeated distress reports", + "description": "", + "parent": null, + "body": { + "Sa": { + "Shared": { + "Scenario": { + "viewpoint": "BoundaryInterface", + "context": "521b8f60-174d-47a4-a672-efff675ebf82", + "precondition": "A vessel has detected an emergency and the reporting service is available.", + "postcondition": "The operator has a classified incident with the latest vessel report.", + "steps": [ + "90d07c73-a950-4a68-8b65-c3964dfe5d19", + "5f09f99a-584a-4917-8b5d-4fda45f4932e" + ] + } + } + } + } + }, + "e13f9bc0-b8c7-4e91-b481-3732d6c08168": { + "id": "e13f9bc0-b8c7-4e91-b481-3732d6c08168", "alias": "distress_reporting_interface", "name": "Distress reporting interface", "description": "", @@ -531,510 +574,480 @@ "Shared": { "Interface": { "items": [ - "5e16affb-7fa4-4a3d-8bfe-6340586ab83f" + "5de7b2ef-8012-484a-be40-5b4ce883223f" ] } } } } }, - "f59b18f3-aa83-4050-9bc8-06ea0efaaa4b": { - "id": "f59b18f3-aa83-4050-9bc8-06ea0efaaa4b", - "alias": "incident_coordinator", - "name": "Incident coordinator", + "e5c72171-cd6a-49c6-be3d-db3bd48bc978": { + "id": "e5c72171-cd6a-49c6-be3d-db3bd48bc978", + "alias": "normal_reporting", + "name": "Normal reporting", "description": "", - "parent": null, - "body": { - "Oa": "Role" - } - }, - "f7514a9c-933c-4133-8b77-37c0dccd935f": { - "id": "f7514a9c-933c-4133-8b77-37c0dccd935f", - "alias": "repeated_distress_reports", - "name": "Repeated distress reports", - "description": "", - "parent": null, + "parent": "27c7dfaa-6a65-41e9-bf1a-1b1ba58912d5", "body": { "Sa": { "Shared": { - "Scenario": { - "context": "7781bd9f-e788-4049-9af4-9a3eab40d377", - "precondition": "A vessel has detected an emergency and the reporting service is available.", - "postcondition": "The operator has a classified incident with the latest vessel report.", - "steps": [ - "84a0db92-ac74-493a-af29-74ec7715d7fa", - "28b8e56d-7ddf-4950-8c30-7385c044cc72" - ] + "State": { + "kind": "Mode", + "entry": "", + "exit": "", + "do_activity": "" } } } } }, - "fa23a2a8-6f13-49e3-be47-f757f26d5c9f": { - "id": "fa23a2a8-6f13-49e3-be47-f757f26d5c9f", - "alias": "respond_to_distress", - "name": "Respond to distress", + "e74f3d77-766b-4a94-85cb-4a1e6fe4cf10": { + "id": "e74f3d77-766b-4a94-85cb-4a1e6fe4cf10", + "alias": "distress_report", + "name": "Distress report", "description": "", "parent": null, + "body": { + "Oa": { + "Shared": { + "ExchangeItem": { + "kind": "Information" + } + } + } + } + }, + "ebea3af4-39f1-4582-91ee-52fbdbd03b9f": { + "id": "ebea3af4-39f1-4582-91ee-52fbdbd03b9f", + "alias": "assess_incident", + "name": "Assess incident", + "description": "", + "parent": "9526e01a-1936-48fc-9b84-4639f63b9370", "body": { "Oa": "Activity" } }, - "fa6051e1-0e60-4a1e-bfa1-f7111e06b74f": { - "id": "fa6051e1-0e60-4a1e-bfa1-f7111e06b74f", - "alias": "assessment_function_input", - "name": "Assessment function input", + "f32ed660-9ef2-45a6-ab83-9ae0db133fda": { + "id": "f32ed660-9ef2-45a6-ab83-9ae0db133fda", + "alias": "report_function_output", + "name": "Report function output", "description": "", - "parent": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", + "parent": "d6b99909-2b10-41d5-8423-40afb3905673", "body": { "Sa": { "Shared": { "Port": { - "direction": "In", - "interface": "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4" + "direction": "Out", + "interface": "e13f9bc0-b8c7-4e91-b481-3732d6c08168" } } } } + }, + "fea9acb1-fa3a-4001-9677-784caf97c15b": { + "id": "fea9acb1-fa3a-4001-9677-784caf97c15b", + "alias": "manage_distress_response", + "name": "Manage distress response", + "description": "", + "parent": null, + "body": { + "Sa": "Function" + } } }, "relations": { - "00e36d6e-78e8-476a-bbd6-a6e3bcd5a018": { - "id": "00e36d6e-78e8-476a-bbd6-a6e3bcd5a018", - "alias": "signal_restored", - "name": "Signal restored", - "description": "", - "body": { - "StateTransition": { - "source": "d7fad7e9-d799-4fa6-b49f-1304d3285b5e", - "target": "d00b5d17-8660-4955-a70d-988a6e6b6c4e", - "trigger": "validated_report_received", - "guard": "position_is_current", - "effect": "Clear the degraded-reporting alert." - } - } - }, - "044cdc5f-a34a-4e51-9774-c1774a33dc91": { - "id": "044cdc5f-a34a-4e51-9774-c1774a33dc91", - "alias": "review_on_degraded_entry", - "name": "Review on degraded entry", - "description": "", - "body": { - "StateAction": { - "source": "d7fad7e9-d799-4fa6-b49f-1304d3285b5e", - "target": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", - "phase": "Entry" - } - } - }, - "17fef4ab-acc7-4f21-b70d-5d64f6ad1261": { - "id": "17fef4ab-acc7-4f21-b70d-5d64f6ad1261", + "01605431-cd83-4db9-aa81-a230ba6a2bf6": { + "id": "01605431-cd83-4db9-aa81-a230ba6a2bf6", "alias": "assesses_incident", "name": "Assesses incident", "description": "", "body": { "Allocation": { - "source": "721b68ab-5136-408e-890d-925215d5661e", - "target": "3388cc0d-0abc-4479-a948-6740266ec236" + "source": "5b8669e9-5071-4ef5-a7c4-ebb45f662841", + "target": "ebea3af4-39f1-4582-91ee-52fbdbd03b9f" } } }, - "2c092728-eafb-47e3-bcc7-8b795e36a25e": { - "id": "2c092728-eafb-47e3-bcc7-8b795e36a25e", - "alias": "assessment_in_degraded_mode", - "name": "Assessment in degraded mode", + "03b5cafa-6560-495e-9ad3-c7069e75a44e": { + "id": "03b5cafa-6560-495e-9ad3-c7069e75a44e", + "alias": "distress_reporting_connection", + "name": "Distress reporting connection", "description": "", "body": { - "Availability": { - "source": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", - "target": "d7fad7e9-d799-4fa6-b49f-1304d3285b5e" + "BoundaryExchange": { + "source": "2a9f2d3a-45eb-4a9b-b2aa-284d8ccb961b", + "target": "c68d6903-8ebe-4976-9f0c-835553fabd72", + "items": [ + "5de7b2ef-8012-484a-be40-5b4ce883223f" + ] } } }, - "331c78a2-b6b3-452f-a238-84a6a3df3547": { - "id": "331c78a2-b6b3-452f-a238-84a6a3df3547", + "084e26f6-d26b-4de5-8560-8eb19bc7b3dc": { + "id": "084e26f6-d26b-4de5-8560-8eb19bc7b3dc", + "alias": "mission_capability", + "name": "Mission capability", + "description": "", + "body": { + "MissionCapability": { + "source": "42bc4bd3-dab1-4b5b-9815-a5fd36a939f0", + "target": "521b8f60-174d-47a4-a672-efff675ebf82" + } + } + }, + "0b00c34d-bf48-46cf-bb46-43556b575fbc": { + "id": "0b00c34d-bf48-46cf-bb46-43556b575fbc", + "alias": "functional_chain_support", + "name": "Functional chain support", + "description": "", + "body": { + "ChainInvolvement": { + "source": "34f9ddb2-bb79-4658-8932-c8393b9f5022", + "target": "521b8f60-174d-47a4-a672-efff675ebf82" + } + } + }, + "0eca6687-28a9-479e-9fe0-485bf1a7a22e": { + "id": "0eca6687-28a9-479e-9fe0-485bf1a7a22e", + "alias": "review_on_degraded_entry", + "name": "Review on degraded entry", + "description": "", + "body": { + "StateAction": { + "source": "bf5895c7-565c-4181-a604-6d338c019b12", + "target": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "phase": "Entry" + } + } + }, + "3fced0b9-2362-4ac4-8caa-45aac3674412": { + "id": "3fced0b9-2362-4ac4-8caa-45aac3674412", "alias": "signal_degraded", "name": "Signal degraded", "description": "", "body": { "StateTransition": { - "source": "d00b5d17-8660-4955-a70d-988a6e6b6c4e", - "target": "d7fad7e9-d799-4fa6-b49f-1304d3285b5e", + "source": "e5c72171-cd6a-49c6-be3d-db3bd48bc978", + "target": "bf5895c7-565c-4181-a604-6d338c019b12", + "transition_kind": "External", + "triggers": [ + "7d7a7b65-c6df-42fc-bc94-3162261ad107" + ], + "effects": [], "trigger": "report_timeout", "guard": "seconds_since_last_report > 30", "effect": "Flag the incident and request an operator review." } } }, - "39ff3786-d94c-40ad-90fa-c009ab6f53f9": { - "id": "39ff3786-d94c-40ad-90fa-c009ab6f53f9", - "alias": "system_capability_support", - "name": "System capability support", + "401033be-3111-4e4f-a66a-4ff56d61670c": { + "id": "401033be-3111-4e4f-a66a-4ff56d61670c", + "alias": "assessment_in_normal_mode", + "name": "Assessment in normal mode", "description": "", "body": { - "CapabilityInvolvement": { - "source": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", - "target": "7781bd9f-e788-4049-9af4-9a3eab40d377" + "Availability": { + "source": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "target": "e5c72171-cd6a-49c6-be3d-db3bd48bc978" } } }, - "41d934ba-76f7-4425-b433-2d4d293ab0df": { - "id": "41d934ba-76f7-4425-b433-2d4d293ab0df", - "alias": "operational_realization", - "name": "Operational realization", + "56fdbdda-a9a7-48b4-9512-d0cec7f9066d": { + "id": "56fdbdda-a9a7-48b4-9512-d0cec7f9066d", + "alias": "distress_signal", + "name": "Distress signal", "description": "", "body": { - "ChainInvolvement": { - "source": "51c8ed9f-93ea-45fe-8829-e4ec88f09ce5", - "target": "6ca5efd6-2e92-4508-a02d-4013793743cb" + "Interaction": { + "source": "3e0a28ce-335f-4d39-80ac-5c04a0a22a7f", + "target": "ebea3af4-39f1-4582-91ee-52fbdbd03b9f", + "items": [ + "e74f3d77-766b-4a94-85cb-4a1e6fe4cf10" + ] } } }, - "4cf85b5a-eb4c-40f1-8bfc-06b30b24a9ef": { - "id": "4cf85b5a-eb4c-40f1-8bfc-06b30b24a9ef", + "65c050ec-af57-449f-a3d6-5f867c9d121a": { + "id": "65c050ec-af57-449f-a3d6-5f867c9d121a", "alias": "fulfils_coordinator_role", "name": "Fulfils coordinator role", "description": "", "body": { "RoleRealization": { - "source": "721b68ab-5136-408e-890d-925215d5661e", - "target": "f59b18f3-aa83-4050-9bc8-06ea0efaaa4b" + "source": "5b8669e9-5071-4ef5-a7c4-ebb45f662841", + "target": "39ba0d44-3f9d-4d98-bf9a-6c9b8c5ed041" } } }, - "5d34a01d-0dad-4a68-9b3b-998dce0d6e9b": { - "id": "5d34a01d-0dad-4a68-9b3b-998dce0d6e9b", + "6cafacbd-4a72-44d6-a3b2-587b246e202c": { + "id": "6cafacbd-4a72-44d6-a3b2-587b246e202c", + "alias": "coordinates_assessment", + "name": "Coordinates assessment", + "description": "", + "body": { + "RoleAssignment": { + "source": "39ba0d44-3f9d-4d98-bf9a-6c9b8c5ed041", + "target": "ebea3af4-39f1-4582-91ee-52fbdbd03b9f" + } + } + }, + "6d8cd148-e950-4f1d-978f-43e66ad00cd9": { + "id": "6d8cd148-e950-4f1d-978f-43e66ad00cd9", + "alias": "operational_contribution", + "name": "Operational contribution", + "description": "", + "body": { + "CapabilityInvolvement": { + "source": "ebea3af4-39f1-4582-91ee-52fbdbd03b9f", + "target": "334793e5-fdfd-427e-89d5-7cc91283c75a" + } + } + }, + "75701d38-2c85-4f67-9ccd-c48e4ad77420": { + "id": "75701d38-2c85-4f67-9ccd-c48e4ad77420", + "alias": "assessment_in_degraded_mode", + "name": "Assessment in degraded mode", + "description": "", + "body": { + "Availability": { + "source": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "target": "bf5895c7-565c-4181-a604-6d338c019b12" + } + } + }, + "94234700-0f4c-4233-9fc4-c90df4dc7b61": { + "id": "94234700-0f4c-4233-9fc4-c90df4dc7b61", + "alias": "system_assessment", + "name": "System assessment", + "description": "", + "body": { + "Allocation": { + "source": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", + "target": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d" + } + } + }, + "97c41496-b02a-4d9c-88c9-c3bb2332b7a2": { + "id": "97c41496-b02a-4d9c-88c9-c3bb2332b7a2", + "alias": "reporting_service_provided", + "name": "Reporting service provided", + "description": "", + "body": { + "InterfaceProvision": { + "source": "8cda5e33-5731-40af-91d1-9060ea723935", + "target": "e13f9bc0-b8c7-4e91-b481-3732d6c08168" + } + } + }, + "a990b96f-52be-4d71-ac0e-83e01a23a69a": { + "id": "a990b96f-52be-4d71-ac0e-83e01a23a69a", + "alias": "operational_realization", + "name": "Operational realization", + "description": "", + "body": { + "ChainInvolvement": { + "source": "86aa4bf3-6543-4e81-929b-f0fc3482ff77", + "target": "334793e5-fdfd-427e-89d5-7cc91283c75a" + } + } + }, + "b29fbe37-6543-4d89-826b-015dff8da216": { + "id": "b29fbe37-6543-4d89-826b-015dff8da216", + "alias": "reports_distress", + "name": "Reports distress", + "description": "", + "body": { + "Allocation": { + "source": "b9dd4745-a110-4ff0-a599-f00f9e45bb88", + "target": "3e0a28ce-335f-4d39-80ac-5c04a0a22a7f" + } + } + }, + "b93bac52-2a1a-47ac-92ff-3a7268b6b476": { + "id": "b93bac52-2a1a-47ac-92ff-3a7268b6b476", "alias": "initialize_reporting", "name": "Initialize reporting", "description": "", "body": { "StateTransition": { - "source": "0deb4c4c-d7cc-4dd9-bcc5-f357387cf978", - "target": "d00b5d17-8660-4955-a70d-988a6e6b6c4e", + "source": "26df594f-d55c-4d83-9907-fabad1e27572", + "target": "e5c72171-cd6a-49c6-be3d-db3bd48bc978", + "transition_kind": "External", + "triggers": [], + "effects": [], "trigger": "", "guard": "", "effect": "" } } }, - "64ab242b-6043-4452-9b28-7205fec309df": { - "id": "64ab242b-6043-4452-9b28-7205fec309df", - "alias": "operational_contribution", - "name": "Operational contribution", - "description": "", - "body": { - "CapabilityInvolvement": { - "source": "3388cc0d-0abc-4479-a948-6740266ec236", - "target": "6ca5efd6-2e92-4508-a02d-4013793743cb" - } - } - }, - "689a8e09-b7ca-4d97-b551-a21e3b438bfe": { - "id": "689a8e09-b7ca-4d97-b551-a21e3b438bfe", - "alias": "distress_signal", - "name": "Distress signal", - "description": "", - "body": { - "Interaction": { - "source": "d50e92c4-840e-4822-bcf7-033feb2eb879", - "target": "3388cc0d-0abc-4479-a948-6740266ec236", - "items": [ - "835c2e84-f4e9-4592-b5df-d205803d97b7" - ] - } - } - }, - "6a82e148-d38e-4103-8481-046b4c474952": { - "id": "6a82e148-d38e-4103-8481-046b4c474952", - "alias": "vessel_transmission", - "name": "Vessel transmission", - "description": "", - "body": { - "Allocation": { - "source": "cfb45cf5-bebe-4632-9bde-0ee023c42583", - "target": "b0a649d6-0558-48f5-8437-161be8329159" - } - } - }, - "7c32cbe5-0821-4793-a37f-9f017fc8a3f4": { - "id": "7c32cbe5-0821-4793-a37f-9f017fc8a3f4", - "alias": "reporting_service_required", - "name": "Reporting service required", - "description": "", - "body": { - "InterfaceRequirement": { - "source": "47e28c63-803b-4ea6-af92-e778f62ecc3e", - "target": "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4" - } - } - }, - "92468388-63c2-4f2c-a1fd-2c3f27b76398": { - "id": "92468388-63c2-4f2c-a1fd-2c3f27b76398", - "alias": "functional_chain_support", - "name": "Functional chain support", - "description": "", - "body": { - "ChainInvolvement": { - "source": "49743116-7777-4df8-9601-74fd4cba22c0", - "target": "7781bd9f-e788-4049-9af4-9a3eab40d377" - } - } - }, - "93e3a60d-33c0-4110-83d9-63f2902d5eeb": { - "id": "93e3a60d-33c0-4110-83d9-63f2902d5eeb", - "alias": "system_assessment", - "name": "System assessment", - "description": "", - "body": { - "Allocation": { - "source": "47e28c63-803b-4ea6-af92-e778f62ecc3e", - "target": "b1cc95c7-1d2f-42d0-9d93-587954bd563b" - } - } - }, - "a06f90b9-361b-4da2-86a9-0447df519e0c": { - "id": "a06f90b9-361b-4da2-86a9-0447df519e0c", - "alias": "coordinates_assessment", - "name": "Coordinates assessment", - "description": "", - "body": { - "RoleAssignment": { - "source": "f59b18f3-aa83-4050-9bc8-06ea0efaaa4b", - "target": "3388cc0d-0abc-4479-a948-6740266ec236" - } - } - }, - "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d": { - "id": "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d", + "b9fa9d19-c1a5-4569-bef2-58ce788a75a3": { + "id": "b9fa9d19-c1a5-4569-bef2-58ce788a75a3", "alias": "validated_distress_report", "name": "Validated distress report", "description": "", "body": { "FunctionalExchange": { - "source": "b0a649d6-0558-48f5-8437-161be8329159", - "target": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", - "source_port": "6ecf32ed-4009-48ba-b374-3bf156f6c355", - "target_port": "fa6051e1-0e60-4a1e-bfa1-f7111e06b74f", + "source": "d6b99909-2b10-41d5-8423-40afb3905673", + "target": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "source_port": "f32ed660-9ef2-45a6-ab83-9ae0db133fda", + "target_port": "a1bd6431-2823-45b6-b669-27a2f6ecee24", "items": [ - "5e16affb-7fa4-4a3d-8bfe-6340586ab83f" + "5de7b2ef-8012-484a-be40-5b4ce883223f" ] } } }, - "bce2587e-f47c-4d85-ac6d-a098170bbaa5": { - "id": "bce2587e-f47c-4d85-ac6d-a098170bbaa5", - "alias": "assessment_in_normal_mode", - "name": "Assessment in normal mode", - "description": "", - "body": { - "Availability": { - "source": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", - "target": "d00b5d17-8660-4955-a70d-988a6e6b6c4e" - } - } - }, - "d6a2c8d2-2a4f-4d90-a490-c2c661db4423": { - "id": "d6a2c8d2-2a4f-4d90-a490-c2c661db4423", + "cb767431-e196-4abf-9c7e-5b415caf2e53": { + "id": "cb767431-e196-4abf-9c7e-5b415caf2e53", "alias": "report_carried_by_connection", "name": "Report carried by connection", "description": "", "body": { "ExchangeAllocation": { - "source": "eb7ae249-165c-4717-bebc-da476eebb05e", - "target": "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d" + "source": "03b5cafa-6560-495e-9ad3-c7069e75a44e", + "target": "b9fa9d19-c1a5-4569-bef2-58ce788a75a3" } } }, - "e88a9747-0d1c-4813-8273-e6710f622e9b": { - "id": "e88a9747-0d1c-4813-8273-e6710f622e9b", - "alias": "mission_capability", - "name": "Mission capability", + "cf7aaa0b-71f6-4e6b-8c83-8ac87423c1fb": { + "id": "cf7aaa0b-71f6-4e6b-8c83-8ac87423c1fb", + "alias": "reporting_service_required", + "name": "Reporting service required", "description": "", "body": { - "MissionCapability": { - "source": "218e9ac0-1fdb-4ce8-bbcb-4cc5c36b3746", - "target": "7781bd9f-e788-4049-9af4-9a3eab40d377" + "InterfaceRequirement": { + "source": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", + "target": "e13f9bc0-b8c7-4e91-b481-3732d6c08168" } } }, - "eb7ae249-165c-4717-bebc-da476eebb05e": { - "id": "eb7ae249-165c-4717-bebc-da476eebb05e", - "alias": "distress_reporting_connection", - "name": "Distress reporting connection", - "description": "", - "body": { - "BoundaryExchange": { - "source": "a0e18d73-a9ce-4e9e-8ecf-0a54b1412932", - "target": "8477d19d-4a62-43bb-a7e3-845b9b3d1002", - "items": [ - "5e16affb-7fa4-4a3d-8bfe-6340586ab83f" - ] - } - } - }, - "ec3f9e3f-5134-49af-9969-29f818dfcb46": { - "id": "ec3f9e3f-5134-49af-9969-29f818dfcb46", - "alias": "reporting_service_provided", - "name": "Reporting service provided", - "description": "", - "body": { - "InterfaceProvision": { - "source": "cfb45cf5-bebe-4632-9bde-0ee023c42583", - "target": "f008c7a3-9bda-4b7e-a4c5-8ee736183cb4" - } - } - }, - "f844c555-b407-402c-81c9-4928245249ca": { - "id": "f844c555-b407-402c-81c9-4928245249ca", - "alias": "reports_distress", - "name": "Reports distress", + "df07c2ae-cee6-4ca9-8433-809aee36f6bd": { + "id": "df07c2ae-cee6-4ca9-8433-809aee36f6bd", + "alias": "vessel_transmission", + "name": "Vessel transmission", "description": "", "body": { "Allocation": { - "source": "7e8ea298-1c68-4c9e-994d-6008d47f62ce", - "target": "d50e92c4-840e-4822-bcf7-033feb2eb879" + "source": "8cda5e33-5731-40af-91d1-9060ea723935", + "target": "d6b99909-2b10-41d5-8423-40afb3905673" + } + } + }, + "e72da212-c2ac-476a-b083-ace00756b5e1": { + "id": "e72da212-c2ac-476a-b083-ace00756b5e1", + "alias": "system_capability_support", + "name": "System capability support", + "description": "", + "body": { + "CapabilityInvolvement": { + "source": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "target": "521b8f60-174d-47a4-a672-efff675ebf82" + } + } + }, + "fc699be4-387c-4b6a-9514-3a9e54aa101e": { + "id": "fc699be4-387c-4b6a-9514-3a9e54aa101e", + "alias": "signal_restored", + "name": "Signal restored", + "description": "", + "body": { + "StateTransition": { + "source": "bf5895c7-565c-4181-a604-6d338c019b12", + "target": "e5c72171-cd6a-49c6-be3d-db3bd48bc978", + "transition_kind": "External", + "triggers": [ + "8be42c58-6486-4038-aaa9-5aea2dce3b65" + ], + "effects": [], + "trigger": "validated_report_received", + "guard": "position_is_current", + "effect": "Clear the degraded-reporting alert." } } } }, "diagrams": { - "064d0c1c-5db0-4516-ab6f-5bbf18d02e6a": { - "id": "064d0c1c-5db0-4516-ab6f-5bbf18d02e6a", + "181c5d1c-9b20-4223-b0d7-0465cfcdd988": { + "id": "181c5d1c-9b20-4223-b0d7-0465cfcdd988", "alias": "sa_system_boundary_and_functions", "name": "SA system boundary and functions", "description": "A focused projection of the shared engineering model.", "layer": "Sa", "projection": "Allocation", "nodes": { - "00edf6bc-b857-439a-8747-f1f66c1675e2": { - "id": "00edf6bc-b857-439a-8747-f1f66c1675e2", + "1e59932f-3c3f-4ff7-b3d7-a56ea45a8757": { + "id": "1e59932f-3c3f-4ff7-b3d7-a56ea45a8757", "alias": "view_vessel_communication_service", - "element": "cfb45cf5-bebe-4632-9bde-0ee023c42583", + "element": "8cda5e33-5731-40af-91d1-9060ea723935", "position": { "x": 60.0, "y": 60.0 }, "size": { "width": 272.0, - "height": 166.0 + "height": 248.0 }, "collapsed": false }, - "035dab75-ef9e-4ca3-a107-87262e3c680b": { - "id": "035dab75-ef9e-4ca3-a107-87262e3c680b", + "3dbe9ac3-4058-47f8-a112-94f81da8b113": { + "id": "3dbe9ac3-4058-47f8-a112-94f81da8b113", "alias": "view_transmit_distress_report", - "element": "b0a649d6-0558-48f5-8437-161be8329159", + "element": "d6b99909-2b10-41d5-8423-40afb3905673", "position": { "x": 84.0, - "y": 108.0 + "y": 124.0 }, "size": { "width": 224.0, - "height": 94.0 + "height": 132.0 }, "collapsed": false }, - "16b5055a-c98b-4276-b564-85b7fe1f020f": { - "id": "16b5055a-c98b-4276-b564-85b7fe1f020f", - "alias": "view_support_timely_rescue_decisions", - "element": "218e9ac0-1fdb-4ce8-bbcb-4cc5c36b3746", - "position": { - "x": 392.0, - "y": 60.0 - }, - "size": { - "width": 224.0, - "height": 94.0 - }, - "collapsed": false - }, - "4aa2fb09-b367-402c-a438-d4f918f04e08": { - "id": "4aa2fb09-b367-402c-a438-d4f918f04e08", - "alias": "view_digital_distress_handling", - "element": "49743116-7777-4df8-9601-74fd4cba22c0", - "position": { - "x": 676.0, - "y": 60.0 - }, - "size": { - "width": 224.0, - "height": 94.0 - }, - "collapsed": false - }, - "5a6d6a1c-9915-4e33-8299-b512c50b18f5": { - "id": "5a6d6a1c-9915-4e33-8299-b512c50b18f5", + "5113e074-4e3b-4e6e-8b33-4081cdedb02a": { + "id": "5113e074-4e3b-4e6e-8b33-4081cdedb02a", "alias": "view_rescue_coordination_system", - "element": "47e28c63-803b-4ea6-af92-e778f62ecc3e", + "element": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", "position": { - "x": 960.0, + "x": 572.0, "y": 60.0 }, "size": { "width": 272.0, - "height": 166.0 + "height": 248.0 }, "collapsed": false }, - "621e0e5e-d1be-4693-b95a-7c48d36e07b4": { - "id": "621e0e5e-d1be-4693-b95a-7c48d36e07b4", - "alias": "view_manage_distress_response", - "element": "c64f93a7-bf47-42b5-b432-7589b9144f2c", - "position": { - "x": 60.0, - "y": 286.0 - }, - "size": { - "width": 224.0, - "height": 94.0 - }, - "collapsed": false - }, - "9f41eaff-3456-494b-b136-9f6f01afd90f": { - "id": "9f41eaff-3456-494b-b136-9f6f01afd90f", - "alias": "view_coordinate_rescue_response", - "element": "7781bd9f-e788-4049-9af4-9a3eab40d377", - "position": { - "x": 344.0, - "y": 286.0 - }, - "size": { - "width": 224.0, - "height": 94.0 - }, - "collapsed": false - }, - "e75a6c26-dc64-4fa3-bc8f-a1a38e1f9b68": { - "id": "e75a6c26-dc64-4fa3-bc8f-a1a38e1f9b68", + "d7cfae62-b32f-44e0-a98e-89765da3d4e2": { + "id": "d7cfae62-b32f-44e0-a98e-89765da3d4e2", "alias": "view_classify_incident_and_alert_operator", - "element": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", + "element": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", "position": { - "x": 984.0, - "y": 108.0 + "x": 596.0, + "y": 124.0 }, "size": { "width": 224.0, - "height": 94.0 + "height": 132.0 }, "collapsed": false } } }, - "a67786d6-5b08-4b06-a0c8-584a04f179ef": { - "id": "a67786d6-5b08-4b06-a0c8-584a04f179ef", - "alias": "sa_functional_decomposition", - "name": "SA functional decomposition", + "78fe5575-54ec-4898-840b-db3fe0bbcea1": { + "id": "78fe5575-54ec-4898-840b-db3fe0bbcea1", + "alias": "sa_missions_and_capabilities", + "name": "SA missions and capabilities", "description": "A focused projection of the shared engineering model.", "layer": "Sa", - "projection": "Decomposition", + "projection": "Capabilities", "nodes": { - "5ae489f2-4be1-4842-b464-37900983e333": { - "id": "5ae489f2-4be1-4842-b464-37900983e333", - "alias": "view_classify_incident_and_alert_operator_5ae489f2", - "element": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", + "15f17f55-b5ac-48f5-8476-c96ec4ba4707": { + "id": "15f17f55-b5ac-48f5-8476-c96ec4ba4707", + "alias": "view_coordinate_rescue_response", + "element": "521b8f60-174d-47a4-a672-efff675ebf82", "position": { - "x": 84.0, - "y": 108.0 + "x": 988.0, + "y": 60.0 }, "size": { "width": 224.0, @@ -1042,107 +1055,65 @@ }, "collapsed": false }, - "80ab61e0-d1f2-4008-9858-0759bdaa02e3": { - "id": "80ab61e0-d1f2-4008-9858-0759bdaa02e3", - "alias": "view_manage_distress_response_80ab61e0", - "element": "c64f93a7-bf47-42b5-b432-7589b9144f2c", + "3db00caf-b5bb-4241-bb69-017497c20340": { + "id": "3db00caf-b5bb-4241-bb69-017497c20340", + "alias": "view_rescue_coordination_system_3db00caf", + "element": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", "position": { "x": 60.0, "y": 60.0 }, "size": { - "width": 272.0, - "height": 276.0 + "width": 224.0, + "height": 132.0 }, "collapsed": false }, - "e02431fd-c27e-4b48-9c94-37b8e3d55375": { - "id": "e02431fd-c27e-4b48-9c94-37b8e3d55375", - "alias": "view_transmit_distress_report_e02431fd", - "element": "b0a649d6-0558-48f5-8437-161be8329159", + "7508ba39-d8bb-45d8-92df-f22764c8536e": { + "id": "7508ba39-d8bb-45d8-92df-f22764c8536e", + "alias": "view_support_timely_rescue_decisions", + "element": "42bc4bd3-dab1-4b5b-9815-a5fd36a939f0", "position": { - "x": 84.0, - "y": 218.0 + "x": 524.0, + "y": 60.0 }, "size": { "width": 224.0, "height": 94.0 }, "collapsed": false + }, + "dd551ce6-a062-476f-82f9-44b0549e0459": { + "id": "dd551ce6-a062-476f-82f9-44b0549e0459", + "alias": "view_vessel_communication_service_dd551ce6", + "element": "8cda5e33-5731-40af-91d1-9060ea723935", + "position": { + "x": 1452.0, + "y": 60.0 + }, + "size": { + "width": 224.0, + "height": 132.0 + }, + "collapsed": false } } }, - "d7f59b88-4a9b-4906-b859-1c6d044bbb52": { - "id": "d7f59b88-4a9b-4906-b859-1c6d044bbb52", + "7fdd7f39-a225-442f-8588-05d77284ba6b": { + "id": "7fdd7f39-a225-442f-8588-05d77284ba6b", "alias": "oa_participants_and_activities", "name": "OA participants and activities", "description": "A focused projection of the shared engineering model.", "layer": "Oa", "projection": "Allocation", "nodes": { - "2f5fed31-e2dc-419d-9ebc-a5c9e9682277": { - "id": "2f5fed31-e2dc-419d-9ebc-a5c9e9682277", - "alias": "view_rescue_coordination", - "element": "721b68ab-5136-408e-890d-925215d5661e", - "position": { - "x": 60.0, - "y": 60.0 - }, - "size": { - "width": 272.0, - "height": 166.0 - }, - "collapsed": false - }, - "91fe2d63-0083-4df2-9c29-563766e1b706": { - "id": "91fe2d63-0083-4df2-9c29-563766e1b706", - "alias": "view_protect_life_at_sea", - "element": "6ca5efd6-2e92-4508-a02d-4013793743cb", - "position": { - "x": 392.0, - "y": 60.0 - }, - "size": { - "width": 224.0, - "height": 94.0 - }, - "collapsed": false - }, - "a045fd40-84ea-48f3-a6d4-95641492d960": { - "id": "a045fd40-84ea-48f3-a6d4-95641492d960", - "alias": "view_distress_to_response", - "element": "51c8ed9f-93ea-45fe-8829-e4ec88f09ce5", - "position": { - "x": 676.0, - "y": 60.0 - }, - "size": { - "width": 224.0, - "height": 94.0 - }, - "collapsed": false - }, - "a2cabc9f-c12c-4eff-8acf-0e9b86829cbe": { - "id": "a2cabc9f-c12c-4eff-8acf-0e9b86829cbe", + "07438ef3-fedd-409d-8d39-3e4a712a8dce": { + "id": "07438ef3-fedd-409d-8d39-3e4a712a8dce", "alias": "view_report_distress", - "element": "d50e92c4-840e-4822-bcf7-033feb2eb879", - "position": { - "x": 984.0, - "y": 108.0 - }, - "size": { - "width": 224.0, - "height": 94.0 - }, - "collapsed": false - }, - "acaa5a3d-51c4-45da-b5aa-4825bccd747c": { - "id": "acaa5a3d-51c4-45da-b5aa-4825bccd747c", - "alias": "view_assess_incident", - "element": "3388cc0d-0abc-4479-a948-6740266ec236", + "element": "3e0a28ce-335f-4d39-80ac-5c04a0a22a7f", "position": { "x": 84.0, - "y": 108.0 + "y": 124.0 }, "size": { "width": 224.0, @@ -1150,27 +1121,65 @@ }, "collapsed": false }, - "af3a61b3-db02-400f-bd18-b4422e2db7a7": { - "id": "af3a61b3-db02-400f-bd18-b4422e2db7a7", - "alias": "view_vessel_in_distress", - "element": "7e8ea298-1c68-4c9e-994d-6008d47f62ce", + "0e9765db-e564-49e8-8c4e-8cf94c06b9d4": { + "id": "0e9765db-e564-49e8-8c4e-8cf94c06b9d4", + "alias": "view_rescue_coordination", + "element": "5b8669e9-5071-4ef5-a7c4-ebb45f662841", "position": { - "x": 960.0, + "x": 572.0, "y": 60.0 }, "size": { "width": 272.0, - "height": 166.0 + "height": 182.0 }, "collapsed": false }, - "e4c687d7-4a44-4dee-a2d8-bdbe6a5cf649": { - "id": "e4c687d7-4a44-4dee-a2d8-bdbe6a5cf649", - "alias": "view_respond_to_distress", - "element": "fa23a2a8-6f13-49e3-be47-f757f26d5c9f", + "20c607f1-1c2b-4fef-8cff-6e122fc7939b": { + "id": "20c607f1-1c2b-4fef-8cff-6e122fc7939b", + "alias": "view_vessel_in_distress", + "element": "b9dd4745-a110-4ff0-a599-f00f9e45bb88", "position": { "x": 60.0, - "y": 286.0 + "y": 60.0 + }, + "size": { + "width": 272.0, + "height": 182.0 + }, + "collapsed": false + }, + "3e5163ae-436f-45e6-9130-b3d3781a2f03": { + "id": "3e5163ae-436f-45e6-9130-b3d3781a2f03", + "alias": "view_assess_incident", + "element": "ebea3af4-39f1-4582-91ee-52fbdbd03b9f", + "position": { + "x": 596.0, + "y": 124.0 + }, + "size": { + "width": 224.0, + "height": 94.0 + }, + "collapsed": false + } + } + }, + "b1b0a28b-5a92-46e4-ba35-9637d6b9720d": { + "id": "b1b0a28b-5a92-46e4-ba35-9637d6b9720d", + "alias": "oa_capabilities_and_participants", + "name": "OA capabilities and participants", + "description": "A focused projection of the shared engineering model.", + "layer": "Oa", + "projection": "Capabilities", + "nodes": { + "91ff9ff9-3f1b-42e5-8754-1c280cf9d3bf": { + "id": "91ff9ff9-3f1b-42e5-8754-1c280cf9d3bf", + "alias": "view_rescue_coordination_91ff9ff9", + "element": "5b8669e9-5071-4ef5-a7c4-ebb45f662841", + "position": { + "x": 988.0, + "y": 60.0 }, "size": { "width": 224.0, @@ -1178,169 +1187,187 @@ }, "collapsed": false }, - "fcbda72a-5478-4d77-8330-16f89cdefc37": { - "id": "fcbda72a-5478-4d77-8330-16f89cdefc37", + "96abcbf4-fe39-41a2-bc7a-896260b0e6f5": { + "id": "96abcbf4-fe39-41a2-bc7a-896260b0e6f5", "alias": "view_incident_coordinator", - "element": "f59b18f3-aa83-4050-9bc8-06ea0efaaa4b", + "element": "39ba0d44-3f9d-4d98-bf9a-6c9b8c5ed041", "position": { - "x": 344.0, - "y": 286.0 + "x": 60.0, + "y": 60.0 }, "size": { "width": 224.0, "height": 94.0 }, "collapsed": false + }, + "e4aaf25f-ae0d-49d0-93c2-c481d2770f09": { + "id": "e4aaf25f-ae0d-49d0-93c2-c481d2770f09", + "alias": "view_vessel_in_distress_e4aaf25f", + "element": "b9dd4745-a110-4ff0-a599-f00f9e45bb88", + "position": { + "x": 1452.0, + "y": 60.0 + }, + "size": { + "width": 224.0, + "height": 94.0 + }, + "collapsed": false + }, + "f14d122d-32ca-42e4-bf2c-1d34be1b2bcc": { + "id": "f14d122d-32ca-42e4-bf2c-1d34be1b2bcc", + "alias": "view_protect_life_at_sea", + "element": "334793e5-fdfd-427e-89d5-7cc91283c75a", + "position": { + "x": 524.0, + "y": 60.0 + }, + "size": { + "width": 224.0, + "height": 94.0 + }, + "collapsed": false + } + } + }, + "bdfa2607-3900-45f8-9382-3065573942dd": { + "id": "bdfa2607-3900-45f8-9382-3065573942dd", + "alias": "oa_activity_dataflow", + "name": "OA activity dataflow", + "description": "A focused projection of the shared engineering model.", + "layer": "Oa", + "projection": "FunctionalDataflow", + "nodes": { + "4fb9673b-b13d-4f29-9bc1-73db1004d0df": { + "id": "4fb9673b-b13d-4f29-9bc1-73db1004d0df", + "alias": "view_assess_incident_4fb9673b", + "element": "ebea3af4-39f1-4582-91ee-52fbdbd03b9f", + "position": { + "x": 84.0, + "y": 124.0 + }, + "size": { + "width": 224.0, + "height": 94.0 + }, + "collapsed": false + }, + "9e6cc97a-cc88-4630-894e-4ddb9dbf8c23": { + "id": "9e6cc97a-cc88-4630-894e-4ddb9dbf8c23", + "alias": "view_report_distress_9e6cc97a", + "element": "3e0a28ce-335f-4d39-80ac-5c04a0a22a7f", + "position": { + "x": 84.0, + "y": 234.0 + }, + "size": { + "width": 224.0, + "height": 94.0 + }, + "collapsed": false + }, + "c9f9d743-d1e0-4672-a874-29fb98296507": { + "id": "c9f9d743-d1e0-4672-a874-29fb98296507", + "alias": "view_respond_to_distress", + "element": "9526e01a-1936-48fc-9b84-4639f63b9370", + "position": { + "x": 60.0, + "y": 60.0 + }, + "size": { + "width": 272.0, + "height": 292.0 + }, + "collapsed": false + } + } + }, + "d8764c63-336d-4558-ac58-dba9dfa74c87": { + "id": "d8764c63-336d-4558-ac58-dba9dfa74c87", + "alias": "sa_functional_decomposition", + "name": "SA functional decomposition", + "description": "A focused projection of the shared engineering model.", + "layer": "Sa", + "projection": "FunctionalDataflow", + "nodes": { + "4444f7de-c924-429f-8703-f484a8ee4dce": { + "id": "4444f7de-c924-429f-8703-f484a8ee4dce", + "alias": "view_transmit_distress_report_4444f7de", + "element": "d6b99909-2b10-41d5-8423-40afb3905673", + "position": { + "x": 84.0, + "y": 124.0 + }, + "size": { + "width": 224.0, + "height": 132.0 + }, + "collapsed": false + }, + "96fbd2d9-a6f2-4889-8e0e-a664eba39e07": { + "id": "96fbd2d9-a6f2-4889-8e0e-a664eba39e07", + "alias": "view_manage_distress_response", + "element": "fea9acb1-fa3a-4001-9677-784caf97c15b", + "position": { + "x": 60.0, + "y": 60.0 + }, + "size": { + "width": 272.0, + "height": 368.0 + }, + "collapsed": false + }, + "e8dbf569-226f-4004-bd24-cee2a2072b2c": { + "id": "e8dbf569-226f-4004-bd24-cee2a2072b2c", + "alias": "view_classify_incident_and_alert_operator_e8dbf569", + "element": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", + "position": { + "x": 84.0, + "y": 272.0 + }, + "size": { + "width": 224.0, + "height": 132.0 + }, + "collapsed": false } } } }, "artifact_links": { - "091b5a40-1631-49ef-8b53-1471c016a13f": { - "id": "091b5a40-1631-49ef-8b53-1471c016a13f", - "alias": "console_enclosure_cad", - "name": "Console enclosure CAD", - "description": "Illustrative external engineering reference; opening a model does not fetch it.", - "owner": "47e28c63-803b-4ea6-af92-e778f62ecc3e", - "relation": "References", - "uri": "cad://rescue-console/enclosure.step", - "revision": "B.3", - "fragment": null - }, - "0b09f95e-0545-44c3-b687-84489ce1422b": { - "id": "0b09f95e-0545-44c3-b687-84489ce1422b", + "2c11e575-9636-426b-8a46-8d696c25c9e0": { + "id": "2c11e575-9636-426b-8a46-8d696c25c9e0", "alias": "response_implementation", "name": "Response implementation", "description": "Illustrative external engineering reference; opening a model does not fetch it.", - "owner": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", + "owner": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", "relation": "Implements", "uri": "git+https://example.org/rescue/control?path=src/response.rs", "revision": "design-v2", "fragment": null + }, + "b6003fcd-a5d6-4b22-b17b-9110759d8064": { + "id": "b6003fcd-a5d6-4b22-b17b-9110759d8064", + "alias": "console_enclosure_cad", + "name": "Console enclosure CAD", + "description": "Illustrative external engineering reference; opening a model does not fetch it.", + "owner": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", + "relation": "References", + "uri": "cad://rescue-console/enclosure.step", + "revision": "B.3", + "fragment": null } }, "traces": { - "1d0a908f-9e22-42b7-9aac-26bbe3f5df78": { - "id": "1d0a908f-9e22-42b7-9aac-26bbe3f5df78", - "alias": "trace_respond_to_distress", - "name": "Respond to distress ↔ Manage distress response", - "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "fa23a2a8-6f13-49e3-be47-f757f26d5c9f", - "sa": "c64f93a7-bf47-42b5-b432-7589b9144f2c", - "kind": "Refinement", - "baseline": { - "oa": { - "name": "Respond to distress", - "description": "" - }, - "sa": { - "name": "Manage distress response", - "description": "" - } - } - }, - "49f2b55a-6dcc-44ba-a68f-a305942db7c9": { - "id": "49f2b55a-6dcc-44ba-a68f-a305942db7c9", - "alias": "trace_rescue_coordination", - "name": "Rescue coordination ↔ Rescue coordination system", - "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "721b68ab-5136-408e-890d-925215d5661e", - "sa": "47e28c63-803b-4ea6-af92-e778f62ecc3e", - "kind": "Participant", - "baseline": { - "oa": { - "name": "Rescue coordination", - "description": "" - }, - "sa": { - "name": "Rescue coordination system", - "description": "" - } - } - }, - "4ac98979-6c84-4a66-b043-373b70bb5203": { - "id": "4ac98979-6c84-4a66-b043-373b70bb5203", - "alias": "trace_distress_to_response", - "name": "Distress to response ↔ Digital distress handling", - "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "51c8ed9f-93ea-45fe-8829-e4ec88f09ce5", - "sa": "49743116-7777-4df8-9601-74fd4cba22c0", - "kind": "Sequence", - "baseline": { - "oa": { - "name": "Distress to response", - "description": "" - }, - "sa": { - "name": "Digital distress handling", - "description": "" - } - } - }, - "4b6acf23-dab3-462d-b45f-066aea916932": { - "id": "4b6acf23-dab3-462d-b45f-066aea916932", - "alias": "trace_protect_life_at_sea", - "name": "Protect life at sea ↔ Coordinate rescue response", - "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "6ca5efd6-2e92-4508-a02d-4013793743cb", - "sa": "7781bd9f-e788-4049-9af4-9a3eab40d377", - "kind": "Capability", - "baseline": { - "oa": { - "name": "Protect life at sea", - "description": "" - }, - "sa": { - "name": "Coordinate rescue response", - "description": "" - } - } - }, - "587cca51-69e8-47e7-9674-32ff49926a22": { - "id": "587cca51-69e8-47e7-9674-32ff49926a22", - "alias": "trace_distress_signal", - "name": "Distress signal ↔ Validated distress report", - "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "689a8e09-b7ca-4d97-b551-a21e3b438bfe", - "sa": "ae3ceb52-113f-40b3-8a90-fd6e6b8c775d", - "kind": "Exchange", - "baseline": { - "oa": { - "name": "Distress signal", - "description": "" - }, - "sa": { - "name": "Validated distress report", - "description": "" - } - } - }, - "7790684b-220f-443d-8754-52c29414367f": { - "id": "7790684b-220f-443d-8754-52c29414367f", - "alias": "trace_distress_report", - "name": "Distress report ↔ Digital distress report", - "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "835c2e84-f4e9-4592-b5df-d205803d97b7", - "sa": "5e16affb-7fa4-4a3d-8bfe-6340586ab83f", - "kind": "Item", - "baseline": { - "oa": { - "name": "Distress report", - "description": "" - }, - "sa": { - "name": "Digital distress report", - "description": "" - } - } - }, - "9a8101e4-ebce-4836-a0e3-63440c2e1e87": { - "id": "9a8101e4-ebce-4836-a0e3-63440c2e1e87", + "268f4a8f-0ba1-4218-9698-31e76cbd38ec": { + "id": "268f4a8f-0ba1-4218-9698-31e76cbd38ec", "alias": "trace_vessel_in_distress", "name": "Vessel in distress ↔ Vessel communication service", "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "7e8ea298-1c68-4c9e-994d-6008d47f62ce", - "sa": "cfb45cf5-bebe-4632-9bde-0ee023c42583", + "oa": "b9dd4745-a110-4ff0-a599-f00f9e45bb88", + "sa": "8cda5e33-5731-40af-91d1-9060ea723935", "kind": "Participant", "baseline": { "oa": { @@ -1353,13 +1380,89 @@ } } }, - "b8fee65b-21da-4a27-9b42-575d417bd942": { - "id": "b8fee65b-21da-4a27-9b42-575d417bd942", + "3d77a609-3426-4317-83c4-74dfa6558e6c": { + "id": "3d77a609-3426-4317-83c4-74dfa6558e6c", + "alias": "trace_respond_to_distress", + "name": "Respond to distress ↔ Manage distress response", + "description": "Reviewed OA/SA correspondence in the coastal rescue example.", + "oa": "9526e01a-1936-48fc-9b84-4639f63b9370", + "sa": "fea9acb1-fa3a-4001-9677-784caf97c15b", + "kind": "Refinement", + "baseline": { + "oa": { + "name": "Respond to distress", + "description": "" + }, + "sa": { + "name": "Manage distress response", + "description": "" + } + } + }, + "4b5f05e7-fa2f-4281-a046-d358a0ac03d5": { + "id": "4b5f05e7-fa2f-4281-a046-d358a0ac03d5", + "alias": "trace_report_distress", + "name": "Report distress ↔ Transmit distress report", + "description": "Reviewed OA/SA correspondence in the coastal rescue example.", + "oa": "3e0a28ce-335f-4d39-80ac-5c04a0a22a7f", + "sa": "d6b99909-2b10-41d5-8423-40afb3905673", + "kind": "Refinement", + "baseline": { + "oa": { + "name": "Report distress", + "description": "" + }, + "sa": { + "name": "Transmit distress report", + "description": "" + } + } + }, + "4ca472c7-de50-4217-96e0-7dee7d8bcb3a": { + "id": "4ca472c7-de50-4217-96e0-7dee7d8bcb3a", + "alias": "trace_protect_life_at_sea", + "name": "Protect life at sea ↔ Coordinate rescue response", + "description": "Reviewed OA/SA correspondence in the coastal rescue example.", + "oa": "334793e5-fdfd-427e-89d5-7cc91283c75a", + "sa": "521b8f60-174d-47a4-a672-efff675ebf82", + "kind": "Capability", + "baseline": { + "oa": { + "name": "Protect life at sea", + "description": "" + }, + "sa": { + "name": "Coordinate rescue response", + "description": "" + } + } + }, + "6c3fe0b0-b7b0-4d66-8450-3736349f935f": { + "id": "6c3fe0b0-b7b0-4d66-8450-3736349f935f", + "alias": "trace_distress_report", + "name": "Distress report ↔ Digital distress report", + "description": "Reviewed OA/SA correspondence in the coastal rescue example.", + "oa": "e74f3d77-766b-4a94-85cb-4a1e6fe4cf10", + "sa": "5de7b2ef-8012-484a-be40-5b4ce883223f", + "kind": "Item", + "baseline": { + "oa": { + "name": "Distress report", + "description": "" + }, + "sa": { + "name": "Digital distress report", + "description": "" + } + } + }, + "ad41088e-62b6-4e52-b63a-970a939ea77a": { + "id": "ad41088e-62b6-4e52-b63a-970a939ea77a", "alias": "trace_assess_incident", "name": "Assess incident ↔ Classify incident and alert operator", "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "3388cc0d-0abc-4479-a948-6740266ec236", - "sa": "b1cc95c7-1d2f-42d0-9d93-587954bd563b", + "oa": "ebea3af4-39f1-4582-91ee-52fbdbd03b9f", + "sa": "b87858d8-3e9a-4f5a-bbb8-4648e743bf0d", "kind": "Refinement", "baseline": { "oa": { @@ -1372,13 +1475,51 @@ } } }, - "be4365d6-2a43-433c-935f-c039b266242f": { - "id": "be4365d6-2a43-433c-935f-c039b266242f", + "e3d46af5-47b7-42a5-b92f-48ebbe0b9a1d": { + "id": "e3d46af5-47b7-42a5-b92f-48ebbe0b9a1d", + "alias": "trace_distress_signal", + "name": "Distress signal ↔ Validated distress report", + "description": "Reviewed OA/SA correspondence in the coastal rescue example.", + "oa": "56fdbdda-a9a7-48b4-9512-d0cec7f9066d", + "sa": "b9fa9d19-c1a5-4569-bef2-58ce788a75a3", + "kind": "Exchange", + "baseline": { + "oa": { + "name": "Distress signal", + "description": "" + }, + "sa": { + "name": "Validated distress report", + "description": "" + } + } + }, + "e5ea9201-6fb6-4e9e-b3c6-e9d0bc167c21": { + "id": "e5ea9201-6fb6-4e9e-b3c6-e9d0bc167c21", + "alias": "trace_rescue_coordination", + "name": "Rescue coordination ↔ Rescue coordination system", + "description": "Reviewed OA/SA correspondence in the coastal rescue example.", + "oa": "5b8669e9-5071-4ef5-a7c4-ebb45f662841", + "sa": "2027bca4-204e-40fe-a6af-fa2f74e4ce0e", + "kind": "Participant", + "baseline": { + "oa": { + "name": "Rescue coordination", + "description": "" + }, + "sa": { + "name": "Rescue coordination system", + "description": "" + } + } + }, + "ea6c8ccb-2822-42bc-968e-41a3960bff28": { + "id": "ea6c8ccb-2822-42bc-968e-41a3960bff28", "alias": "trace_distress_received", "name": "Distress received ↔ Report handled", "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "5e0c0d0e-5eb5-467c-bc35-dfe29d534703", - "sa": "bcdb57f1-5fa8-46ce-9498-b467cea5d98f", + "oa": "1c1b700a-45e2-418d-8f1c-40e57e409434", + "sa": "d48ccc42-f422-4026-b5c2-68bbe830abf6", "kind": "Scenario", "baseline": { "oa": { @@ -1391,21 +1532,21 @@ } } }, - "d3f224a5-0b2d-4eba-93c9-232b9e84e742": { - "id": "d3f224a5-0b2d-4eba-93c9-232b9e84e742", - "alias": "trace_report_distress", - "name": "Report distress ↔ Transmit distress report", + "ebf036d6-1504-4386-bbe2-87e0b12338f6": { + "id": "ebf036d6-1504-4386-bbe2-87e0b12338f6", + "alias": "trace_distress_to_response", + "name": "Distress to response ↔ Digital distress handling", "description": "Reviewed OA/SA correspondence in the coastal rescue example.", - "oa": "d50e92c4-840e-4822-bcf7-033feb2eb879", - "sa": "b0a649d6-0558-48f5-8437-161be8329159", - "kind": "Refinement", + "oa": "86aa4bf3-6543-4e81-929b-f0fc3482ff77", + "sa": "34f9ddb2-bb79-4658-8932-c8393b9f5022", + "kind": "Sequence", "baseline": { "oa": { - "name": "Report distress", + "name": "Distress to response", "description": "" }, "sa": { - "name": "Transmit distress report", + "name": "Digital distress handling", "description": "" } } diff --git a/harness/STATE.md b/harness/STATE.md index 34e656e1..b0fa2ef8 100644 --- a/harness/STATE.md +++ b/harness/STATE.md @@ -1,50 +1,55 @@ -# First release state — R4 authoring / native iteration / R5 integration +# First release state — hierarchy and port correction -## Objective and baseline -Active goal: feature-complete OA + SA/Architecture first release, beyond V2; objective attachment81e84f53-2b51-4151-9e34-59414bda8b2d. User demands closer original Capella study and practical usability. Later layers remain future work. V2 source ZIP and dist packages preserved; do not mark release complete. PLAN.md is current milestone/acceptance source. +## Objective and evidence -## Verified implementation -- R2 missions/capabilities, R1 process topology and R4 declared scenarios/message semantics implemented in shared core; exact handoffs release-capability-core.md, release-topology-core.md, release-scenarios-core.md. -- Fresh independent release-semantic-review.md findings CLOSED: branch-local duplicate replies/use-after-delete, Role compatibility, loop repetition diagnostics, reverse Reply picker and state-owner picker. Independent27 R1/R2/R4 tests + compiled external repro passed. Core worker71 focused regressions + strict Clippy passed before R5. Loop warnings distinguish uncertainty from execution claims. -- R1 contextual tools now work from empty and legacy Process/Chain; preserve legacy linear interpretation and perform explained atomic path conversion. Root added measured Fit/zoom and scaled hit testing after native excessive-scroll finding; empty process now has guidance. Latest source not native reverified yet. -- R4 dedicated scenario.rs authoring supports typed lifelines, all message styles, paired Call+Reply, explicit bound ScenarioUse, fragments/operand destinations/actions/state observations, carried values. Core helpers drive endpoint/viewpoint compatibility. Worker six scenario tests; root56 full desktop tests passed session50129 before source-find addition. -- Root R4 property forms include typed message/payload/reuse/binding fields and new constructors. Shared core reply/role helpers; distinct state-owner/effective-performer rule restored after review and tested. Modeling actions picklist near top of capability/mission properties; Connections inspector traverses real core references and diagram placements. -- Source lint runs bounded max1worker/latestversion, caches accepted model checks, rejects stale diagnostics across reset. Source navigation uses layout sensor; root further added focus, declaration context and literal Find/Go to line (CtrlF/CtrlG/F3/ShiftF3), UTF-8 byte cursor offsets, invalid-draft preservation. Latest59 desktop test run session22577 currently building after tests; inspect result before claiming complete. +Active first-release goal: complete OA + SA/System Architecture, Rust/Iced Windows/Linux, equivalent graphical/source editing, reST contract, traceability, REST and built-in guidance. Objective attachment81e84f53-2b51-4151-9e34-59414bda8b2d. V2 is the preserved baseline, not release acceptance. PLAN.md and release-semantics-audit.md retain the full scope. -## Current native verification -Root exclusively owns Computer Use. Sky persistent bindings sky/studioWindow/studioState/studioDialog/dialogState. Refresh inventory before next action. CUA through node_repl @oai/sky skill26.901.41600, not disabledcua_repl. Native file dialogs sometimes return tiny16px screenshot first; use screenshot width>100 for coordinates. One observed action then fresh capture; typing after focus observation. +User prioritizes Capella-like hierarchical architecture and correct ports. release-diagram-port-correction.md records the correction; release-port-contract.md is being finalized before implementation. No release completion claim. -Verified checkpoint executable: D:/CodexBuilds/Capella2-release1-01a06e2e/ui-r1-r4-checkpoint/arcadia-studio.exe SHA256B24611C9AA7BF686BDA3FDD0B25BB0CE71715D5FED471287ECBAE2B0BF385F98; window395472. This predates scenario authoring, topology zoom and Find. AltF4 requested after SaveAs, fresh inventory needed to confirm closure. stderr empty and process responsive during run. -- Native1440x900 and1100x700: guide/search, persistent task/explorer navigation; selected capability correctly identifies placement; Modeling actions menu appears near top. SourceForSelection now reveals correct declaration, but it lands near viewport bottom without focus; root further focus/context patch pending native verification. -- Help→resize→Open saved capability model now automatically fits47% with all nodes visible: original cache/layout Fit bug fixed and native reverified. -- Connections outgoing extension→target capability→incoming capability/chain relationships works. Right panel retains connection tab during creation, hiding name fields; root now switches new element to Properties and added EditProperties(id) message for explicit property actions. Pending native check. -- Created empty OA Process Choose rescue response, involved Assess incident through +Work, used Branch/parallel to create Report distress / Respond to distress alternatives after it, condition Incident needs more information + else. Observed5newSequenceLinks,4branchnodes, rendered guard/alternative routes. At minimum width excessively horizontal graph; root now adds Fit/zoom (not yet native checked). Branch form scroll works and commit is atomic via same Command path. -- Saved full result through native SaveAs to ui-r1-r4-checkpoint/process-branch-ui.arcadia. On-disk source verified process name, exact guard and5SequenceLinks. No original fixture overwritten. -- Earlier R2 native extension fixture ui-r2-checkpoint/capability-extension-ui.arcadia preserved: Rescue in heavy weather extends Protect life at sea, condition Sea state is 6 or higher; exact source verified. Prior app closed. -- Original Capella six native benchmark workflows recorded in release-capella-workflow-benchmark.md. Original window524804 disappeared from fresh inventory this turn; do not assume open. Disposable workspace/sample under D:/CodexBuilds/Capella2-release1-01a06e2e; preserve it. Reopen if more comparisons needed. +## Implemented and verified -## Active ownership -- Root: desktop app/forms/views/workflow/navigation/guide/source_navigation, topology.rs (released by worker after wrapper edits), state docs, exclusive CUA. Next: finish current59test/build result, copy new checkpoint, native Fit/zoom/sourceFind/scenarioauthoring/save-reopen; strict desktop Clippy. Root basicR5forms enums/refs/Event constructors already added; ergonomic state workflow still needed. -- release_capella_benchmark: ONLY behavior.rs + behavior/scenario.rs and benchmark docs. R4 authoring code complete, final focused checks/report then release. Root owns topology now. Shared behaviorEvent::is_submit guards both editors; root integrated. Event routing explicitly tags scenario commit so viewport events cannot redirect it. -- release_capability_core: R5 core model/validation/private state_validation.rs/references/session/transitions/projection/demo/coretests(exceptlanguage). Exact adopted contract release-state-contract.md: Event Signal/Time/Change, After/At, External/Local/Internal, typed trigger/effect refs,9newpseudostates, is_stable_state. Events/refs and state module compile; hierarchy/cardinality/focused tests underway. Source factory defaults preserved; Project::relate/Command::Connect use Local from EntryPoint. No desktop ownership. -- release_text_service_fix: language/persistence/tests/server/API/OpenAPI/language.rst. R5 source/API landed; previously16language+17HTTP/config+1unit passed, reST warning-free. Await core finalfreeze for final focused/strict checks; may read-only draft R3contract while waiting. R6 read-only report done: release-data-contract.md; not implemented. -- release_semantics_review: idle, focused review closed. Reuse after R5 / current graphical changes for fresh review. +- R1 explicit process/chain occurrences and guarded control topology; R2 missions/capabilities; R4 typed scenarios/messages/reuse; R5 state/event semantics, nested regions and pseudostates. Exact contracts/reviews are in the corresponding release-*.md reports. R1/R2/R4 independent semantic findings closed before this checkpoint. +- Desktop contextual scenario/state/process authoring; typed property adapter; searchable offline guide; asynchronous bounded source lint with stale-result rejection; UTF-8 Find/Go to line. State authoring tests pass, but R4/R5 complete native authoring acceptance remains pending. +- Architecture, functional-dataflow and capability projections separated. Demo now has six focused views. Shared projection preserves allocation/containment, calculates owner-bound selectable ports, and feeds canvas, Fit, SVG and movement. Generic port metamodel is still pending correction. +- Git initialized on codex/release1-engineering; source baseline commit93ba83d. No remote publication. User authorizes worktrees. Current post-review changes are uncommitted. +- Baseline full locked core/desktop/server tests passed (desktop64; server1unit+17HTTP); strict workspace Clippy passed at baseline. Post-review core4 projection regressions pass, including missing work-parent fallback and direct-versus-inferred allocation distinction. -## Required remaining work -R5 ergonomic state/event authoring/rendering plus finalcore/source verification; R6 data/contracts per design (lead still must freeze decisions); R3 fullsemantic drift and mapped existing-counterpart review; categories/persistentfilters/coverage; home/recent/recovery; optional hosteddesktop ETagopen/publish/save; explicit schema3 losslessV2migration; workedexamples and currentdocs; independent finalrequirements/correctness/UI/simplicity reviews; Windows/Linux fullchecks/nativeflows/packages. No V2 exclusion substitutes for release acceptance. +## Current changes and ownership -## Environment -Windows Rust1.98.1, target D:/CodexBuilds/Capella2-01a06e2e. Build cargo build --locked -p oa-desktop; tests cargo test --locked -p oa-desktop. Copy checkpoint exe before native launch so further builds can link. WSLUbuntu24.04 config per verification-v2-linux.md. Git unborn/untracked preserve. No disk blocker. Prior target/debug deletion rejected: do not retry/bypass. FinalMSRV/platform/clean-workflow checks remain. +- Root owns core projection/session/regressions, desktop views.rs, docs, integration and native CUA. Fixes: omitted work parent falls back to actual performer; port reveal unfolds owner ancestry; component-port footer and larger root corridors; inferred allocation summary metadata/inspector explanation. +- hierarchy_port_review owns ONLY desktop app.rs, diagram.rs, tests.rs for insertion/reflow fixes and canvas/SVG summary distinction. Earlier full desktop run67/68 failed: folding selects placement ID instead of semantic owner, causing subsequent child creation rejection. Worker fixes root cause and nested sibling reflow; do not claim current tests all pass. Other reviewed fixes: projected child drag preview, creation routing from capability views, unfolded insertion path, SVG labels/stereotypes. +- port_contract_design owns ONLY release-port-contract.md now; adopted design separates FunctionInput/Output item contracts, Component Standard/Flow and independent orientation, PortAllocation, required FE endpoint IDs, atomic generation/reuse and explicit lossless V2→3 migration. Isolated core implementation worktree follows contract freeze. +- capella_startup_diagnosis read-only complete: healthy original Capella pid14556/window1049956; redundant graphical splash pid7048/window395654 hung in native splash update. No deletion/config workaround indicated. -## Usage-limit interruption recovery -All three workers stopped with explicit account usage-limit errors; no worker is still active. Root owns recovery/integration of their current files. R5 core+server full locked tests passed in root session11632 (exit0). Worker left behavior.rs declaring states module without writing states.rs; root is completing that module before the next build. Native currentcheckpoint disappeared from process/window inventory without stderr output; root relaunched preserved ui-scenario-checkpoint executable, new returned window1050736. No unsaved native work was lost (last work was only reopening saved fixture). Root just verified Find/Enter/F3/CtrlG+line1 with actual selection and minimum1100x700layout; Fit/scenarioauthoring remain next native checks. +## Native verification and current pause -## User correction: diagram hierarchy and ports — current priority -User reports architecture diagrams have become generic graphs and port semantics/rendering differ dubiously from Capella. Lead confirmed projection includes almost every relation between placed objects, Overview flattens every parent, and renderer has no boundary-port anchors. Reopening original Capella to inspect SAB/SDFB/OAB ownership and port workflows before freezing corrective contract. Preserve completed state editor work; state native verification is pending, not release complete. Current desktop:59 prior full regressions +4 new state authoring tests pass, cargo check passes after recovery; strict Clippy/current full63 tests not yet run. New state_scene.rs gives actual nested geometry, internal transition rows and vector pseudostate symbols. No fresh agents available: three existing agents still errored on account usage limits; root continues. +Computer Use through node_repl @oai/sky, skill26.901.41600. Root exclusively owns input. Most recent attempt reported physical Escape stop before inventory; CUA paused, no further native input without user continuation. Code work can proceed. Existing persistent handles must be revalidated on resume. -## Git adoption and hierarchy checkpoint -User explicitly authorized Git and optional worktrees. Existing .git was unborn; created codex/release1-engineering, added repository ignore/line-ending rules, and preparing the first source checkpoint. Future isolated implementation can use worktrees after this commit; read-only reviews do not need them. Nothing pushed or published. +Studio checkpoint D:/CodexBuilds/Capella2-release1-01a06e2e/ui-hierarchy-checkpoint/arcadia-studio.exe, SHA256 D6055F659754E9159232483EAF9FA595C1D7F53683F8FB618D855F04B9C931A5, last window723086,1440×900. Personally exercised OA/SA layer changes, nested participants/work, auto function/component port appearance and function-output selection. Found label overlap; footer/corridor/alias fixes are newer than this executable and need native recheck. No unsaved edits in this checkpoint. -Hierarchy correction implementation: dedicated FunctionalDataflow/Capabilities projections, architecture filters participants/work + exchanges, six focused demo views with architecture preferred on open/layer change, calculated boundary ports referenced by FE/BoundaryExchange, shared movement/hit/SVG anchors. Layout measures port room and 64px headers, orders root containers by actual exchange flow. Source/OpenAPI enum support updated. Functional/component port metamodel correction remains required; do not mistake improved rendering for semantic completion. +Healthy original Capella has the disposable In-Flight Entertainment sample open. Root reached System Analysis workflow and expanded System Architecture diagrams; SAB port workflow not yet exercised. Previously observed six workflows are recorded in release-capella-workflow-benchmark.md. Root startup diagnosis now supersedes old unavailable-window notes. -Verification: full locked core+desktop+server tests exit0 root session12111; desktop64 tests, new3 core projection regressions and1 desktop port hit/preview/SVG test. Earlier new group-movement test incorrectly used projected origin as stored MoveNode target; corrected to command's absolute persisted-coordinate contract, and shared layout/header measurement now avoids the native offset mismatch. Strict workspace Clippy passed before projection changes; rerun needed on this checkpoint. Native checkpoint ui-hierarchy-checkpoint SHA256D6055F659754E9159232483EAF9FA595C1D7F53683F8FB618D855F04B9C931A5 built/copied; native launch/verification next. Capella graphical window395654 remains a splash, console launcher14556 unresponsive; no new native port study claimed. +Preserved actual native authoring fixtures: ui-r2-checkpoint/capability-extension-ui.arcadia (conditional extension); ui-r1-r4-checkpoint/process-branch-ui.arcadia (five control links and guarded alternatives), both under the release build directory. Find/Enter/F3/CtrlG and1100×700 layout previously exercised. New process Fit, scenario/state authoring, source focus refinements and latest diagram geometry still require native verification. + +## Exact next actions + +1. Finish nested insertion/reflow and summary display; run focused then full current tests/Clippy. Regenerate distributable examples with current focused diagrams, preserving historical V2 fixtures. Update docs and commit reviewed hierarchy milestone. +2. Freeze port contract and create isolated Git worktree for core/schema3 implementation. Root integrates typed desktop actions, forms, projection glyphs and API/source parity. Verify migration, deletion/undo, OA↔SA mapping and item/provider roles with independent review. +3. Resume native Capella SAB/port study and Studio default/minimum authoring verification when CUA is resumed; fix from observed evidence. +4. Continue remaining first-release requirements: R6 data, R3 semantic drift/mapped reconciliation, persistent filters/coverage, Home/recent/recovery, optional hosted ETag editing, updated examples/help/reST/API, independent final reviews, Windows/Linux checks and packages. + +## Environment and commands + +Windows Rust1.98.1, target D:/CodexBuilds/Capella2-01a06e2e. Set CARGO_TARGET_DIR to that path, then cargo test --locked -p oa-core -p oa-desktop -p oa-server; cargo clippy --locked --workspace --all-targets -- -D warnings; cargo build --locked -p oa-desktop. Copy build to a checkpoint path before native launch to avoid linker locks. WSLUbuntu24.04 setup in verification-v2-linux.md; final MSRV/platform verification remains. + +Prior recursive target/debug deletion was rejected: do not retry/bypass. No disk blocker. Old agents hit usage limits but current agents work; no usage reset authorized or used. Goal remains active; previous short turn stopped on explicit CUA Escape and made no material implementation progress. + +## Current integration checkpoint, 2026-09-05 + +User resumed CUA explicitly; it is working. Current original Capella window527162 maximized2560x1392. Root opened [SAB] High Level System Overview with some FCs, inspected function output port FOP5 properties (Outgoing Exchange Items, Realized Function Output Ports), created FunctionalExchange38 between Provide Navigation Data and Determine Operating Profiles by palette/source/target. It automatically created output FOP1 and input FIP3; Semantic Browser verifies ownership and actual endpoint identities. Allocation Management had no available component exchange; cancelled. Separate propagation/synchronization commands observed in Modeling Accelerators. Component-port creation/properties is next. + +Hierarchy worker released app.rs/diagram.rs/tests.rs after fixing semantic selection lost on folding, nested sibling/ancestor reflow including folded hidden descendants, and canvas/SVG inferred-summary distinction. Root full locked core+desktop+server tests session6598 passed (desktop70, server1unit+17HTTP); strict workspace Clippy and desktop build session38990 passed. Demo source/JSON regenerated from a single model with matching IDs and successful load checks; old V2 fixtures untouched. New maintained core example generate_demo provides reproducible regeneration. Guide and README reflect focused view names/summary semantics. + +Latest native checkpoint ready: D:/CodexBuilds/Capella2-release1-01a06e2e/ui-hierarchy-reviewed/arcadia-studio.exe SHA2563603AC957B6E16B4321F7FB7E759B3A2265357679DB8F27DD9ED5642B7E02179. Not launched yet. Old Studio window723086 has dirty marker, so inspect and preserve any unsaved changes before closing (do not infer it is safe from the earlier no-edit state). + +Typed-port work isolated at D:/CodexWorktrees/Capella2-typed-ports, branch codex/typed-port-contracts, from c20a207. port_contract_design owns core model/ports/validation/references/session/transitions/demo/projection + non-language tests; capella_startup_diagnosis now owns persistence/migration/language/server/API/reST + source/migration tests. They coordinate shared schema but never edit the same files. Root main remains buildable during their implementation. Temporary model-capacity errors were retried on the same agents; both resumed. Full core port/schema3 acceptance pending.