Record corrected navigation trial and alias transaction measurements
This commit is contained in:
+204
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"binarySha256": "bad169f8be78dcfa74b32714569c886dd2132727080684fc2ba618d5822e3559",
|
||||
"fixtureUnchanged": true,
|
||||
"trialFilesUnchanged": true,
|
||||
"files": {
|
||||
"evidence/repair-check.md": {
|
||||
"bytes": 1419,
|
||||
"sha256": "f4db17bdca4ecbb1bf0caef01b2da5f1f7f798ab3152b648ce6dd8696a6a68e5"
|
||||
},
|
||||
"expected-diagnostics.json": {
|
||||
"bytes": 288,
|
||||
"sha256": "3700393d76b940cfc076bf52861bd7b1f43370f8eabce3594531bd0bf1fc851e"
|
||||
},
|
||||
"model.json": {
|
||||
"bytes": 134520,
|
||||
"sha256": "ef0ef4006c3e09d5db6e1b621256b3f7d6642f3a7b09cc34607cfbcca830c727"
|
||||
},
|
||||
"model.rs": {
|
||||
"bytes": 28762,
|
||||
"sha256": "15f30f6bde655808fe754665c26d560e36f2a9bad340f346b09137d0d05045f5"
|
||||
},
|
||||
"oa/activities/activity_oa_restore_work.arcadia": {
|
||||
"bytes": 1307,
|
||||
"sha256": "83e73d0a013d5c3e1a4af0d9139ab0cfa362d25a846671fc2dac59181061a9d4"
|
||||
},
|
||||
"oa/behavior/process_oa_assessment_procedure.arcadia": {
|
||||
"bytes": 697,
|
||||
"sha256": "172c32c044ef4b5bc58a1f4635cc81f48dabb4014479b47dce7b25fedf2dbd0d"
|
||||
},
|
||||
"oa/behavior/process_oa_field_procedure.arcadia": {
|
||||
"bytes": 1781,
|
||||
"sha256": "d2552dc5383e2e91cb302a790364e197f663c2edc013a2ab1978789825c9c324"
|
||||
},
|
||||
"oa/behavior/process_oa_response.arcadia": {
|
||||
"bytes": 3225,
|
||||
"sha256": "cf86f46fa5c5d70592ef43f1bc1cb4d968efd8add384ba88036bef6b88aa4abc"
|
||||
},
|
||||
"oa/behavior/scenario_oa_conversation.arcadia": {
|
||||
"bytes": 1795,
|
||||
"sha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
|
||||
},
|
||||
"oa/behavior/scenario_oa_full_scenario.arcadia": {
|
||||
"bytes": 1261,
|
||||
"sha256": "00a1edf2c9707a0eb62ac070c2d02467874f2c9c1f273cc6ddb53d6d65999a1c"
|
||||
},
|
||||
"oa/behavior/state_machine_oa_monitor.arcadia": {
|
||||
"bytes": 2022,
|
||||
"sha256": "447c9ad1359f4a31ecf975ad07c0b08d8e7e03191fb0858e2fc56f377b223cd5"
|
||||
},
|
||||
"oa/capabilities.arcadia": {
|
||||
"bytes": 781,
|
||||
"sha256": "fc8012e5554350b12e1cb80080f8feab80d933c9b33c0f2a7bb500cb7d609936"
|
||||
},
|
||||
"oa/model.arcadia": {
|
||||
"bytes": 661,
|
||||
"sha256": "f7cf914766ea73ec53b85e32d117ea9a9dba52d3e038246863541ae7069b1a15"
|
||||
},
|
||||
"oa/participants.arcadia": {
|
||||
"bytes": 1834,
|
||||
"sha256": "951764c14179f27c10e315acf2ea37d1fff54c77b8441e23addd239e8c715ce3"
|
||||
},
|
||||
"oa/types.arcadia": {
|
||||
"bytes": 788,
|
||||
"sha256": "9d0396fb82dd5733edd8d1cf52f968ca84906927c704f9cf0944a7fae215cf49"
|
||||
},
|
||||
"project.arcadia": {
|
||||
"bytes": 1958,
|
||||
"sha256": "b2674e6bf77cfe0f6f0ba79c81d2e96d92f39c02ca2c6266d80e91723bfb9fda"
|
||||
},
|
||||
"README.md": {
|
||||
"bytes": 11137,
|
||||
"sha256": "113cfb1cf38a98b51bff60442d86a35d636a3d80ef206bece7d53d0aae67f2d5"
|
||||
},
|
||||
"sa/behavior/process_sa_assessment_procedure.arcadia": {
|
||||
"bytes": 706,
|
||||
"sha256": "73928ced61c06cbc08728d7956676a50fd4c05aa5b7f1ff4f29ce27a0b0f2088"
|
||||
},
|
||||
"sa/behavior/process_sa_field_procedure.arcadia": {
|
||||
"bytes": 1790,
|
||||
"sha256": "886d462af83110cbfa55dd232a667ea1446761234471357cbb878794e98e8768"
|
||||
},
|
||||
"sa/behavior/process_sa_response.arcadia": {
|
||||
"bytes": 3234,
|
||||
"sha256": "041785fc22842423822431bd5e6e8d16094ebd0716965e7c765fb8c1d7549e8a"
|
||||
},
|
||||
"sa/behavior/scenario_sa_conversation.arcadia": {
|
||||
"bytes": 2127,
|
||||
"sha256": "97276f5757ee9aa12a0dbd9d3ccd58174b3091162bb8bcce357cec20a45f5d85"
|
||||
},
|
||||
"sa/behavior/scenario_sa_full_scenario.arcadia": {
|
||||
"bytes": 1256,
|
||||
"sha256": "e12fc406b99d60a2f7768aaa0b25ba560e8605f0b8e37f3a7cdd3b8443562b74"
|
||||
},
|
||||
"sa/behavior/state_machine_sa_monitor.arcadia": {
|
||||
"bytes": 2022,
|
||||
"sha256": "05ce29af99424c491c47fe2450dc6f5f8ce995511c01ec7e17bb5855be3c9736"
|
||||
},
|
||||
"sa/capabilities.arcadia": {
|
||||
"bytes": 781,
|
||||
"sha256": "b6912fb3ece439912345fa71724acd462e716a1e5a88203a1058a5c3b2c20a4f"
|
||||
},
|
||||
"sa/functions/function_sa_audit_thresholds.arcadia": {
|
||||
"bytes": 297,
|
||||
"sha256": "e5a04325d52183956dca814dd90f4e56c96c6b7db0f4f202f203ecb49c3e0f4f"
|
||||
},
|
||||
"sa/functions/function_sa_restore_work.arcadia": {
|
||||
"bytes": 2576,
|
||||
"sha256": "fddeb67308051325041fee641fe758ddf43345b7c47b66d433616ad07fdccdd6"
|
||||
},
|
||||
"sa/model.arcadia": {
|
||||
"bytes": 661,
|
||||
"sha256": "d431509251acb859fbb98733b6d18add952495e10a78703fbe8f31e40bc083c4"
|
||||
},
|
||||
"sa/participants.arcadia": {
|
||||
"bytes": 4012,
|
||||
"sha256": "780d2eb08b217b67b55febb3d34846f727b8ee9018df6c5741748647e36b2ff8"
|
||||
},
|
||||
"sa/types.arcadia": {
|
||||
"bytes": 1227,
|
||||
"sha256": "101fc0fbd99f1101514aa7b6da4f8e535aae0bb94c9e2b9e7e6c151135b28660"
|
||||
},
|
||||
"traceability.arcadia": {
|
||||
"bytes": 29506,
|
||||
"sha256": "48a96f543456c9b5a5798fc795594e4119147fe45f11a6f109f141b7f514560f"
|
||||
},
|
||||
"transition-before.json": {
|
||||
"bytes": 35801,
|
||||
"sha256": "2253e6434f741687e22327c37d520ed15c043bc36025498650bc2366bb6a874d"
|
||||
},
|
||||
"transition-request.json": {
|
||||
"bytes": 4276,
|
||||
"sha256": "43b9a22e5f95ad3bc0ebd2478ead0e14406854abc989ae94ded9367b013d812a"
|
||||
},
|
||||
"views/diagram_oa_allocation_view.arcadia": {
|
||||
"bytes": 2176,
|
||||
"sha256": "dfc0eb61e0e2aa5bda45524571fbfa3494f44ce19696f3e15e07438074a07bc7"
|
||||
},
|
||||
"views/diagram_sa_allocation_view.arcadia": {
|
||||
"bytes": 2173,
|
||||
"sha256": "b78b43a26a82efb8fbd5374b09c329fa341f57b29f635d397b9ef8aede71d389"
|
||||
},
|
||||
"views/diagram_sa_capability_view.arcadia": {
|
||||
"bytes": 1620,
|
||||
"sha256": "75e8dc9fb30f25d6f8fd3c6b595593ab4f98958a25798f961e336e0fac557649"
|
||||
},
|
||||
"views/diagram_sa_service_view.arcadia": {
|
||||
"bytes": 2209,
|
||||
"sha256": "b08c84f3ea633e7c78dfdad3272f75415f6256cf3614b6d99bfd4f0269076c9b"
|
||||
},
|
||||
"views/diagram_sa_state_view.arcadia": {
|
||||
"bytes": 1931,
|
||||
"sha256": "5f42f4c605e57b817d8400ed21f2b14bfc4e1592aebe941ff113767504c2b869"
|
||||
}
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"label": "check",
|
||||
"startedAtUtc": "2026-09-11T19:09:18.070150+00:00",
|
||||
"command": [
|
||||
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\source-cli-20260911\\verified\\arcadia.exe",
|
||||
"check",
|
||||
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\source-alias-rename-preparation-20260911\\cli-preview\\model\\project.arcadia",
|
||||
"--json"
|
||||
],
|
||||
"exitCode": 0,
|
||||
"wallSeconds": 1.6030613000002631,
|
||||
"status": "checked",
|
||||
"stdoutSha256": "0c7fe8010119fd9e52eda190dead17d60a504a7fd63591072ac907d27a133620"
|
||||
},
|
||||
{
|
||||
"label": "rename-preview-1",
|
||||
"startedAtUtc": "2026-09-11T19:09:19.803111+00:00",
|
||||
"command": [
|
||||
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\source-cli-20260911\\verified\\arcadia.exe",
|
||||
"rename-alias",
|
||||
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\source-alias-rename-preparation-20260911\\cli-preview\\model\\project.arcadia",
|
||||
"oa_restore_work",
|
||||
"oa_restore_pressure",
|
||||
"--json"
|
||||
],
|
||||
"exitCode": 0,
|
||||
"wallSeconds": 2.1857801000005566,
|
||||
"status": "preview",
|
||||
"stdoutSha256": "aab9347187e1d2e630f9500015071e7b0dc8940b488199f8dcb8eb03c07f44e5"
|
||||
},
|
||||
{
|
||||
"label": "rename-preview-2",
|
||||
"startedAtUtc": "2026-09-11T19:09:22.054451+00:00",
|
||||
"command": [
|
||||
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\source-cli-20260911\\verified\\arcadia.exe",
|
||||
"rename-alias",
|
||||
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\source-alias-rename-preparation-20260911\\cli-preview\\model\\project.arcadia",
|
||||
"oa_restore_work",
|
||||
"oa_restore_pressure",
|
||||
"--json"
|
||||
],
|
||||
"exitCode": 0,
|
||||
"wallSeconds": 2.188615999999456,
|
||||
"status": "preview",
|
||||
"stdoutSha256": "aab9347187e1d2e630f9500015071e7b0dc8940b488199f8dcb8eb03c07f44e5"
|
||||
}
|
||||
],
|
||||
"scope": "Existing debug CLI process startup, disk load, validation, rename preparation and JSON preview. Not current Document/UI latency, accepted-snapshot preview, or native acceptance."
|
||||
}
|
||||
+47
File diff suppressed because one or more lines are too long
+822
@@ -0,0 +1,822 @@
|
||||
//! Accepted graphical and source state, committed and restored together.
|
||||
//! Editor drafts and filesystem receipts belong to their respective adapters.
|
||||
use oa_core::{
|
||||
Command, Id, ModelError, Project, language, prepare_command,
|
||||
source_project::{self, CompiledSourceProject, ProjectLimits, SourceBundle, SourceDiagnostic},
|
||||
validation::Severity,
|
||||
};
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
const HISTORY_LIMIT: usize = 100;
|
||||
const HISTORY_BYTES: usize = 32 * 1024 * 1024;
|
||||
|
||||
struct HistoryEntry {
|
||||
snapshot: Arc<CompiledSourceProject>,
|
||||
bytes: usize,
|
||||
}
|
||||
|
||||
struct RelocatedHistory {
|
||||
current: Arc<CompiledSourceProject>,
|
||||
past: Vec<HistoryEntry>,
|
||||
future: Vec<HistoryEntry>,
|
||||
}
|
||||
|
||||
fn estimated_bytes(compiled: &CompiledSourceProject) -> usize {
|
||||
compiled
|
||||
.bundle
|
||||
.files
|
||||
.values()
|
||||
.fold(0usize, |sum, text| sum.saturating_add(text.len()))
|
||||
.saturating_add(
|
||||
serde_json::to_vec(&compiled.decoded.project).map_or(usize::MAX, |bytes| bytes.len()),
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DocumentError {
|
||||
Model(ModelError),
|
||||
Source(Vec<SourceDiagnostic>),
|
||||
}
|
||||
|
||||
impl DocumentError {
|
||||
pub fn diagnostics(&self) -> &[SourceDiagnostic] {
|
||||
match self {
|
||||
Self::Model(_) => &[],
|
||||
Self::Source(diagnostics) => diagnostics,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DocumentError {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Model(error) => error.fmt(formatter),
|
||||
Self::Source(diagnostics) => {
|
||||
if let Some(first) = diagnostics.first() {
|
||||
write!(
|
||||
formatter,
|
||||
"{}:{}:{}: {}",
|
||||
first.path,
|
||||
first.diagnostic.line,
|
||||
first.diagnostic.column,
|
||||
first.diagnostic.message
|
||||
)
|
||||
} else {
|
||||
formatter.write_str("Source validation failed.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for DocumentError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
Self::Model(error) => Some(error),
|
||||
Self::Source(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ModelError> for DocumentError {
|
||||
fn from(error: ModelError) -> Self {
|
||||
Self::Model(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<SourceDiagnostic>> for DocumentError {
|
||||
fn from(diagnostics: Vec<SourceDiagnostic>) -> Self {
|
||||
Self::Source(diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Document {
|
||||
current: Arc<CompiledSourceProject>,
|
||||
past: Vec<HistoryEntry>,
|
||||
future: Vec<HistoryEntry>,
|
||||
current_bytes: usize,
|
||||
saved: Arc<SourceBundle>,
|
||||
revision: u64,
|
||||
view_index: std::cell::OnceCell<oa_core::view_options::ViewIndex>,
|
||||
limits: ProjectLimits,
|
||||
recovered_unsaved: bool,
|
||||
}
|
||||
|
||||
impl Document {
|
||||
/// A valid generated workspace starts clean, like a new semantic Session.
|
||||
pub fn from_project(project: Project, limits: ProjectLimits) -> Result<Self, DocumentError> {
|
||||
oa_core::validate_candidate(&project)?;
|
||||
let document = Self::from_bundle(source_project::format_bundle(&project), limits)?;
|
||||
if document.project() != &project {
|
||||
return Err(DocumentError::Model(ModelError(
|
||||
"Generated source does not reproduce the supplied project.".into(),
|
||||
)));
|
||||
}
|
||||
Ok(document)
|
||||
}
|
||||
|
||||
/// Retain the exact input as the saved baseline. If compilation inserts
|
||||
/// missing IDs, those accepted source changes still need saving.
|
||||
pub fn from_bundle(bundle: SourceBundle, limits: ProjectLimits) -> Result<Self, DocumentError> {
|
||||
let current = Arc::new(source_project::compile_bundle(&bundle, limits)?);
|
||||
let current_bytes = estimated_bytes(¤t);
|
||||
Ok(Self {
|
||||
current,
|
||||
current_bytes,
|
||||
past: Vec::new(),
|
||||
future: Vec::new(),
|
||||
saved: Arc::new(bundle),
|
||||
revision: 0,
|
||||
view_index: Default::default(),
|
||||
limits,
|
||||
recovered_unsaved: false,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn project(&self) -> &Project {
|
||||
&self.current.decoded.project
|
||||
}
|
||||
|
||||
/// Semantic reachability is shared by every diagram at this accepted revision.
|
||||
pub fn view_index(&self) -> &oa_core::view_options::ViewIndex {
|
||||
self.view_index
|
||||
.get_or_init(|| oa_core::view_options::ViewIndex::new(self.project()))
|
||||
}
|
||||
|
||||
pub fn bundle(&self) -> &SourceBundle {
|
||||
&self.current.bundle
|
||||
}
|
||||
|
||||
pub fn compiled(&self) -> &CompiledSourceProject {
|
||||
&self.current
|
||||
}
|
||||
|
||||
pub fn revision(&self) -> u64 {
|
||||
self.revision
|
||||
}
|
||||
|
||||
pub fn dirty(&self) -> bool {
|
||||
self.recovered_unsaved || self.bundle() != self.saved.as_ref()
|
||||
}
|
||||
|
||||
/// Recovered work is a detached copy until explicitly saved by its user.
|
||||
pub fn mark_recovered(&mut self) {
|
||||
self.recovered_unsaved = true;
|
||||
}
|
||||
|
||||
pub fn can_undo(&self) -> bool {
|
||||
!self.past.is_empty()
|
||||
}
|
||||
|
||||
pub fn can_redo(&self) -> bool {
|
||||
!self.future.is_empty()
|
||||
}
|
||||
|
||||
/// Capture this before asynchronous saving. Completion must return the same
|
||||
/// snapshot, rather than marking whatever is current at completion as saved.
|
||||
pub fn snapshot(&self) -> Arc<CompiledSourceProject> {
|
||||
self.current.clone()
|
||||
}
|
||||
|
||||
/// Records the bytes actually saved, even when later edits remain current.
|
||||
/// The I/O adapter owns document identity and save completion ordering.
|
||||
pub fn mark_saved(&mut self, snapshot: Arc<CompiledSourceProject>) {
|
||||
self.saved = Arc::new(snapshot.bundle.clone());
|
||||
self.recovered_unsaved = false;
|
||||
}
|
||||
|
||||
/// Check a source Save as before writing any files. A retained included file
|
||||
/// must never be displaced by the new entry, including on a later Undo.
|
||||
pub fn check_save_entry(&self, entry: &str) -> Result<(), DocumentError> {
|
||||
if entry == self.bundle().entry {
|
||||
return Ok(());
|
||||
}
|
||||
self.relocated_history(entry).map(|_| ())
|
||||
}
|
||||
|
||||
/// Adopt a successfully saved source entry without recording an engineering
|
||||
/// edit or clearing Redo. The caller still marks the exact receipt as saved.
|
||||
pub fn adopt_saved_entry(
|
||||
&mut self,
|
||||
saved: &CompiledSourceProject,
|
||||
revision: u64,
|
||||
) -> Result<(), DocumentError> {
|
||||
if revision != self.revision {
|
||||
return Err(
|
||||
ModelError("Newer edits retain the current source location.".into()).into(),
|
||||
);
|
||||
}
|
||||
let RelocatedHistory {
|
||||
current,
|
||||
past,
|
||||
future,
|
||||
} = self.relocated_history(&saved.bundle.entry)?;
|
||||
if current.bundle != saved.bundle
|
||||
|| current.decoded.project != saved.decoded.project
|
||||
|| current.index != saved.index
|
||||
{
|
||||
return Err(ModelError(
|
||||
"The save receipt changes more than the source entry location.".into(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
if current.bundle != self.current.bundle {
|
||||
self.current_bytes = estimated_bytes(¤t);
|
||||
self.current = current;
|
||||
self.past = past;
|
||||
self.future = future;
|
||||
// Source-position readers must reject their old revision even though
|
||||
// changing the save location does not create an Undo transaction.
|
||||
self.revision = self.revision.saturating_add(1);
|
||||
self.view_index.take();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn relocated_history(&self, entry: &str) -> Result<RelocatedHistory, DocumentError> {
|
||||
if entry.contains('/') || source_project::resolve_include("", entry).as_deref() != Ok(entry)
|
||||
{
|
||||
return Err(ModelError("Choose a portable .arcadia entry file name.".into()).into());
|
||||
}
|
||||
let snapshots = std::iter::once(self.current.as_ref())
|
||||
.chain(self.past.iter().map(|h| h.snapshot.as_ref()))
|
||||
.chain(self.future.iter().map(|h| h.snapshot.as_ref()));
|
||||
let mut uniform_entry = true;
|
||||
for snapshot in snapshots {
|
||||
uniform_entry &= snapshot.bundle.entry == self.bundle().entry;
|
||||
if snapshot.bundle.files.keys().any(|path| {
|
||||
path != &snapshot.bundle.entry && path.to_lowercase() == entry.to_lowercase()
|
||||
}) {
|
||||
return Err(ModelError(format!(
|
||||
"The entry name '{entry}' is used by an included file in this document or its Undo/Redo history. Choose another entry name."
|
||||
)).into());
|
||||
}
|
||||
}
|
||||
let relocate = |snapshot: &Arc<CompiledSourceProject>| -> Result<Arc<CompiledSourceProject>, DocumentError> {
|
||||
if snapshot.bundle.entry == entry {
|
||||
return Ok(snapshot.clone());
|
||||
}
|
||||
let mut bundle = snapshot.bundle.clone();
|
||||
let text = bundle
|
||||
.files
|
||||
.remove(&bundle.entry)
|
||||
.ok_or_else(|| ModelError("The accepted source entry is missing.".into()))?;
|
||||
bundle.entry = entry.to_owned();
|
||||
bundle.files.insert(entry.to_owned(), text);
|
||||
let compiled = source_project::compile_bundle(&bundle, self.limits)?;
|
||||
if compiled.bundle != bundle || compiled.decoded.project != snapshot.decoded.project {
|
||||
return Err(ModelError(
|
||||
"Changing the entry location would change the model or authored source.".into(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
Ok(Arc::new(compiled))
|
||||
};
|
||||
let current = relocate(&self.current)?;
|
||||
let history = |entries: &[HistoryEntry]| {
|
||||
entries
|
||||
.iter()
|
||||
.map(|old| {
|
||||
// Different entry names in history are authored source changes.
|
||||
// Keep those snapshots exact instead of collapsing real edits.
|
||||
let snapshot = if uniform_entry {
|
||||
relocate(&old.snapshot)?
|
||||
} else {
|
||||
old.snapshot.clone()
|
||||
};
|
||||
Ok(HistoryEntry {
|
||||
bytes: estimated_bytes(&snapshot),
|
||||
snapshot,
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, DocumentError>>()
|
||||
};
|
||||
Ok(RelocatedHistory {
|
||||
current,
|
||||
past: history(&self.past)?,
|
||||
future: history(&self.future)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn execute(&mut self, command: Command) -> Result<Option<Id>, DocumentError> {
|
||||
let candidate = prepare_command(self.project(), &command)?;
|
||||
// Equal model values can still carry different record provenance, such
|
||||
// as deleting and recreating an identical record with a reused UUID.
|
||||
// Only the resulting model/source pair determines whether this is a no-op.
|
||||
let compiled = source_project::update_bundle_with_identity_map(
|
||||
&self.current,
|
||||
&candidate.project,
|
||||
&candidate.identity_map,
|
||||
self.limits,
|
||||
)?;
|
||||
self.commit(compiled);
|
||||
Ok(candidate.selected)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn apply_bundle(&mut self, bundle: SourceBundle) -> Result<bool, DocumentError> {
|
||||
let compiled = source_project::compile_bundle(&bundle, self.limits)?;
|
||||
Ok(self.commit(compiled))
|
||||
}
|
||||
|
||||
/// Public compiled fields are convenient data, not a validation capability.
|
||||
/// Rebuild diagnostics/index and reject a stale or altered model/index pair.
|
||||
pub fn apply_compiled(
|
||||
&mut self,
|
||||
compiled: CompiledSourceProject,
|
||||
) -> Result<bool, DocumentError> {
|
||||
let checked = source_project::compile_bundle(&compiled.bundle, self.limits)?;
|
||||
if checked.bundle != compiled.bundle
|
||||
|| checked.decoded.project != compiled.decoded.project
|
||||
|| checked.index != compiled.index
|
||||
{
|
||||
return Err(DocumentError::Source(vec![SourceDiagnostic {
|
||||
path: compiled.bundle.entry,
|
||||
diagnostic: language::Diagnostic {
|
||||
severity: Severity::Error,
|
||||
code: "stale_source_index".into(),
|
||||
object_id: None,
|
||||
field: None,
|
||||
line: 1,
|
||||
column: 1,
|
||||
message: "Compile the current documents before applying this source snapshot."
|
||||
.into(),
|
||||
span: language::Span::default(),
|
||||
},
|
||||
related: Vec::new(),
|
||||
}]));
|
||||
}
|
||||
Ok(self.commit(checked))
|
||||
}
|
||||
|
||||
pub fn undo(&mut self) -> bool {
|
||||
let Some(previous) = self.past.pop() else {
|
||||
return false;
|
||||
};
|
||||
self.future.push(HistoryEntry {
|
||||
snapshot: std::mem::replace(&mut self.current, previous.snapshot),
|
||||
bytes: std::mem::replace(&mut self.current_bytes, previous.bytes),
|
||||
});
|
||||
self.revision = self.revision.saturating_add(1);
|
||||
self.view_index.take();
|
||||
true
|
||||
}
|
||||
|
||||
pub fn redo(&mut self) -> bool {
|
||||
let Some(next) = self.future.pop() else {
|
||||
return false;
|
||||
};
|
||||
self.past.push(HistoryEntry {
|
||||
snapshot: std::mem::replace(&mut self.current, next.snapshot),
|
||||
bytes: std::mem::replace(&mut self.current_bytes, next.bytes),
|
||||
});
|
||||
self.revision = self.revision.saturating_add(1);
|
||||
self.view_index.take();
|
||||
true
|
||||
}
|
||||
|
||||
fn commit(&mut self, compiled: CompiledSourceProject) -> bool {
|
||||
if compiled.bundle == self.current.bundle {
|
||||
return false;
|
||||
}
|
||||
let bytes = estimated_bytes(&compiled);
|
||||
self.past.push(HistoryEntry {
|
||||
snapshot: std::mem::replace(&mut self.current, Arc::new(compiled)),
|
||||
bytes: std::mem::replace(&mut self.current_bytes, bytes),
|
||||
});
|
||||
self.future.clear();
|
||||
let mut retained = self.past.iter().fold(self.current_bytes, |sum, entry| {
|
||||
sum.saturating_add(entry.bytes)
|
||||
});
|
||||
while !self.past.is_empty() && (self.past.len() > HISTORY_LIMIT || retained > HISTORY_BYTES)
|
||||
{
|
||||
retained = retained.saturating_sub(self.past.remove(0).bytes);
|
||||
}
|
||||
self.revision = self.revision.saturating_add(1);
|
||||
self.view_index.take();
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "document_save_as_tests.rs"]
|
||||
mod save_as_tests;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use oa_core::{Kind, Layer};
|
||||
|
||||
fn document() -> Document {
|
||||
Document::from_project(Project::empty(), ProjectLimits::default()).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cached_view_index_tracks_accepted_creation_undo_and_redo() {
|
||||
use oa_core::{Relation, RelationBody, RelationKind, view_options::ViewOptions};
|
||||
let mut p = Project::empty();
|
||||
let source = p
|
||||
.add_element(Kind::Entity, Layer::Oa, "Team", None)
|
||||
.unwrap();
|
||||
let target = p
|
||||
.add_element(Kind::Actor, Layer::Oa, "Dispatcher", None)
|
||||
.unwrap();
|
||||
let mut document = Document::from_project(p, ProjectLimits::default()).unwrap();
|
||||
let id = Id::new_v4();
|
||||
let options = ViewOptions::default();
|
||||
let visible = |d: &Document| d.view_index().prepare(Layer::Oa, &options).includes(id);
|
||||
assert!(!visible(&document));
|
||||
document
|
||||
.execute(Command::CreateRelation(Relation {
|
||||
id,
|
||||
alias: "radio".into(),
|
||||
name: "Radio".into(),
|
||||
description: String::new(),
|
||||
body: RelationBody::new(RelationKind::CommunicationMean, source, target),
|
||||
}))
|
||||
.unwrap();
|
||||
assert!(visible(&document));
|
||||
assert!(document.undo());
|
||||
assert!(!visible(&document));
|
||||
assert!(document.redo());
|
||||
assert!(visible(&document));
|
||||
}
|
||||
|
||||
fn comment(bundle: &SourceBundle, text: &str) -> SourceBundle {
|
||||
let mut changed = bundle.clone();
|
||||
changed
|
||||
.files
|
||||
.get_mut(&changed.entry)
|
||||
.unwrap()
|
||||
.push_str(text);
|
||||
changed
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creation_selects_the_single_uuid_persisted_in_source() {
|
||||
let mut document = document();
|
||||
let id = document
|
||||
.execute(Command::AddElement {
|
||||
kind: Kind::Activity,
|
||||
layer: Layer::Oa,
|
||||
name: "Assess incident".into(),
|
||||
parent: None,
|
||||
})
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(document.project().elements.len(), 1);
|
||||
assert_eq!(document.project().elements[&id].name, "Assess incident");
|
||||
let location = &document.compiled().index.declarations[&id];
|
||||
let declaration =
|
||||
&document.bundle().files[&location.path][location.span.start..location.span.end];
|
||||
assert!(declaration.contains(&id.to_string()));
|
||||
let reopened =
|
||||
source_project::compile_bundle(document.bundle(), ProjectLimits::default()).unwrap();
|
||||
assert_eq!(reopened.decoded.project, *document.project());
|
||||
assert_eq!(document.revision(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejected_compile_command_and_writeback_preserve_state_and_redo() {
|
||||
let bundle = source_project::format_bundle(&Project::empty());
|
||||
let bytes = bundle.files.values().map(String::len).sum::<usize>();
|
||||
let mut limits = ProjectLimits::default();
|
||||
limits.model.max_source_bytes = bytes + 100;
|
||||
let mut document = Document::from_bundle(bundle, limits).unwrap();
|
||||
document
|
||||
.apply_bundle(comment(document.bundle(), "// preserved future\n"))
|
||||
.unwrap();
|
||||
assert!(document.undo());
|
||||
let before = document.snapshot();
|
||||
let revision = document.revision();
|
||||
let history = (document.past.len(), document.future.len());
|
||||
|
||||
let malformed = comment(document.bundle(), "?");
|
||||
assert!(document.apply_bundle(malformed).is_err());
|
||||
assert!(document.execute(Command::Delete(Id::new_v4())).is_err());
|
||||
let error = document
|
||||
.execute(Command::Rename(document.project().id, "x".repeat(200)))
|
||||
.unwrap_err();
|
||||
assert!(!error.diagnostics().is_empty());
|
||||
assert!(error.to_string().contains(&document.bundle().entry));
|
||||
assert!(Arc::ptr_eq(&before, &document.snapshot()));
|
||||
assert_eq!(document.revision(), revision);
|
||||
assert_eq!((document.past.len(), document.future.len()), history);
|
||||
assert!(!document.dirty());
|
||||
assert!(document.redo());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn comment_and_semantic_history_restore_exact_bytes_and_branch_together() {
|
||||
let mut document = document();
|
||||
let initial = document.snapshot();
|
||||
let annotated = comment(
|
||||
document.bundle(),
|
||||
"\r\n// Project rationale: preserve me.\r\n",
|
||||
);
|
||||
assert!(document.apply_bundle(annotated.clone()).unwrap());
|
||||
assert_eq!(document.project(), &initial.decoded.project);
|
||||
assert_eq!(document.revision(), 1);
|
||||
document
|
||||
.execute(Command::Rename(
|
||||
document.project().id,
|
||||
"Rescue workspace".into(),
|
||||
))
|
||||
.unwrap();
|
||||
let renamed = document.snapshot();
|
||||
assert!(document.undo());
|
||||
assert_eq!(document.bundle(), &annotated);
|
||||
assert!(document.undo());
|
||||
assert_eq!(document.bundle(), &initial.bundle);
|
||||
assert!(!document.dirty());
|
||||
assert!(document.redo());
|
||||
assert_eq!(document.bundle(), &annotated);
|
||||
assert!(document.redo());
|
||||
assert_eq!(document.bundle(), &renamed.bundle);
|
||||
assert!(document.undo());
|
||||
let branch = comment(document.bundle(), "// A different source-only decision.\n");
|
||||
assert!(document.apply_bundle(branch.clone()).unwrap());
|
||||
assert!(!document.can_redo());
|
||||
assert_eq!(document.project(), &initial.decoded.project);
|
||||
assert!(document.undo());
|
||||
assert_eq!(document.bundle(), &annotated);
|
||||
assert!(document.redo());
|
||||
assert_eq!(document.bundle(), &branch);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_cross_file_reparent_and_source_edit_share_exact_history() {
|
||||
let bundle = SourceBundle {
|
||||
entry: "project.arcadia".into(),
|
||||
files: [
|
||||
(
|
||||
"project.arcadia".into(),
|
||||
"arcadia 3; project rescue \"Rescue\" { include \"oa/source.arcadia\"; include \"oa/target.arcadia\"; }\n".into(),
|
||||
),
|
||||
(
|
||||
"oa/source.arcadia".into(),
|
||||
"// Source module\r\noa_activity respond \"Respond\" {\r\n // Assessment rationale follows this activity.\r\n oa_activity assess \"Assess\" {}\r\n}\r\n".into(),
|
||||
),
|
||||
(
|
||||
"oa/target.arcadia".into(),
|
||||
"// Destination module\noa_activity coordinate \"Coordinate\" {}\n".into(),
|
||||
),
|
||||
].into(),
|
||||
};
|
||||
let mut document = Document::from_bundle(bundle, ProjectLimits::default()).unwrap();
|
||||
document.mark_saved(document.snapshot());
|
||||
let original = document.snapshot();
|
||||
let id = |alias: &str| {
|
||||
original
|
||||
.decoded
|
||||
.project
|
||||
.elements
|
||||
.values()
|
||||
.find(|element| element.alias == alias)
|
||||
.unwrap()
|
||||
.id
|
||||
};
|
||||
let child = id("assess");
|
||||
let destination = id("coordinate");
|
||||
document
|
||||
.execute(Command::Reparent {
|
||||
element: child,
|
||||
parent: Some(destination),
|
||||
})
|
||||
.unwrap();
|
||||
let moved = document.snapshot();
|
||||
assert_eq!(
|
||||
document.project().elements[&child].parent,
|
||||
Some(destination)
|
||||
);
|
||||
assert_eq!(
|
||||
document.compiled().index.declarations[&child].path,
|
||||
"oa/target.arcadia"
|
||||
);
|
||||
assert!(
|
||||
document.bundle().files["oa/target.arcadia"]
|
||||
.contains("// Assessment rationale follows this activity.")
|
||||
);
|
||||
assert!(
|
||||
!document.bundle().files["oa/source.arcadia"]
|
||||
.contains("// Assessment rationale follows this activity.")
|
||||
);
|
||||
let edited = comment(document.bundle(), "// Reviewed containment decision.\n");
|
||||
assert!(document.apply_bundle(edited.clone()).unwrap());
|
||||
assert_eq!(document.project(), &moved.decoded.project);
|
||||
assert!(document.undo());
|
||||
assert_eq!(document.bundle(), &moved.bundle);
|
||||
assert!(document.undo());
|
||||
assert_eq!(document.bundle(), &original.bundle);
|
||||
assert_eq!(document.project(), &original.decoded.project);
|
||||
assert!(!document.dirty());
|
||||
assert!(document.redo());
|
||||
assert_eq!(document.bundle(), &moved.bundle);
|
||||
assert!(document.redo());
|
||||
assert_eq!(document.bundle(), &edited);
|
||||
let accepted = document.snapshot();
|
||||
let invalid = comment(document.bundle(), "invalid_declaration;");
|
||||
assert!(document.apply_bundle(invalid).is_err());
|
||||
assert!(Arc::ptr_eq(&accepted, &document.snapshot()));
|
||||
let reopened =
|
||||
Document::from_bundle(document.bundle().clone(), ProjectLimits::default()).unwrap();
|
||||
assert_eq!(reopened.project(), document.project());
|
||||
assert_eq!(reopened.bundle(), document.bundle());
|
||||
assert!(!reopened.dirty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recreated_equal_record_does_not_inherit_deleted_source_ownership() {
|
||||
let bundle = SourceBundle {
|
||||
entry: "project.arcadia".into(),
|
||||
files: [
|
||||
(
|
||||
"project.arcadia".into(),
|
||||
"arcadia 3; project rescue \"Rescue\" { include \"authored.arcadia\"; }\n"
|
||||
.into(),
|
||||
),
|
||||
(
|
||||
"authored.arcadia".into(),
|
||||
"// Rationale for the original record.\noa_activity assess \"Assess\" {}\n"
|
||||
.into(),
|
||||
),
|
||||
]
|
||||
.into(),
|
||||
};
|
||||
let mut document = Document::from_bundle(bundle, ProjectLimits::default()).unwrap();
|
||||
document.mark_saved(document.snapshot());
|
||||
let before = document.snapshot();
|
||||
let element = document.project().elements.values().next().unwrap().clone();
|
||||
let id = element.id;
|
||||
document
|
||||
.execute(Command::Batch(vec![
|
||||
Command::Delete(id),
|
||||
Command::CreateElement(element),
|
||||
]))
|
||||
.unwrap();
|
||||
assert_eq!(document.project(), &before.decoded.project);
|
||||
assert_ne!(
|
||||
document.compiled().index.declarations[&id].path,
|
||||
"authored.arcadia"
|
||||
);
|
||||
assert!(
|
||||
document.bundle().files["authored.arcadia"]
|
||||
.contains("// Rationale for the original record.")
|
||||
);
|
||||
assert!(!document.bundle().files["authored.arcadia"].contains("oa_activity"));
|
||||
assert!(document.dirty());
|
||||
assert_eq!(document.revision(), 1);
|
||||
let recreated = document.snapshot();
|
||||
assert!(document.undo());
|
||||
assert_eq!(document.bundle(), &before.bundle);
|
||||
assert!(!document.dirty());
|
||||
assert!(document.redo());
|
||||
assert_eq!(document.bundle(), &recreated.bundle);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn asynchronous_save_marks_its_snapshot_without_cleaning_later_edits() {
|
||||
let mut document = document();
|
||||
document
|
||||
.apply_bundle(comment(document.bundle(), "// Saved rationale.\n"))
|
||||
.unwrap();
|
||||
let saving = document.snapshot();
|
||||
document
|
||||
.apply_bundle(comment(document.bundle(), "// Later unsaved rationale.\n"))
|
||||
.unwrap();
|
||||
document.mark_saved(saving);
|
||||
assert!(document.dirty());
|
||||
assert!(document.undo());
|
||||
assert!(!document.dirty());
|
||||
assert!(document.redo());
|
||||
assert!(document.dirty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_op_command_or_source_apply_preserves_history_revision_and_redo() {
|
||||
let mut document = document();
|
||||
assert!(!document.undo());
|
||||
assert!(!document.redo());
|
||||
document
|
||||
.apply_bundle(comment(document.bundle(), "// Future edit.\n"))
|
||||
.unwrap();
|
||||
assert!(document.undo());
|
||||
let before = document.snapshot();
|
||||
let revision = document.revision();
|
||||
document
|
||||
.execute(Command::Rename(
|
||||
document.project().id,
|
||||
document.project().name.clone(),
|
||||
))
|
||||
.unwrap();
|
||||
assert!(!document.apply_bundle(document.bundle().clone()).unwrap());
|
||||
assert!(
|
||||
!document
|
||||
.apply_compiled(document.compiled().clone())
|
||||
.unwrap()
|
||||
);
|
||||
assert!(Arc::ptr_eq(&before, &document.snapshot()));
|
||||
assert_eq!(document.revision(), revision);
|
||||
assert!(document.can_redo());
|
||||
assert!(!document.can_undo());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn altered_compiled_model_or_index_is_rejected_without_mutation() {
|
||||
let mut document = document();
|
||||
let before = document.snapshot();
|
||||
let mut forged = document.compiled().clone();
|
||||
forged.decoded.project.name = "Not in the source".into();
|
||||
assert!(document.apply_compiled(forged).is_err());
|
||||
let mut forged = document.compiled().clone();
|
||||
forged.index.declarations.clear();
|
||||
let error = document.apply_compiled(forged).unwrap_err();
|
||||
assert_eq!(error.diagnostics()[0].diagnostic.code, "stale_source_index");
|
||||
assert!(Arc::ptr_eq(&before, &document.snapshot()));
|
||||
assert_eq!(document.revision(), 0);
|
||||
assert!(!document.can_undo());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn omitted_id_stabilization_remains_dirty_until_exact_source_is_saved() {
|
||||
let bundle = SourceBundle {
|
||||
entry: "project.arcadia".into(),
|
||||
files: [(
|
||||
"project.arcadia".into(),
|
||||
"arcadia 3; project rescue \"Rescue\" {}\n".into(),
|
||||
)]
|
||||
.into(),
|
||||
};
|
||||
let mut document = Document::from_bundle(bundle.clone(), ProjectLimits::default()).unwrap();
|
||||
assert!(document.dirty());
|
||||
assert_ne!(document.bundle(), &bundle);
|
||||
let id = document.project().id;
|
||||
assert!(!document.apply_bundle(document.bundle().clone()).unwrap());
|
||||
assert_eq!(document.project().id, id);
|
||||
document.mark_saved(document.snapshot());
|
||||
assert!(!document.dirty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepted_history_keeps_the_latest_hundred_complete_snapshots() {
|
||||
let mut document = document();
|
||||
for change in 0..105 {
|
||||
document
|
||||
.apply_bundle(comment(
|
||||
document.bundle(),
|
||||
&format!("// Change {change}.\n"),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
assert_eq!(document.past.len(), HISTORY_LIMIT);
|
||||
let mut undone = 0;
|
||||
while document.undo() {
|
||||
undone += 1;
|
||||
}
|
||||
assert_eq!(undone, HISTORY_LIMIT);
|
||||
assert_eq!(
|
||||
document.bundle().files[&document.bundle().entry]
|
||||
.matches("// Change")
|
||||
.count(),
|
||||
5
|
||||
);
|
||||
while document.redo() {}
|
||||
assert_eq!(document.past.len(), HISTORY_LIMIT);
|
||||
assert_eq!(document.revision(), 305);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_project_is_rejected_before_format_can_normalize_it() {
|
||||
let mut project = Project::empty();
|
||||
project.schema_version = 17;
|
||||
assert!(Document::from_project(project, ProjectLimits::default()).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn byte_budget_trims_oldest_history_without_discarding_a_large_current() {
|
||||
let mut document = document();
|
||||
let rationale = format!("// {}\n", "x".repeat(11 * 1024 * 1024));
|
||||
document
|
||||
.apply_bundle(comment(document.bundle(), &rationale))
|
||||
.unwrap();
|
||||
document
|
||||
.apply_bundle(comment(document.bundle(), "// Second version\n"))
|
||||
.unwrap();
|
||||
document
|
||||
.apply_bundle(comment(document.bundle(), "// Third version\n"))
|
||||
.unwrap();
|
||||
assert_eq!(document.past.len(), 1);
|
||||
let before = document.snapshot();
|
||||
assert!(document.undo());
|
||||
assert!(!document.can_undo());
|
||||
assert!(document.redo());
|
||||
assert!(Arc::ptr_eq(&before, &document.snapshot()));
|
||||
let large = format!("// {}\n", "y".repeat(22 * 1024 * 1024));
|
||||
document
|
||||
.apply_bundle(comment(document.bundle(), &large))
|
||||
.unwrap();
|
||||
assert!(document.current_bytes > HISTORY_BYTES);
|
||||
assert!(!document.can_undo());
|
||||
assert!(document.bundle().files[&document.bundle().entry].ends_with(&large));
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# Restore safe water pressure
|
||||
|
||||
This source-7 project follows one engineering question: after a pressure alarm, can the control room restore service remotely, or must a technician repair a valve? It connects the operational need to an explicitly chosen coordination-service boundary. Allow about 25 minutes for the walkthrough.
|
||||
|
||||
Copy the whole `examples/release1` folder to your working location, then open the copied `project.arcadia` in Arcadia Studio. Keep the folder together: the entry includes 29 modules, and the evidence link is relative to it. If you instead use Save As to a new folder, it copies model source files only: also copy `evidence/` beside the new entry and keep this README available. Save As does not copy external artifact targets. Existing older examples remain useful migration exercises.
|
||||
|
||||
The numbers, guards and states describe an illustrative design. The model does not simulate hydraulics, execute a control algorithm, or establish the safety of an actual water network.
|
||||
|
||||
## 1. Start with responsibility, not equipment
|
||||
|
||||
Open saved view **1 · OA responsibility and repair traffic**. The **Control room** assesses the alarm, resets the valve and confirms pressure. The **Field technician** performs field repair. The parent activity **Restore safe pressure** groups these leaf activities; responsibility is allocated to the leaves.
|
||||
|
||||
Inspect **Technician service conversation** (`oa_contact`). This unoriented CommunicationMean connects operational participants. **Request field repair** and **Report repair result** are Interactions between their allocated activities. Each Interaction is explicitly allocated to the communication mean. No OA port or implementation component has been introduced.
|
||||
|
||||
Inspect the **Valve repair** exchange item and its `pressure` parameter. The parameter has direction InOut, Value storage, multiplicity 1..1, and a real-valued type bounded from 0 to 600 with unit text `kPa`. The unit documents the contract; no conversion is inferred.
|
||||
|
||||
## 2. Follow the alternative and its reusable procedure
|
||||
|
||||
Open process **Handle a pressure alarm** (`oa_response`) in the behavior workspace. Its first step references **Assess an alarm procedure** (`oa_assessment_procedure`), whose Action uses the assessment activity and whose ChainInvolvement supports **Assess an alarm**. Follow that reference to the Choice in the main process. The guarded branch allows an authorized remote reset; the `else` branch references **Field repair procedure** (`oa_field_procedure`). Both paths merge before confirmation. The explicit SequenceLinks define flow; the list of steps alone does not imply those branches.
|
||||
|
||||
Open the referenced procedure. It contains request exchange, repair action, then report exchange. The parent process reuses that procedure by identity. It does not copy its actions. The main process contributes to the restoration capability.
|
||||
|
||||
Open scenario **Repair request and measured reply** (`oa_conversation`). The Control room calls the technician using the communication mean, supplying `420.0`. The technician's correlated Reply returns `320.0` on the reversed participant pair. The reply points to the actual Call. The enclosing scenario (`oa_full_scenario`) reuses this conversation with two explicit lifeline bindings.
|
||||
|
||||
The mission **Maintain safe water supply** links to the restoration capability, which includes the assessment capability. The repair conversation has the restoration context: it begins after assessment and coordinates repair. The assessment procedure supplies the separate assessment behavior support.
|
||||
|
||||
## 3. Examine the explicit SA engineering decisions
|
||||
|
||||
Open **2 · SA service boundary and functions**. The chosen System is **Pressure coordination service**; the technician remains outside as a SystemActor. OA activities have traced SA functions. The communication mean has a traced SA BoundaryExchange (`sa_contact`), with two explicitly chosen Standard component ports. The two Interactions have traced FunctionalExchanges with directional function ports.
|
||||
|
||||
Inspect **Valve repair service** (`sa_repair_interface`), its synchronous Operation acceptance, and the client Requires / provider Provides links. Four PortAllocations connect the function ports to their component ports; two ExchangeAllocations connect functional traffic to the boundary exchange. These are explicit contract refinements. An operational channel cannot choose the technical interface or ports on the engineer's behalf.
|
||||
|
||||
The generator performs the real OA→SA transition. `transition-before.json` is the OA model plus the two intentionally named SA participants. `transition-request.json` contains their explicit mappings and both component-port Create decisions. It deliberately leaves the operational ExchangeAllocations out of this first transition: those allocations require the later reviewed SA interface and port refinements. Omitting these allocations is explicit, not silently guessed.
|
||||
|
||||
For a fresh transition exercise, import `transition-before.json`, select the OA content, map Control room to the existing System and Field technician to the existing SystemActor, and review both communication endpoint ports. The supplied request is the exact programmatic counterpart. The generated final project then adds the interface/port allocations, views, evidence and one unfinished function. Fresh transition UUIDs are normalized by the generator for stable published files, so an interactive replay is semantically comparable rather than byte-identical to `model.json`.
|
||||
|
||||
## 4. Compare views without changing the architecture
|
||||
|
||||
Switch between **2 · SA service boundary and functions** and **3 · SA service conversation only**. They place the same semantic identities. The focused view uses the participant exchange category, an explicitly empty work-category selection, and NameAndItems labels. It shows the boundary conversation and hides functional traffic. The underlying exchanges and their port positions remain unchanged.
|
||||
|
||||
Open View properties to inspect the selections. Clearing a filter does not delete a relation. The category is an engineering collection of existing exchanges; it is not a replacement exchange. **4 · SA mission and included capability** supplies a separate goal view.
|
||||
|
||||
Open **5 · SA pressure supervision** in the state workspace. Follow the initial state to monitoring, the typed high-pressure Change event into waiting, and the guarded return. Waiting has an Entry action linked to the assessment function. This is an event/action relationship, not free prose embedded in a transition label.
|
||||
|
||||
## 5. Investigate the deliberate warning
|
||||
|
||||
Model checks should report exactly one warning: `work_without_behavior_context` on **Audit pressure thresholds** (`sa_audit_thresholds`). It has a responsible System but no process/chain or scenario use. `expected-diagnostics.json` records the expected located issue.
|
||||
|
||||
Decide whether threshold auditing belongs in the response process, in a separate maintenance behavior, or outside the intended model. Add the appropriate behavior use or remove the explicitly out-of-scope function. Merely hiding it in a view would not resolve the coverage question. The supplied model intentionally leaves this decision open.
|
||||
|
||||
## 6. Make one reviewed change and inspect its source
|
||||
|
||||
1. In OA, rename **Confirm safe pressure** (`oa_confirm`) to **Confirm stable pressure** and Apply the edit.
|
||||
2. Open semantic OA→SA review for that activity and its existing function counterpart (`sa_confirm`). Review the Header Name facet and choose Take source. Preview, then Apply the reviewed change.
|
||||
3. Confirm that the SA function name changed while the deliberately different System name remains **Pressure coordination service**.
|
||||
4. In Source, inspect `sa/functions/function_sa_restore_work.arcadia` and `traceability.arcadia`. The counterpart name and review history change. Unrelated modules retain their text. Use Undo/Redo in this editing session to inspect the reviewed transaction; then Save and reopen to check persistence. Undo history is session-local; reopening restores the saved model, not the previous undo stack.
|
||||
|
||||
The integration oracle executes this exact semantic review and source update. It separately proves that changing the request Interaction to target a Control-room-owned activity violates the communication allocation's performer pairing: command and source-update paths reject the invalid candidate together.
|
||||
|
||||
## Source, service and reproducibility
|
||||
|
||||
| File or folder | Purpose |
|
||||
|---|---|
|
||||
| `project.arcadia` | Openable source-7 entry with all module includes |
|
||||
| `oa/`, `sa/` | Participants, work, data, capabilities and reusable behavior |
|
||||
| `views/` | Five saved views; filters and placements are presentation state |
|
||||
| `traceability.arcadia` | OA↔SA correspondence and review history |
|
||||
| `model.json` | Current schema-7 interchange of the final accepted model |
|
||||
| `transition-before.json`, `transition-request.json` | Explicit first-transition replay inputs |
|
||||
| `evidence/repair-check.md` | Local teaching evidence linked from the SA conversation |
|
||||
| `model.rs` | Deterministic lesson builder shared by generator and tests |
|
||||
|
||||
The REST routes are documented in [the API reference](../../docs/api.rst). Import `model.json` with `POST /api/v1/projects/import`; query the returned resource's `/model` and `/validation`. Expect schema 7 and the one warning above. JSON import provides canonical source; to retain the exact modular source layout, use `/api/v1/projects/import-source-project` with a SourceBundle containing entry `project.arcadia` and only the 30 reachable `.arcadia` file strings, keyed by slash-separated relative paths. Neither route reads the artifact target from your local filesystem.
|
||||
|
||||
For transition replay, import `transition-before.json` instead. Submit `transition-request.json` to that baseline resource's `/transitions/preview` with its current ETag in `If-Match`. Review the returned plan, then follow the documented `/transitions/apply` protocol. Use the baseline resource for this exercise: the final model already contains the mapped records and subsequent refinements. This tutorial's automated evidence is core/source validation; it does not claim a separate native or HTTP acceptance run of this particular example.
|
||||
|
||||
From the repository root, with the supported Rust toolchain available:
|
||||
|
||||
```text
|
||||
cargo run --locked -p oa-core --example generate_release1 -- examples/release1
|
||||
cargo test --locked -p oa-core --test release1_teaching
|
||||
```
|
||||
|
||||
Regeneration deliberately overwrites the generated source and JSON in the selected output folder. Copy the lesson before experimenting. No old examples are rewritten. The tests check deterministic regeneration, exact source/interchange parity, explicit transport and reply direction, behavior reuse, view identity/geometry, atomic rejection, and a reviewed name change preserving unrelated modules.
|
||||
|
||||
The available SVG export is for architecture views. Faithful process, scenario and state-scene SVG export is outside this first-release export scope; the interactive behavior workspace is the authoritative rendering for this exercise.
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
# Repair conversation acceptance notes
|
||||
|
||||
Revision: lesson-1. Linked from `sa_conversation` by `repair_test_evidence`, relation Verifies, fragment `acceptance`.
|
||||
|
||||
## Acceptance
|
||||
|
||||
This is a reproducible teaching check, not field-test evidence for a real valve.
|
||||
|
||||
- The Control room calls the Field technician across the operational channel; the correlated Reply reverses the actual Call pair.
|
||||
- The SA conversation uses the selected service boundary and explicit Standard client/provider ports. A synchronous operation interface and its Requires/Provides links describe the contract.
|
||||
- Both request and report functional exchanges are allocated through matching function/component ports and the boundary exchange.
|
||||
- The example carries input/output pressure values `420.0` and `320.0` against the declared 0..600 real type. Values and unit text are descriptive model data; no hydraulic simulation has run.
|
||||
- The remote reset and field-repair alternatives join before pressure confirmation. The field procedure and scenario conversation are reused through identities and explicit bindings.
|
||||
|
||||
Run `cargo test --locked -p oa-core --test release1_teaching` from the repository root to reproduce the core/source oracles. The intentionally unfinished threshold-audit function remains a located coverage warning. Actual equipment safety assessment, executable control validation and field measurements are separate engineering work.
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
[
|
||||
{
|
||||
"code": "work_without_behavior_context",
|
||||
"element": "4149a872-3440-59de-9879-8981e78d27ab",
|
||||
"field": null,
|
||||
"message": "Include this leaf activity/function in a process/chain or scenario through a work action or exchange occurrence.",
|
||||
"severity": "Warning"
|
||||
}
|
||||
]
|
||||
+4401
File diff suppressed because it is too large
Load Diff
+1040
File diff suppressed because it is too large
Load Diff
+45
@@ -0,0 +1,45 @@
|
||||
oa_activity oa_restore_work "Restore safe pressure" id "1b91f8a7-0bdb-514e-b1cd-955658e09927" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
oa_activity oa_assess "Assess pressure alarm" id "61f7bbfb-74a4-5540-9182-2583dfb27a49" {
|
||||
description "";
|
||||
parent @oa_restore_work;
|
||||
}
|
||||
|
||||
oa_activity oa_confirm "Confirm safe pressure" id "727c0b5c-8db6-5eb7-83d6-735519c5949f" {
|
||||
description "";
|
||||
parent @oa_restore_work;
|
||||
}
|
||||
|
||||
oa_activity oa_repair "Repair valve in the field" id "a21465af-05f3-5fb5-8983-de26932422fb" {
|
||||
description "";
|
||||
parent @oa_restore_work;
|
||||
}
|
||||
|
||||
oa_activity oa_reset "Reset valve remotely" id "d0c8be87-d238-503a-a549-7558a210507f" {
|
||||
description "";
|
||||
parent @oa_restore_work;
|
||||
}
|
||||
|
||||
capability_involvement oa_assessment_support "Capability involvement: Assess an alarm" id "ffdbfcd0-d423-5707-a880-0dfbe1400f72" {
|
||||
description "";
|
||||
source @oa_assess;
|
||||
target @oa_triage;
|
||||
}
|
||||
|
||||
interaction oa_repair_request "Request field repair" id "cf423ea2-8b2e-5a27-93d4-5e8542d9db8d" {
|
||||
description "";
|
||||
items [@oa_repair_operation];
|
||||
source @oa_assess;
|
||||
target @oa_repair;
|
||||
}
|
||||
|
||||
interaction oa_repair_report "Report repair result" id "b436d0b3-c824-5a96-af6b-2c269816d1cc" {
|
||||
description "";
|
||||
items [@oa_repair_operation];
|
||||
source @oa_repair;
|
||||
target @oa_confirm;
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
oa_process oa_assessment_procedure "Assess an alarm procedure" id "022d3cfa-bbaf-5e13-924a-8e55099b8745" {
|
||||
description "";
|
||||
parent none;
|
||||
steps [@oa_assessment_action];
|
||||
}
|
||||
|
||||
oa_occurrence oa_assessment_action "Assess pressure alarm" id "942975b8-0bef-5ae8-9fcb-c37497833fb0" {
|
||||
body {
|
||||
Action {
|
||||
action @oa_assess;
|
||||
lifeline none;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_assessment_procedure;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
chain_involvement oa_assessment_delivery "Chain involvement: Assess an alarm" id "628cb4fc-fe63-5f6b-b364-6268f26b5740" {
|
||||
description "";
|
||||
source @oa_assessment_procedure;
|
||||
target @oa_triage;
|
||||
}
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
oa_process oa_field_procedure "Field repair procedure" id "5d3af417-244c-54bb-9588-16daedda4e1f" {
|
||||
description "";
|
||||
parent none;
|
||||
steps [@oa_request_step, @oa_repair_step, @oa_report_step];
|
||||
}
|
||||
|
||||
oa_occurrence oa_repair_step "Repair the valve" id "c59432fe-6092-5ee0-908d-9dbf39476471" {
|
||||
body {
|
||||
Action {
|
||||
action @oa_repair;
|
||||
lifeline none;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_field_procedure;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_occurrence oa_report_step "Report the measured result" id "df2fd3f8-6bc2-5380-a13f-36643ed35ac7" {
|
||||
body {
|
||||
Exchange {
|
||||
exchange @oa_repair_report;
|
||||
message_kind Asynchronous;
|
||||
receiver none;
|
||||
reply_to none;
|
||||
sender none;
|
||||
values [];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_field_procedure;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_occurrence oa_request_step "Request the field repair" id "5ba8079c-2dbe-5e98-ae82-2b60c6020a02" {
|
||||
body {
|
||||
Exchange {
|
||||
exchange @oa_repair_request;
|
||||
message_kind Asynchronous;
|
||||
receiver none;
|
||||
reply_to none;
|
||||
sender none;
|
||||
values [];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_field_procedure;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sequence_link oa_repair_then_report "Sequence link: Report the measured result" id "c8196d35-2168-5fef-8b03-ba0d139bc00f" {
|
||||
description "";
|
||||
guard "";
|
||||
source @oa_repair_step;
|
||||
target @oa_report_step;
|
||||
}
|
||||
|
||||
sequence_link oa_request_then_repair "Sequence link: Repair the valve" id "3f54d890-4ca5-5e36-873b-abb5c92d578c" {
|
||||
description "";
|
||||
guard "";
|
||||
source @oa_request_step;
|
||||
target @oa_repair_step;
|
||||
}
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
oa_process oa_response "Handle a pressure alarm" id "58bae2b0-f560-50f2-818d-19091d22d18a" {
|
||||
description "";
|
||||
parent none;
|
||||
steps [@oa_assess_step, @oa_decision, @oa_reset_step, @oa_use_field, @oa_merge, @oa_confirm_step];
|
||||
}
|
||||
|
||||
oa_occurrence oa_assess_step "Assess the alarm" id "0b07b9ed-492d-57f6-b0b1-ce8a709238a7" {
|
||||
body {
|
||||
SequenceReference {
|
||||
sequence @oa_assessment_procedure;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_occurrence oa_confirm_step "Confirm safe pressure" id "e00594a3-6122-5a6b-b3c2-ecb5506c741d" {
|
||||
body {
|
||||
Action {
|
||||
action @oa_confirm;
|
||||
lifeline none;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_occurrence oa_decision "Can a remote reset safely recover pressure?" id "b280c6ca-e5f9-5424-a5c1-5676e01c2371" {
|
||||
body {
|
||||
Control {
|
||||
kind Choice;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_occurrence oa_merge "Recovery path completed" id "6b945a6d-6aa0-5dd3-96e6-2e8d757d167d" {
|
||||
body {
|
||||
Control {
|
||||
kind Merge;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_occurrence oa_reset_step "Try the authorized remote reset" id "d2026fc2-74a8-5e22-9942-ff3eb68a3677" {
|
||||
body {
|
||||
Action {
|
||||
action @oa_reset;
|
||||
lifeline none;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_occurrence oa_use_field "Use the field repair procedure" id "fc6763bf-a534-54bf-afcd-57ab285ff07d" {
|
||||
body {
|
||||
SequenceReference {
|
||||
sequence @oa_field_procedure;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sequence_link oa_assess_then_decide "Continue" id "109e2d6b-7e86-5934-93a5-fab56eced84e" {
|
||||
description "";
|
||||
guard "";
|
||||
source @oa_assess_step;
|
||||
target @oa_decision;
|
||||
}
|
||||
|
||||
sequence_link oa_field_path "else" id "c1adbbd0-a762-5ee3-8b9a-5c18af377771" {
|
||||
description "";
|
||||
guard "else";
|
||||
source @oa_decision;
|
||||
target @oa_use_field;
|
||||
}
|
||||
|
||||
sequence_link oa_remote_path "remote reset is authorized" id "76218d89-68fd-531d-b35b-90c5b769a5ef" {
|
||||
description "";
|
||||
guard "remote reset is authorized";
|
||||
source @oa_decision;
|
||||
target @oa_reset_step;
|
||||
}
|
||||
|
||||
sequence_link oa_confirm_path "Continue" id "229ee94f-d147-50f6-9769-b5bd0c03a084" {
|
||||
description "";
|
||||
guard "";
|
||||
source @oa_merge;
|
||||
target @oa_confirm_step;
|
||||
}
|
||||
|
||||
sequence_link oa_remote_merge "Continue" id "bac43d3b-910b-5bdc-be9b-f78cf973e1ed" {
|
||||
description "";
|
||||
guard "";
|
||||
source @oa_reset_step;
|
||||
target @oa_merge;
|
||||
}
|
||||
|
||||
chain_involvement oa_response_delivery "Chain involvement: Restore a safe supply" id "c7c248f8-28b8-55be-9023-0991d44021e3" {
|
||||
description "";
|
||||
source @oa_response;
|
||||
target @oa_restore;
|
||||
}
|
||||
|
||||
sequence_link oa_field_merge "Continue" id "c8593670-8906-530f-b6a2-3ada77a9c219" {
|
||||
description "";
|
||||
guard "";
|
||||
source @oa_use_field;
|
||||
target @oa_merge;
|
||||
}
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
oa_scenario oa_conversation "Repair request and measured reply" id "20472233-5ce6-5ffe-b4ad-0bdbccf3e423" {
|
||||
context @oa_restore;
|
||||
description "";
|
||||
parent none;
|
||||
postcondition "The controller has received the measured pressure after repair";
|
||||
precondition "A pressure alarm has been assessed";
|
||||
steps [@oa_call, @oa_reply];
|
||||
viewpoint ParticipantInteraction;
|
||||
}
|
||||
|
||||
oa_occurrence oa_call "Request valve repair" id "b97437c6-cd7a-5a05-b537-b30a17dd936a" {
|
||||
body {
|
||||
Exchange {
|
||||
exchange @oa_contact;
|
||||
message_kind Call;
|
||||
receiver @oa_responder;
|
||||
reply_to none;
|
||||
sender @oa_caller;
|
||||
values [{
|
||||
expression "420.0";
|
||||
field @oa_pressure_parameter;
|
||||
path [];
|
||||
}];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_conversation;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_lifeline oa_caller "Controller" id "41859a65-ded2-547b-ab03-14e2fa740cf9" {
|
||||
description "";
|
||||
parent @oa_conversation;
|
||||
represented @oa_control;
|
||||
}
|
||||
|
||||
oa_occurrence oa_reply "Return pressure after repair" id "cc2d497a-fd15-5455-9ee5-e70eb95811d8" {
|
||||
body {
|
||||
Exchange {
|
||||
exchange @oa_contact;
|
||||
message_kind Reply;
|
||||
receiver @oa_caller;
|
||||
reply_to @oa_call;
|
||||
sender @oa_responder;
|
||||
values [{
|
||||
expression "320.0";
|
||||
field @oa_pressure_parameter;
|
||||
path [];
|
||||
}];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_conversation;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
oa_lifeline oa_responder "Technician" id "fc81c5f0-0442-5b88-992b-e5b10f351c59" {
|
||||
description "";
|
||||
parent @oa_conversation;
|
||||
represented @oa_technician;
|
||||
}
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
oa_scenario oa_full_scenario "Restore supply through field repair" id "d6f881a4-95da-54e9-ad97-1b8965532629" {
|
||||
context @oa_restore;
|
||||
description "";
|
||||
parent none;
|
||||
postcondition "The controller has received the measured pressure after repair";
|
||||
precondition "A pressure alarm has been assessed";
|
||||
steps [@oa_use_conversation];
|
||||
viewpoint ParticipantInteraction;
|
||||
}
|
||||
|
||||
oa_lifeline oa_outer_controller "Controller" id "2011b3ac-614b-5a47-8891-7ff81965f425" {
|
||||
description "";
|
||||
parent @oa_full_scenario;
|
||||
represented @oa_control;
|
||||
}
|
||||
|
||||
oa_lifeline oa_outer_technician "Technician" id "fffff882-78fd-5415-928d-c1ef7fac6576" {
|
||||
description "";
|
||||
parent @oa_full_scenario;
|
||||
represented @oa_technician;
|
||||
}
|
||||
|
||||
oa_occurrence oa_use_conversation "Use the reviewed repair conversation" id "9ff94014-afa1-50ab-a4d3-8e9dd0565cc5" {
|
||||
body {
|
||||
ScenarioUse {
|
||||
bindings [{
|
||||
local @oa_outer_controller;
|
||||
referenced @oa_caller;
|
||||
}, {
|
||||
local @oa_outer_technician;
|
||||
referenced @oa_responder;
|
||||
}];
|
||||
scenario @oa_conversation;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @oa_full_scenario;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
oa_state_machine oa_monitor "Pressure supervision" id "1970608f-85d1-5234-ac86-5e2b0df27dc3" {
|
||||
description "";
|
||||
parent @oa_control;
|
||||
}
|
||||
|
||||
oa_region oa_monitor_region "Supervision cycle" id "8412e9c6-96fe-5ed6-a903-1d37ec3c3bf7" {
|
||||
description "";
|
||||
parent @oa_monitor;
|
||||
}
|
||||
|
||||
oa_initial oa_monitor_initial "Start" id "a7ffb869-9dde-5e76-b276-c719c5c143a9" {
|
||||
description "";
|
||||
do_activity "";
|
||||
entry "";
|
||||
exit "";
|
||||
kind Initial;
|
||||
parent @oa_monitor_region;
|
||||
}
|
||||
|
||||
oa_state oa_monitoring "Monitoring" id "6cbde0d8-9f5f-510a-a8c1-e29cb99ad4ae" {
|
||||
description "";
|
||||
do_activity "";
|
||||
entry "";
|
||||
exit "";
|
||||
kind State;
|
||||
parent @oa_monitor_region;
|
||||
}
|
||||
|
||||
oa_state oa_waiting "Awaiting repair" id "58c15833-6e75-523a-b57f-a88f19f6d672" {
|
||||
description "";
|
||||
do_activity "";
|
||||
entry "";
|
||||
exit "";
|
||||
kind State;
|
||||
parent @oa_monitor_region;
|
||||
}
|
||||
|
||||
state_transition oa_start_monitoring "State transition: Monitoring" id "2b00270c-79a5-52a5-af96-33346bea531b" {
|
||||
description "";
|
||||
effect "";
|
||||
effects [];
|
||||
guard "";
|
||||
source @oa_monitor_initial;
|
||||
target @oa_monitoring;
|
||||
transition_kind External;
|
||||
trigger "";
|
||||
triggers [];
|
||||
}
|
||||
|
||||
state_transition oa_alarm_transition "State transition: Awaiting repair" id "fbde9d5e-c7e9-55db-a2be-497345c491b3" {
|
||||
description "";
|
||||
effect "";
|
||||
effects [];
|
||||
guard "";
|
||||
source @oa_monitoring;
|
||||
target @oa_waiting;
|
||||
transition_kind External;
|
||||
trigger "";
|
||||
triggers [@oa_high_pressure];
|
||||
}
|
||||
|
||||
state_action oa_assess_on_entry "Assess when repair is needed" id "7fa37e63-db65-5aa7-88f2-31ff4347a787" {
|
||||
description "";
|
||||
phase Entry;
|
||||
source @oa_waiting;
|
||||
target @oa_assess;
|
||||
}
|
||||
|
||||
state_transition oa_normal_transition "State transition: Monitoring" id "21fe5e8e-cbc2-5dad-b3e8-1df46e167d97" {
|
||||
description "";
|
||||
effect "";
|
||||
effects [];
|
||||
guard "repair confirmed and pressure is safe";
|
||||
source @oa_waiting;
|
||||
target @oa_monitoring;
|
||||
transition_kind External;
|
||||
trigger "";
|
||||
triggers [];
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
oa_mission oa_mission "Maintain safe water supply" id "c9c61f50-06e0-5d17-973d-dcc57cd5cc90" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
oa_capability oa_restore "Restore a safe supply" id "3dfee23a-148b-5cec-ad2d-b774e84ea5bb" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
oa_capability oa_triage "Assess an alarm" id "6a30b763-cc51-546d-907f-5c63657cfd03" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
mission_capability oa_mission_delivery "Mission capability: Restore a safe supply" id "1f8b1898-65f6-5360-99cf-b78a71bd50ec" {
|
||||
description "";
|
||||
source @oa_mission;
|
||||
target @oa_restore;
|
||||
}
|
||||
|
||||
capability_include oa_include_triage "Capability include: Assess an alarm" id "e21d9a54-ae8e-5618-a4f8-67ee22b92638" {
|
||||
description "";
|
||||
source @oa_restore;
|
||||
target @oa_triage;
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
oa_exchange_category oa_contact_category "Field contact" id "19bd3a3a-4d0c-56d5-bf50-a6b43fd81771" {
|
||||
description "";
|
||||
exchanges [@oa_contact];
|
||||
family "Participant";
|
||||
parent none;
|
||||
}
|
||||
|
||||
oa_event oa_high_pressure "Pressure alarm detected" id "65d6b8d6-271a-5c84-8b42-abbe310c955e" {
|
||||
body {
|
||||
Change {
|
||||
expression "measured_pressure > operating_limit";
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
oa_exchange_category oa_repair_traffic "Repair work exchanges" id "9349b353-53f2-56f8-b571-a05b09335cdf" {
|
||||
description "";
|
||||
exchanges [@oa_repair_request, @oa_repair_report];
|
||||
family "Work";
|
||||
parent none;
|
||||
}
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
oa_entity oa_control "Control room" id "32aa9940-df6e-5a12-b9bd-6337e2d2ed22" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
oa_actor oa_technician "Field technician" id "e07c3952-4a1a-5cc7-b7d5-03a01101ce49" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
allocation oa_assess_allocation "Allocation: Assess pressure alarm" id "594c61cd-94e0-5c07-890d-edfd520d7df9" {
|
||||
description "";
|
||||
source @oa_control;
|
||||
target @oa_assess;
|
||||
}
|
||||
|
||||
allocation oa_confirm_allocation "Allocation: Confirm safe pressure" id "bfd4326e-ea65-5269-b5e6-e063a355d1e9" {
|
||||
description "";
|
||||
source @oa_control;
|
||||
target @oa_confirm;
|
||||
}
|
||||
|
||||
communication_mean oa_contact "Technician service conversation" id "27b47887-baf0-518b-bf87-f5acbf7d0b93" {
|
||||
description "";
|
||||
items [@oa_repair_operation];
|
||||
oriented false;
|
||||
source @oa_control;
|
||||
target @oa_technician;
|
||||
}
|
||||
|
||||
exchange_allocation oa_report_carriage "Exchange allocation: Report repair result" id "4549d3fa-5ab9-52a9-b4f9-3a78fc9d625a" {
|
||||
description "";
|
||||
source @oa_contact;
|
||||
target @oa_repair_report;
|
||||
}
|
||||
|
||||
exchange_allocation oa_request_carriage "Exchange allocation: Request field repair" id "094b888c-450c-5c4f-971a-7d75db059574" {
|
||||
description "";
|
||||
source @oa_contact;
|
||||
target @oa_repair_request;
|
||||
}
|
||||
|
||||
mission_involvement oa_mission_participant "Mission involvement: Maintain safe water supply" id "0c4c9e58-ff32-5c00-b82a-d408a4be0183" {
|
||||
description "";
|
||||
source @oa_control;
|
||||
target @oa_mission;
|
||||
}
|
||||
|
||||
allocation oa_reset_allocation "Allocation: Reset valve remotely" id "1853df1f-30f4-5b1a-baac-2dcaf73c7b3a" {
|
||||
description "";
|
||||
source @oa_control;
|
||||
target @oa_reset;
|
||||
}
|
||||
|
||||
allocation oa_repair_allocation "Allocation: Repair valve in the field" id "ae53f363-0dec-5a7c-9afd-8fcd1b778ab2" {
|
||||
description "";
|
||||
source @oa_technician;
|
||||
target @oa_repair;
|
||||
}
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
oa_data_type oa_pressure "Measured pressure" id "e7824764-5db9-5384-8198-2fbaea2b10b2" {
|
||||
default none;
|
||||
definition {
|
||||
Real {
|
||||
maximum 600.0;
|
||||
minimum 0.0;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent none;
|
||||
unit "kPa";
|
||||
}
|
||||
|
||||
oa_exchange_item oa_repair_operation "Valve repair" id "d736c7d6-d369-550a-8ba4-dae223e40bb3" {
|
||||
description "";
|
||||
kind Information;
|
||||
mechanism Operation;
|
||||
parent none;
|
||||
supertype none;
|
||||
}
|
||||
|
||||
oa_data_field oa_pressure_parameter "Pressure before / after repair" id "8bc6d0a4-3e87-559b-8bd7-1b679a2db5b7" {
|
||||
default none;
|
||||
description "";
|
||||
direction InOut;
|
||||
maximum 1;
|
||||
minimum 1;
|
||||
parent @oa_repair_operation;
|
||||
storage Value;
|
||||
type_ref {
|
||||
Named @oa_pressure;
|
||||
};
|
||||
unit "";
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
arcadia 7;
|
||||
project pressure_restoration "Restore safe water pressure — release 1 walkthrough" id "2786d72f-5763-5f33-a57f-2773a4ca1a6c" {
|
||||
description "A controller either resets a valve remotely or requests field repair. Compare the operational need with the explicitly chosen coordination-service boundary. Start with README.md beside project.arcadia. Units and guards are descriptive; this model does not simulate a real water network.";
|
||||
include "oa/activities/activity_oa_restore_work.arcadia";
|
||||
include "oa/behavior/process_oa_assessment_procedure.arcadia";
|
||||
include "oa/behavior/process_oa_field_procedure.arcadia";
|
||||
include "oa/behavior/process_oa_response.arcadia";
|
||||
include "oa/behavior/scenario_oa_conversation.arcadia";
|
||||
include "oa/behavior/scenario_oa_full_scenario.arcadia";
|
||||
include "oa/behavior/state_machine_oa_monitor.arcadia";
|
||||
include "oa/capabilities.arcadia";
|
||||
include "oa/model.arcadia";
|
||||
include "oa/participants.arcadia";
|
||||
include "oa/types.arcadia";
|
||||
include "sa/behavior/process_sa_assessment_procedure.arcadia";
|
||||
include "sa/behavior/process_sa_field_procedure.arcadia";
|
||||
include "sa/behavior/process_sa_response.arcadia";
|
||||
include "sa/behavior/scenario_sa_conversation.arcadia";
|
||||
include "sa/behavior/scenario_sa_full_scenario.arcadia";
|
||||
include "sa/behavior/state_machine_sa_monitor.arcadia";
|
||||
include "sa/capabilities.arcadia";
|
||||
include "sa/functions/function_sa_audit_thresholds.arcadia";
|
||||
include "sa/functions/function_sa_restore_work.arcadia";
|
||||
include "sa/model.arcadia";
|
||||
include "sa/participants.arcadia";
|
||||
include "sa/types.arcadia";
|
||||
include "traceability.arcadia";
|
||||
include "views/diagram_oa_allocation_view.arcadia";
|
||||
include "views/diagram_sa_allocation_view.arcadia";
|
||||
include "views/diagram_sa_capability_view.arcadia";
|
||||
include "views/diagram_sa_service_view.arcadia";
|
||||
include "views/diagram_sa_state_view.arcadia";
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
sa_functional_chain sa_assessment_procedure "Assess an alarm procedure" id "acd5a018-f559-5298-a40d-1cf6e1353e74" {
|
||||
description "";
|
||||
parent none;
|
||||
steps [@sa_assessment_action];
|
||||
}
|
||||
|
||||
sa_occurrence sa_assessment_action "Assess pressure alarm" id "bae5b192-5b8e-51c6-82ae-2331af0d33bf" {
|
||||
body {
|
||||
Action {
|
||||
action @sa_assess;
|
||||
lifeline none;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_assessment_procedure;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
chain_involvement sa_assessment_delivery "Chain involvement: Assess an alarm" id "a6d5a6be-fa6e-5fa0-a309-08e87ba40c57" {
|
||||
description "";
|
||||
source @sa_assessment_procedure;
|
||||
target @sa_triage;
|
||||
}
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
sa_functional_chain sa_field_procedure "Field repair procedure" id "93eb6479-54e9-59cb-ac7b-16912347bfc0" {
|
||||
description "";
|
||||
parent none;
|
||||
steps [@sa_request_step, @sa_repair_step, @sa_report_step];
|
||||
}
|
||||
|
||||
sa_occurrence sa_repair_step "Repair the valve" id "0f195fea-3493-5ebd-966d-da9eddeb05d7" {
|
||||
body {
|
||||
Action {
|
||||
action @sa_repair;
|
||||
lifeline none;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_field_procedure;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_occurrence sa_report_step "Report the measured result" id "ea32e4ec-8bdc-57ea-8a90-7b09ba4f0eac" {
|
||||
body {
|
||||
Exchange {
|
||||
exchange @sa_repair_report;
|
||||
message_kind Asynchronous;
|
||||
receiver none;
|
||||
reply_to none;
|
||||
sender none;
|
||||
values [];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_field_procedure;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_occurrence sa_request_step "Request the field repair" id "40d94322-baa2-5c81-b261-ff47cdc33782" {
|
||||
body {
|
||||
Exchange {
|
||||
exchange @sa_repair_request;
|
||||
message_kind Asynchronous;
|
||||
receiver none;
|
||||
reply_to none;
|
||||
sender none;
|
||||
values [];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_field_procedure;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sequence_link sa_repair_then_report "Sequence link: Report the measured result" id "7fb30b1d-195c-5f0e-a19c-a536f519a899" {
|
||||
description "";
|
||||
guard "";
|
||||
source @sa_repair_step;
|
||||
target @sa_report_step;
|
||||
}
|
||||
|
||||
sequence_link sa_request_then_repair "Sequence link: Repair the valve" id "6a6d968f-26d6-5dbb-b721-5a27d362779a" {
|
||||
description "";
|
||||
guard "";
|
||||
source @sa_request_step;
|
||||
target @sa_repair_step;
|
||||
}
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
sa_functional_chain sa_response "Handle a pressure alarm" id "5139ce73-56fd-5875-ba3a-e569fc890231" {
|
||||
description "";
|
||||
parent none;
|
||||
steps [@sa_assess_step, @sa_decision, @sa_reset_step, @sa_use_field, @sa_merge, @sa_confirm_step];
|
||||
}
|
||||
|
||||
sa_occurrence sa_assess_step "Assess the alarm" id "9024243c-ccc1-5edb-8477-2aa16e5e9a50" {
|
||||
body {
|
||||
SequenceReference {
|
||||
sequence @sa_assessment_procedure;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_occurrence sa_confirm_step "Confirm safe pressure" id "47bec4f9-d6d0-5ed1-adca-fa0d960dc416" {
|
||||
body {
|
||||
Action {
|
||||
action @sa_confirm;
|
||||
lifeline none;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_occurrence sa_decision "Can a remote reset safely recover pressure?" id "30c8fad9-a49b-5692-9542-3148e76afd7b" {
|
||||
body {
|
||||
Control {
|
||||
kind Choice;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_occurrence sa_merge "Recovery path completed" id "4ed0dd9d-c9e0-5652-aedf-5f0ab4328a07" {
|
||||
body {
|
||||
Control {
|
||||
kind Merge;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_occurrence sa_reset_step "Try the authorized remote reset" id "bfa2ef0b-ce68-55c2-a9e5-31ea8a74fce6" {
|
||||
body {
|
||||
Action {
|
||||
action @sa_reset;
|
||||
lifeline none;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_occurrence sa_use_field "Use the field repair procedure" id "d5e61c5d-510b-5091-a878-da46f3a9e152" {
|
||||
body {
|
||||
SequenceReference {
|
||||
sequence @sa_field_procedure;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_response;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sequence_link sa_assess_then_decide "Continue" id "9d4a131f-36ad-5125-b21f-c3dd033b8c82" {
|
||||
description "";
|
||||
guard "";
|
||||
source @sa_assess_step;
|
||||
target @sa_decision;
|
||||
}
|
||||
|
||||
sequence_link sa_field_path "else" id "1bbd5957-1173-51d8-97e3-ba4f084227ae" {
|
||||
description "";
|
||||
guard "else";
|
||||
source @sa_decision;
|
||||
target @sa_use_field;
|
||||
}
|
||||
|
||||
sequence_link sa_remote_path "remote reset is authorized" id "d8b6710a-e713-5979-934f-e5ca7d155bb4" {
|
||||
description "";
|
||||
guard "remote reset is authorized";
|
||||
source @sa_decision;
|
||||
target @sa_reset_step;
|
||||
}
|
||||
|
||||
sequence_link sa_confirm_path "Continue" id "1e738f27-a3a1-526d-b330-6384088b9689" {
|
||||
description "";
|
||||
guard "";
|
||||
source @sa_merge;
|
||||
target @sa_confirm_step;
|
||||
}
|
||||
|
||||
sequence_link sa_remote_merge "Continue" id "e5279265-8eac-52e8-98dc-571b20475e1f" {
|
||||
description "";
|
||||
guard "";
|
||||
source @sa_reset_step;
|
||||
target @sa_merge;
|
||||
}
|
||||
|
||||
chain_involvement sa_response_delivery "Chain involvement: Restore a safe supply" id "66efc484-53c7-51a3-89e9-422429344b38" {
|
||||
description "";
|
||||
source @sa_response;
|
||||
target @sa_restore;
|
||||
}
|
||||
|
||||
sequence_link sa_field_merge "Continue" id "0f6ac3fb-4ad6-581e-ad14-336472072d5e" {
|
||||
description "";
|
||||
guard "";
|
||||
source @sa_use_field;
|
||||
target @sa_merge;
|
||||
}
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
sa_scenario sa_conversation "Repair request and measured reply" id "730b27ca-b039-5a3b-8dc6-03418f9061b3" {
|
||||
context @sa_restore;
|
||||
description "";
|
||||
parent none;
|
||||
postcondition "The controller has received the measured pressure after repair";
|
||||
precondition "A pressure alarm has been assessed";
|
||||
steps [@sa_call, @sa_reply];
|
||||
viewpoint BoundaryInterface;
|
||||
}
|
||||
|
||||
sa_occurrence sa_call "Request valve repair" id "8bab4783-a098-5984-9e36-493957caf26c" {
|
||||
body {
|
||||
Exchange {
|
||||
exchange @sa_contact;
|
||||
message_kind Call;
|
||||
receiver @sa_responder;
|
||||
reply_to none;
|
||||
sender @sa_caller;
|
||||
values [{
|
||||
expression "420.0";
|
||||
field @sa_pressure_parameter;
|
||||
path [];
|
||||
}];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_conversation;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_lifeline sa_caller "Controller" id "98c61788-2fee-51f4-8cf9-de48e8c70e9e" {
|
||||
description "";
|
||||
parent @sa_conversation;
|
||||
represented @sa_control;
|
||||
}
|
||||
|
||||
sa_occurrence sa_reply "Return pressure after repair" id "4e1c0a56-ce80-5f13-a93a-6956de54880c" {
|
||||
body {
|
||||
Exchange {
|
||||
exchange @sa_contact;
|
||||
message_kind Reply;
|
||||
receiver @sa_caller;
|
||||
reply_to @sa_call;
|
||||
sender @sa_responder;
|
||||
values [{
|
||||
expression "320.0";
|
||||
field @sa_pressure_parameter;
|
||||
path [];
|
||||
}];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_conversation;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
sa_lifeline sa_responder "Technician" id "6249b54a-e396-5338-82b9-89266c55670d" {
|
||||
description "";
|
||||
parent @sa_conversation;
|
||||
represented @sa_technician;
|
||||
}
|
||||
|
||||
artifact repair_test_evidence "Repair conversation acceptance notes" id "f5922bf7-05d8-590f-86e9-1d09f37f4fa6" {
|
||||
description "A local teaching artifact, not proof of a real valve's safety.";
|
||||
fragment "acceptance";
|
||||
owner @sa_conversation;
|
||||
relation Verifies;
|
||||
revision "lesson-1";
|
||||
uri "evidence/repair-check.md";
|
||||
}
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
sa_scenario sa_full_scenario "Restore supply through field repair" id "f746a1cd-ff9f-55c0-b325-01c03d2f4fae" {
|
||||
context @sa_restore;
|
||||
description "";
|
||||
parent none;
|
||||
postcondition "The controller has received the measured pressure after repair";
|
||||
precondition "A pressure alarm has been assessed";
|
||||
steps [@sa_use_conversation];
|
||||
viewpoint BoundaryInterface;
|
||||
}
|
||||
|
||||
sa_lifeline sa_outer_controller "Controller" id "1edfcf9e-9bfa-51f1-80d5-62b8fd8bb023" {
|
||||
description "";
|
||||
parent @sa_full_scenario;
|
||||
represented @sa_control;
|
||||
}
|
||||
|
||||
sa_lifeline sa_outer_technician "Technician" id "155e4fe4-9e3b-5f4e-b886-28abcc3f086b" {
|
||||
description "";
|
||||
parent @sa_full_scenario;
|
||||
represented @sa_technician;
|
||||
}
|
||||
|
||||
sa_occurrence sa_use_conversation "Use the reviewed repair conversation" id "1c9da843-e2d3-5591-8e3f-db083a42867e" {
|
||||
body {
|
||||
ScenarioUse {
|
||||
bindings [{
|
||||
local @sa_outer_controller;
|
||||
referenced @sa_caller;
|
||||
}, {
|
||||
local @sa_outer_technician;
|
||||
referenced @sa_responder;
|
||||
}];
|
||||
scenario @sa_conversation;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent @sa_full_scenario;
|
||||
postcondition "";
|
||||
precondition "";
|
||||
}
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
sa_state_machine sa_monitor "Pressure supervision" id "132b3f28-3f88-5327-9868-8c8b645ed412" {
|
||||
description "";
|
||||
parent @sa_control;
|
||||
}
|
||||
|
||||
sa_region sa_monitor_region "Supervision cycle" id "3ab11e24-4140-58fc-b3fa-da5f51c7fe2c" {
|
||||
description "";
|
||||
parent @sa_monitor;
|
||||
}
|
||||
|
||||
sa_initial sa_monitor_initial "Start" id "57eb5348-14d8-560e-996a-8dbf993243e2" {
|
||||
description "";
|
||||
do_activity "";
|
||||
entry "";
|
||||
exit "";
|
||||
kind Initial;
|
||||
parent @sa_monitor_region;
|
||||
}
|
||||
|
||||
sa_state sa_monitoring "Monitoring" id "8af21f9b-c21e-5aae-af0d-0958840f6655" {
|
||||
description "";
|
||||
do_activity "";
|
||||
entry "";
|
||||
exit "";
|
||||
kind State;
|
||||
parent @sa_monitor_region;
|
||||
}
|
||||
|
||||
sa_state sa_waiting "Awaiting repair" id "a6bb10b1-f1e5-5b31-8afd-5bad5a7b6c37" {
|
||||
description "";
|
||||
do_activity "";
|
||||
entry "";
|
||||
exit "";
|
||||
kind State;
|
||||
parent @sa_monitor_region;
|
||||
}
|
||||
|
||||
state_transition sa_start_monitoring "State transition: Monitoring" id "47730532-0372-5cc5-9d6d-0b8953aebdd8" {
|
||||
description "";
|
||||
effect "";
|
||||
effects [];
|
||||
guard "";
|
||||
source @sa_monitor_initial;
|
||||
target @sa_monitoring;
|
||||
transition_kind External;
|
||||
trigger "";
|
||||
triggers [];
|
||||
}
|
||||
|
||||
state_transition sa_alarm_transition "State transition: Awaiting repair" id "13c3bfa4-9254-5ab2-b96f-f65f402adf81" {
|
||||
description "";
|
||||
effect "";
|
||||
effects [];
|
||||
guard "";
|
||||
source @sa_monitoring;
|
||||
target @sa_waiting;
|
||||
transition_kind External;
|
||||
trigger "";
|
||||
triggers [@sa_high_pressure];
|
||||
}
|
||||
|
||||
state_action sa_assess_on_entry "Assess when repair is needed" id "a887f96a-37cb-5891-8070-011fa276e5b5" {
|
||||
description "";
|
||||
phase Entry;
|
||||
source @sa_waiting;
|
||||
target @sa_assess;
|
||||
}
|
||||
|
||||
state_transition sa_normal_transition "State transition: Monitoring" id "6e2c1b47-764c-577a-b325-ff66dd2a2768" {
|
||||
description "";
|
||||
effect "";
|
||||
effects [];
|
||||
guard "repair confirmed and pressure is safe";
|
||||
source @sa_waiting;
|
||||
target @sa_monitoring;
|
||||
transition_kind External;
|
||||
trigger "";
|
||||
triggers [];
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
sa_mission sa_mission "Maintain safe water supply" id "5ad034b1-084d-5273-9e70-971671766132" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
sa_capability sa_restore "Restore a safe supply" id "81259051-370a-512d-a3b5-6420a6f933b6" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
sa_capability sa_triage "Assess an alarm" id "bad8fa7c-f634-55fd-98d3-e1eb2da05d8f" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
mission_capability sa_mission_delivery "Mission capability: Restore a safe supply" id "a0902e0f-3d18-576a-9aca-975a136dfdd7" {
|
||||
description "";
|
||||
source @sa_mission;
|
||||
target @sa_restore;
|
||||
}
|
||||
|
||||
capability_include sa_include_triage "Capability include: Assess an alarm" id "f3fe7690-734a-5877-8b57-a6599a4033c4" {
|
||||
description "";
|
||||
source @sa_restore;
|
||||
target @sa_triage;
|
||||
}
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
sa_function sa_audit_thresholds "Audit pressure thresholds" id "4149a872-3440-59de-9879-8981e78d27ab" {
|
||||
description "Deliberately unfinished: assigned to the service, but no behavior context yet. Model checks should expose this one work_without_behavior_context warning.";
|
||||
parent none;
|
||||
}
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
sa_function sa_restore_work "Restore safe pressure" id "58867e7d-916e-5ebc-9e4c-8dbed1314be3" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
sa_function sa_assess "Assess pressure alarm" id "dddae020-a444-5d48-acc8-139d2696a672" {
|
||||
description "";
|
||||
parent @sa_restore_work;
|
||||
}
|
||||
|
||||
sa_port sa_repair_request_out "Request field repair output" id "24a6850e-b819-57e0-af88-ca4ab76581b7" {
|
||||
contract {
|
||||
FunctionOutput {
|
||||
outgoing_items [@sa_repair_operation];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
legacy none;
|
||||
parent @sa_assess;
|
||||
}
|
||||
|
||||
sa_function sa_confirm "Confirm safe pressure" id "d75eb3fa-a27d-52d5-8782-8b342b3865f6" {
|
||||
description "";
|
||||
parent @sa_restore_work;
|
||||
}
|
||||
|
||||
sa_port sa_repair_report_in "Report repair result input" id "391af7c4-b07d-53a7-8ddd-5c81461fc4f8" {
|
||||
contract {
|
||||
FunctionInput {
|
||||
incoming_items [@sa_repair_operation];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
legacy none;
|
||||
parent @sa_confirm;
|
||||
}
|
||||
|
||||
sa_function sa_repair "Repair valve in the field" id "9497e10f-04c4-5586-8738-2464a6f00bd4" {
|
||||
description "";
|
||||
parent @sa_restore_work;
|
||||
}
|
||||
|
||||
sa_port sa_repair_report_out "Report repair result output" id "994faed7-dbc8-5b96-9d62-7604ac0fbc3a" {
|
||||
contract {
|
||||
FunctionOutput {
|
||||
outgoing_items [@sa_repair_operation];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
legacy none;
|
||||
parent @sa_repair;
|
||||
}
|
||||
|
||||
sa_port sa_repair_request_in "Request field repair input" id "d2113fb0-a531-54ef-9484-13951b00ab8f" {
|
||||
contract {
|
||||
FunctionInput {
|
||||
incoming_items [@sa_repair_operation];
|
||||
};
|
||||
};
|
||||
description "";
|
||||
legacy none;
|
||||
parent @sa_repair;
|
||||
}
|
||||
|
||||
sa_function sa_reset "Reset valve remotely" id "09342ccb-044b-5483-ac58-87dc3cf7831c" {
|
||||
description "";
|
||||
parent @sa_restore_work;
|
||||
}
|
||||
|
||||
capability_involvement sa_assessment_support "Capability involvement: Assess an alarm" id "93eaad8d-83b7-5980-b9bb-86c9e3f31da4" {
|
||||
description "";
|
||||
source @sa_assess;
|
||||
target @sa_triage;
|
||||
}
|
||||
|
||||
functional_exchange sa_repair_request "Request field repair" id "93474111-f23e-56c1-b61b-b7c2396b91bd" {
|
||||
description "";
|
||||
items [@sa_repair_operation];
|
||||
source @sa_assess;
|
||||
source_port @sa_repair_request_out;
|
||||
target @sa_repair;
|
||||
target_port @sa_repair_request_in;
|
||||
}
|
||||
|
||||
functional_exchange sa_repair_report "Report repair result" id "684eadc3-e670-5779-a60f-bbc9a5bfb062" {
|
||||
description "";
|
||||
items [@sa_repair_operation];
|
||||
source @sa_repair;
|
||||
source_port @sa_repair_report_out;
|
||||
target @sa_confirm;
|
||||
target_port @sa_repair_report_in;
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
sa_exchange_category sa_contact_category "Field contact" id "781cbe75-410f-5cc5-aeb8-a43491f77b99" {
|
||||
description "";
|
||||
exchanges [@sa_contact];
|
||||
family "Participant";
|
||||
parent none;
|
||||
}
|
||||
|
||||
sa_event sa_high_pressure "Pressure alarm detected" id "01490fa8-2f01-5ac8-9722-d55d45414379" {
|
||||
body {
|
||||
Change {
|
||||
expression "measured_pressure > operating_limit";
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
sa_exchange_category sa_repair_traffic "Repair work exchanges" id "a9a47e48-100c-57a8-95f0-7fe24da94f94" {
|
||||
description "";
|
||||
exchanges [@sa_repair_request, @sa_repair_report];
|
||||
family "Work";
|
||||
parent none;
|
||||
}
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
sa_system sa_control "Pressure coordination service" id "435bf87c-73fd-5e4d-978a-4c471bc9eaf0" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
sa_port sa_control_port "Repair service client" id "98d411e7-7c65-5c3f-b543-8bf0f2522ea2" {
|
||||
contract {
|
||||
Component {
|
||||
kind Standard;
|
||||
orientation Unset;
|
||||
};
|
||||
};
|
||||
description "Explicitly chosen Standard component port for the repair service.";
|
||||
legacy none;
|
||||
parent @sa_control;
|
||||
}
|
||||
|
||||
sa_actor sa_technician "Field technician" id "c05b9422-b9da-5de5-b21d-07ad23bd2b8a" {
|
||||
description "";
|
||||
parent none;
|
||||
}
|
||||
|
||||
sa_port sa_technician_port "Repair service provider" id "e6d69cbd-99d7-596b-bbe3-dada6118a600" {
|
||||
contract {
|
||||
Component {
|
||||
kind Standard;
|
||||
orientation Unset;
|
||||
};
|
||||
};
|
||||
description "Explicitly chosen Standard component port for the repair service.";
|
||||
legacy none;
|
||||
parent @sa_technician;
|
||||
}
|
||||
|
||||
allocation sa_assess_allocation "Allocation: Assess pressure alarm" id "9b9356d7-2db2-5a94-a47e-ea892cf02afe" {
|
||||
description "";
|
||||
source @sa_control;
|
||||
target @sa_assess;
|
||||
}
|
||||
|
||||
allocation sa_audit_allocation "Allocation: Audit pressure thresholds" id "1b245065-7242-5d81-8472-aaeb932054c9" {
|
||||
description "";
|
||||
source @sa_control;
|
||||
target @sa_audit_thresholds;
|
||||
}
|
||||
|
||||
allocation sa_confirm_allocation "Allocation: Confirm safe pressure" id "b76bf8de-2fa4-563f-a540-dd30f30e6c49" {
|
||||
description "";
|
||||
source @sa_control;
|
||||
target @sa_confirm;
|
||||
}
|
||||
|
||||
interface_requirement sa_client_requires "Interface requirement: Valve repair service" id "4f85337b-f6eb-533c-a45a-9a5d1d9567ca" {
|
||||
description "";
|
||||
source @sa_control_port;
|
||||
target @sa_repair_interface;
|
||||
}
|
||||
|
||||
boundary_exchange sa_contact "Technician service conversation" id "63009b5f-539e-5914-b630-ec6b7fefb4d5" {
|
||||
description "";
|
||||
items [@sa_repair_operation];
|
||||
oriented false;
|
||||
source @sa_control_port;
|
||||
target @sa_technician_port;
|
||||
}
|
||||
|
||||
exchange_allocation sa_report_carriage "Exchange allocation: Report repair result" id "ff9897b3-a23a-5994-a5b3-99a5b4d34ceb" {
|
||||
description "";
|
||||
source @sa_contact;
|
||||
target @sa_repair_report;
|
||||
}
|
||||
|
||||
exchange_allocation sa_request_carriage "Exchange allocation: Request field repair" id "4c4c4851-5a3d-5bb9-94df-b19f9cf39819" {
|
||||
description "";
|
||||
source @sa_contact;
|
||||
target @sa_repair_request;
|
||||
}
|
||||
|
||||
port_allocation sa_port_report_in "Port allocation: Report repair result input" id "568c5c01-de21-52a2-83bd-afdddc158085" {
|
||||
description "";
|
||||
source @sa_control_port;
|
||||
target @sa_repair_report_in;
|
||||
}
|
||||
|
||||
port_allocation sa_port_request_out "Port allocation: Request field repair output" id "55ec4dbf-bd17-5b0c-b3a3-95b2194aa8b9" {
|
||||
description "";
|
||||
source @sa_control_port;
|
||||
target @sa_repair_request_out;
|
||||
}
|
||||
|
||||
mission_involvement sa_mission_participant "Mission involvement: Maintain safe water supply" id "1c1e5634-ba8c-591f-b143-90a27cdc6cd2" {
|
||||
description "";
|
||||
source @sa_control;
|
||||
target @sa_mission;
|
||||
}
|
||||
|
||||
allocation sa_reset_allocation "Allocation: Reset valve remotely" id "3cc9ab52-2b00-57fd-8709-aabc75e5d3e3" {
|
||||
description "";
|
||||
source @sa_control;
|
||||
target @sa_reset;
|
||||
}
|
||||
|
||||
allocation sa_repair_allocation "Allocation: Repair valve in the field" id "725f2e1b-aa2c-5615-9b1f-28da178168fa" {
|
||||
description "";
|
||||
source @sa_technician;
|
||||
target @sa_repair;
|
||||
}
|
||||
|
||||
port_allocation sa_port_report_out "Port allocation: Report repair result output" id "e53b7a40-e8a3-5b3f-826d-c2b5c164a84a" {
|
||||
description "";
|
||||
source @sa_technician_port;
|
||||
target @sa_repair_report_out;
|
||||
}
|
||||
|
||||
port_allocation sa_port_request_in "Port allocation: Request field repair input" id "09eaa992-4cdf-5ea3-b748-f10fd74b8cba" {
|
||||
description "";
|
||||
source @sa_technician_port;
|
||||
target @sa_repair_request_in;
|
||||
}
|
||||
|
||||
interface_provision sa_provider_provides "Interface provision: Valve repair service" id "55f89fbf-aa3c-5ae1-95ef-ac676f9c1ada" {
|
||||
description "";
|
||||
source @sa_technician_port;
|
||||
target @sa_repair_interface;
|
||||
}
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
sa_data_type sa_pressure "Measured pressure" id "87d0a95b-af1b-5352-b753-e4c6533671a5" {
|
||||
default none;
|
||||
definition {
|
||||
Real {
|
||||
maximum 600.0;
|
||||
minimum 0.0;
|
||||
};
|
||||
};
|
||||
description "";
|
||||
parent none;
|
||||
unit "kPa";
|
||||
}
|
||||
|
||||
sa_interface sa_repair_interface "Valve repair service" id "a4b8942e-a975-5f88-ad14-8f38c345baac" {
|
||||
description "";
|
||||
parent none;
|
||||
supertype none;
|
||||
}
|
||||
|
||||
sa_exchange_item sa_repair_operation "Valve repair" id "a962fc5e-3ab0-5296-8b0d-fd84633f9218" {
|
||||
description "";
|
||||
kind Information;
|
||||
mechanism Operation;
|
||||
parent none;
|
||||
supertype none;
|
||||
}
|
||||
|
||||
sa_data_field sa_pressure_parameter "Pressure before / after repair" id "bb12ba5d-aab5-5a1b-99de-c767f5365b57" {
|
||||
default none;
|
||||
description "";
|
||||
direction InOut;
|
||||
maximum 1;
|
||||
minimum 1;
|
||||
parent @sa_repair_operation;
|
||||
storage Value;
|
||||
type_ref {
|
||||
Named @sa_pressure;
|
||||
};
|
||||
unit "";
|
||||
}
|
||||
|
||||
interface_item_allocation sa_repair_interface_item "Repair operation contract" id "f074e041-23cf-54ad-af9c-f171e30621e7" {
|
||||
acquisition Accept;
|
||||
description "";
|
||||
order 0;
|
||||
source @sa_repair_interface;
|
||||
target @sa_repair_operation;
|
||||
transmission Synchronous;
|
||||
}
|
||||
|
||||
+1156
File diff suppressed because it is too large
Load Diff
+1198
File diff suppressed because it is too large
Load Diff
+114
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"communication_endpoints": [
|
||||
{
|
||||
"source": "27b47887-baf0-518b-bf87-f5acbf7d0b93",
|
||||
"source_port": {
|
||||
"Create": {
|
||||
"alias": "sa_control_port",
|
||||
"description": "Explicitly chosen Standard component port for the repair service.",
|
||||
"id": "98d411e7-7c65-5c3f-b543-8bf0f2522ea2",
|
||||
"kind": "Standard",
|
||||
"name": "Repair service client",
|
||||
"orientation": "Unset"
|
||||
}
|
||||
},
|
||||
"target_port": {
|
||||
"Create": {
|
||||
"alias": "sa_technician_port",
|
||||
"description": "Explicitly chosen Standard component port for the repair service.",
|
||||
"id": "e6d69cbd-99d7-596b-bbe3-dada6118a600",
|
||||
"kind": "Standard",
|
||||
"name": "Repair service provider",
|
||||
"orientation": "Unset"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"destination_diagram": null,
|
||||
"direction": "OaToSa",
|
||||
"fields": [],
|
||||
"mappings": [
|
||||
{
|
||||
"source": "32aa9940-df6e-5a12-b9bd-6337e2d2ed22",
|
||||
"target": "435bf87c-73fd-5e4d-978a-4c471bc9eaf0",
|
||||
"target_kind": null
|
||||
},
|
||||
{
|
||||
"source": "e07c3952-4a1a-5cc7-b7d5-03a01101ce49",
|
||||
"target": "c05b9422-b9da-5de5-b21d-07ad23bd2b8a",
|
||||
"target_kind": null
|
||||
}
|
||||
],
|
||||
"resolutions": [],
|
||||
"scope": "SelectedOnly",
|
||||
"sources": [
|
||||
"022d3cfa-bbaf-5e13-924a-8e55099b8745",
|
||||
"0b07b9ed-492d-57f6-b0b1-ce8a709238a7",
|
||||
"1970608f-85d1-5234-ac86-5e2b0df27dc3",
|
||||
"19bd3a3a-4d0c-56d5-bf50-a6b43fd81771",
|
||||
"1b91f8a7-0bdb-514e-b1cd-955658e09927",
|
||||
"2011b3ac-614b-5a47-8891-7ff81965f425",
|
||||
"20472233-5ce6-5ffe-b4ad-0bdbccf3e423",
|
||||
"32aa9940-df6e-5a12-b9bd-6337e2d2ed22",
|
||||
"3dfee23a-148b-5cec-ad2d-b774e84ea5bb",
|
||||
"41859a65-ded2-547b-ab03-14e2fa740cf9",
|
||||
"58bae2b0-f560-50f2-818d-19091d22d18a",
|
||||
"58c15833-6e75-523a-b57f-a88f19f6d672",
|
||||
"5ba8079c-2dbe-5e98-ae82-2b60c6020a02",
|
||||
"5d3af417-244c-54bb-9588-16daedda4e1f",
|
||||
"61f7bbfb-74a4-5540-9182-2583dfb27a49",
|
||||
"65d6b8d6-271a-5c84-8b42-abbe310c955e",
|
||||
"6a30b763-cc51-546d-907f-5c63657cfd03",
|
||||
"6b945a6d-6aa0-5dd3-96e6-2e8d757d167d",
|
||||
"6cbde0d8-9f5f-510a-a8c1-e29cb99ad4ae",
|
||||
"727c0b5c-8db6-5eb7-83d6-735519c5949f",
|
||||
"8412e9c6-96fe-5ed6-a903-1d37ec3c3bf7",
|
||||
"8bc6d0a4-3e87-559b-8bd7-1b679a2db5b7",
|
||||
"9349b353-53f2-56f8-b571-a05b09335cdf",
|
||||
"942975b8-0bef-5ae8-9fcb-c37497833fb0",
|
||||
"9ff94014-afa1-50ab-a4d3-8e9dd0565cc5",
|
||||
"a21465af-05f3-5fb5-8983-de26932422fb",
|
||||
"a7ffb869-9dde-5e76-b276-c719c5c143a9",
|
||||
"b280c6ca-e5f9-5424-a5c1-5676e01c2371",
|
||||
"b97437c6-cd7a-5a05-b537-b30a17dd936a",
|
||||
"c59432fe-6092-5ee0-908d-9dbf39476471",
|
||||
"c9c61f50-06e0-5d17-973d-dcc57cd5cc90",
|
||||
"cc2d497a-fd15-5455-9ee5-e70eb95811d8",
|
||||
"d0c8be87-d238-503a-a549-7558a210507f",
|
||||
"d2026fc2-74a8-5e22-9942-ff3eb68a3677",
|
||||
"d6f881a4-95da-54e9-ad97-1b8965532629",
|
||||
"d736c7d6-d369-550a-8ba4-dae223e40bb3",
|
||||
"df2fd3f8-6bc2-5380-a13f-36643ed35ac7",
|
||||
"e00594a3-6122-5a6b-b3c2-ecb5506c741d",
|
||||
"e07c3952-4a1a-5cc7-b7d5-03a01101ce49",
|
||||
"e7824764-5db9-5384-8198-2fbaea2b10b2",
|
||||
"fc6763bf-a534-54bf-afcd-57ab285ff07d",
|
||||
"fc81c5f0-0442-5b88-992b-e5b10f351c59",
|
||||
"fffff882-78fd-5415-928d-c1ef7fac6576",
|
||||
"0c4c9e58-ff32-5c00-b82a-d408a4be0183",
|
||||
"109e2d6b-7e86-5934-93a5-fab56eced84e",
|
||||
"1853df1f-30f4-5b1a-baac-2dcaf73c7b3a",
|
||||
"1f8b1898-65f6-5360-99cf-b78a71bd50ec",
|
||||
"21fe5e8e-cbc2-5dad-b3e8-1df46e167d97",
|
||||
"229ee94f-d147-50f6-9769-b5bd0c03a084",
|
||||
"27b47887-baf0-518b-bf87-f5acbf7d0b93",
|
||||
"2b00270c-79a5-52a5-af96-33346bea531b",
|
||||
"3f54d890-4ca5-5e36-873b-abb5c92d578c",
|
||||
"594c61cd-94e0-5c07-890d-edfd520d7df9",
|
||||
"628cb4fc-fe63-5f6b-b364-6268f26b5740",
|
||||
"76218d89-68fd-531d-b35b-90c5b769a5ef",
|
||||
"7fa37e63-db65-5aa7-88f2-31ff4347a787",
|
||||
"ae53f363-0dec-5a7c-9afd-8fcd1b778ab2",
|
||||
"b436d0b3-c824-5a96-af6b-2c269816d1cc",
|
||||
"bac43d3b-910b-5bdc-be9b-f78cf973e1ed",
|
||||
"bfd4326e-ea65-5269-b5e6-e063a355d1e9",
|
||||
"c1adbbd0-a762-5ee3-8b9a-5c18af377771",
|
||||
"c7c248f8-28b8-55be-9023-0991d44021e3",
|
||||
"c8196d35-2168-5fef-8b03-ba0d139bc00f",
|
||||
"c8593670-8906-530f-b6a2-3ada77a9c219",
|
||||
"cf423ea2-8b2e-5a27-93d4-5e8542d9db8d",
|
||||
"e21d9a54-ae8e-5618-a4f8-67ee22b92638",
|
||||
"fbde9d5e-c7e9-55db-a2be-497345c491b3",
|
||||
"ffdbfcd0-d423-5707-a880-0dfbe1400f72"
|
||||
]
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
diagram oa_allocation_view "1 · OA responsibility and repair traffic" id "103ea62c-ac56-5827-94e7-cf09bca96ccc" {
|
||||
description "Teaching view: positions and filters do not change ownership or exchange identities.";
|
||||
layer Oa;
|
||||
projection Allocation;
|
||||
routes [];
|
||||
view_options {
|
||||
coverage "All";
|
||||
exchange_labels "Name";
|
||||
hidden_edges [];
|
||||
participant_categories "All";
|
||||
relation_kinds "All";
|
||||
work_categories "All";
|
||||
work_contexts "All";
|
||||
};
|
||||
}
|
||||
|
||||
node oa_allocation_view_oa_assess id "5ae1c46d-59a3-50fd-8cc3-b292df21f951" {
|
||||
collapsed false;
|
||||
diagram @oa_allocation_view;
|
||||
element @oa_assess;
|
||||
position {
|
||||
x 100.0;
|
||||
y 170.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node oa_allocation_view_oa_confirm id "edd74060-ac61-5450-a57c-a6577daa5d50" {
|
||||
collapsed false;
|
||||
diagram @oa_allocation_view;
|
||||
element @oa_confirm;
|
||||
position {
|
||||
x 100.0;
|
||||
y 490.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node oa_allocation_view_oa_control id "3191e05c-1c7f-5f0e-beb0-5f3bded54c48" {
|
||||
collapsed false;
|
||||
diagram @oa_allocation_view;
|
||||
element @oa_control;
|
||||
position {
|
||||
x 60.0;
|
||||
y 80.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node oa_allocation_view_oa_repair id "202ebe37-ddb4-5099-8ce9-ec3e895ab9e9" {
|
||||
collapsed false;
|
||||
diagram @oa_allocation_view;
|
||||
element @oa_repair;
|
||||
position {
|
||||
x 890.0;
|
||||
y 170.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node oa_allocation_view_oa_reset id "7066f78c-9736-5349-b94a-0587331b980e" {
|
||||
collapsed false;
|
||||
diagram @oa_allocation_view;
|
||||
element @oa_reset;
|
||||
position {
|
||||
x 100.0;
|
||||
y 330.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node oa_allocation_view_oa_technician id "d27f28ef-f10a-5355-9a05-6f2fd39b7de6" {
|
||||
collapsed false;
|
||||
diagram @oa_allocation_view;
|
||||
element @oa_technician;
|
||||
position {
|
||||
x 850.0;
|
||||
y 80.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
diagram sa_allocation_view "2 · SA service boundary and functions" id "35d3c24b-289e-59e5-a610-8333e2c6a4bb" {
|
||||
description "Teaching view: positions and filters do not change ownership or exchange identities.";
|
||||
layer Sa;
|
||||
projection Allocation;
|
||||
routes [];
|
||||
view_options {
|
||||
coverage "All";
|
||||
exchange_labels "Name";
|
||||
hidden_edges [];
|
||||
participant_categories "All";
|
||||
relation_kinds "All";
|
||||
work_categories "All";
|
||||
work_contexts "All";
|
||||
};
|
||||
}
|
||||
|
||||
node sa_allocation_view_sa_assess id "60f6ad74-b69e-5aef-b832-f1bd60b903ae" {
|
||||
collapsed false;
|
||||
diagram @sa_allocation_view;
|
||||
element @sa_assess;
|
||||
position {
|
||||
x 100.0;
|
||||
y 170.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_allocation_view_sa_confirm id "7e3ba36f-bc68-5520-bdb9-77083bb7bba2" {
|
||||
collapsed false;
|
||||
diagram @sa_allocation_view;
|
||||
element @sa_confirm;
|
||||
position {
|
||||
x 100.0;
|
||||
y 490.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_allocation_view_sa_control id "8345c76a-8d85-5c31-902e-ec1cd33ed4a3" {
|
||||
collapsed false;
|
||||
diagram @sa_allocation_view;
|
||||
element @sa_control;
|
||||
position {
|
||||
x 60.0;
|
||||
y 80.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_allocation_view_sa_repair id "34630a18-41b0-5fdd-bff4-ee86e93e8651" {
|
||||
collapsed false;
|
||||
diagram @sa_allocation_view;
|
||||
element @sa_repair;
|
||||
position {
|
||||
x 890.0;
|
||||
y 170.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_allocation_view_sa_reset id "73406244-ebd7-5995-86c7-e17c73c50b32" {
|
||||
collapsed false;
|
||||
diagram @sa_allocation_view;
|
||||
element @sa_reset;
|
||||
position {
|
||||
x 100.0;
|
||||
y 330.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_allocation_view_sa_technician id "f7225d1c-e506-505d-bb20-916950269d4b" {
|
||||
collapsed false;
|
||||
diagram @sa_allocation_view;
|
||||
element @sa_technician;
|
||||
position {
|
||||
x 850.0;
|
||||
y 80.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
diagram sa_capability_view "4 · SA mission and included capability" id "3e6ad194-61b5-584c-b0f0-a78a20af5781" {
|
||||
description "Teaching view: positions and filters do not change ownership or exchange identities.";
|
||||
layer Sa;
|
||||
projection Capabilities;
|
||||
routes [];
|
||||
view_options {
|
||||
coverage "All";
|
||||
exchange_labels "Name";
|
||||
hidden_edges [];
|
||||
participant_categories "All";
|
||||
relation_kinds "All";
|
||||
work_categories "All";
|
||||
work_contexts "All";
|
||||
};
|
||||
}
|
||||
|
||||
node sa_capability_view_sa_control id "41ddb68b-bd2b-5f91-82eb-efde01157828" {
|
||||
collapsed false;
|
||||
diagram @sa_capability_view;
|
||||
element @sa_control;
|
||||
position {
|
||||
x 60.0;
|
||||
y 60.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_capability_view_sa_mission id "4b814335-bf98-5b68-85d5-ea549766517a" {
|
||||
collapsed false;
|
||||
diagram @sa_capability_view;
|
||||
element @sa_mission;
|
||||
position {
|
||||
x 420.0;
|
||||
y 60.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_capability_view_sa_restore id "d3bc13f9-7726-5280-83fe-63f391c45afb" {
|
||||
collapsed false;
|
||||
diagram @sa_capability_view;
|
||||
element @sa_restore;
|
||||
position {
|
||||
x 420.0;
|
||||
y 260.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_capability_view_sa_triage id "069a3fb3-077c-59d8-91da-27b0665143c7" {
|
||||
collapsed false;
|
||||
diagram @sa_capability_view;
|
||||
element @sa_triage;
|
||||
position {
|
||||
x 800.0;
|
||||
y 260.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
diagram sa_service_view "3 · SA service conversation only" id "50af4c9b-93ce-5ff5-a1f8-7a81eb97e779" {
|
||||
description "Teaching view: positions and filters do not change ownership or exchange identities.";
|
||||
layer Sa;
|
||||
projection Allocation;
|
||||
routes [];
|
||||
view_options {
|
||||
coverage "All";
|
||||
exchange_labels "NameAndItems";
|
||||
hidden_edges [];
|
||||
participant_categories {
|
||||
Any [@sa_contact_category];
|
||||
};
|
||||
relation_kinds "All";
|
||||
work_categories {
|
||||
Any [];
|
||||
};
|
||||
work_contexts "All";
|
||||
};
|
||||
}
|
||||
|
||||
node sa_service_view_sa_assess id "439f1e45-e5ed-567c-978b-4c93ef267db1" {
|
||||
collapsed false;
|
||||
diagram @sa_service_view;
|
||||
element @sa_assess;
|
||||
position {
|
||||
x 100.0;
|
||||
y 170.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_service_view_sa_confirm id "6f138672-149b-5f88-ab07-7fc413a42262" {
|
||||
collapsed false;
|
||||
diagram @sa_service_view;
|
||||
element @sa_confirm;
|
||||
position {
|
||||
x 100.0;
|
||||
y 490.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_service_view_sa_control id "f53d4352-b042-56a6-8b3e-c51cd27254f9" {
|
||||
collapsed false;
|
||||
diagram @sa_service_view;
|
||||
element @sa_control;
|
||||
position {
|
||||
x 60.0;
|
||||
y 80.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_service_view_sa_repair id "ae36489d-6ec8-5f1c-b603-8b497227efba" {
|
||||
collapsed false;
|
||||
diagram @sa_service_view;
|
||||
element @sa_repair;
|
||||
position {
|
||||
x 890.0;
|
||||
y 170.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_service_view_sa_reset id "d52da4e6-40b7-5dbc-84fb-80c443711c69" {
|
||||
collapsed false;
|
||||
diagram @sa_service_view;
|
||||
element @sa_reset;
|
||||
position {
|
||||
x 100.0;
|
||||
y 330.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_service_view_sa_technician id "40210589-69f7-5209-b329-10bb83cf615c" {
|
||||
collapsed false;
|
||||
diagram @sa_service_view;
|
||||
element @sa_technician;
|
||||
position {
|
||||
x 850.0;
|
||||
y 80.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
diagram sa_state_view "5 · SA pressure supervision" id "30d5baf9-6581-5cb6-846a-bcaa1e6cce63" {
|
||||
description "Teaching view: positions and filters do not change ownership or exchange identities.";
|
||||
layer Sa;
|
||||
projection {
|
||||
StateMachine {
|
||||
machine @sa_monitor;
|
||||
};
|
||||
};
|
||||
routes [];
|
||||
view_options {
|
||||
coverage "All";
|
||||
exchange_labels "Name";
|
||||
hidden_edges [];
|
||||
participant_categories "All";
|
||||
relation_kinds "All";
|
||||
work_categories "All";
|
||||
work_contexts "All";
|
||||
};
|
||||
}
|
||||
|
||||
node sa_state_view_sa_monitor id "a676fbb9-0833-59a8-98cf-a10d8f4b7434" {
|
||||
collapsed false;
|
||||
diagram @sa_state_view;
|
||||
element @sa_monitor;
|
||||
position {
|
||||
x 30.0;
|
||||
y 30.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_state_view_sa_monitor_initial id "5e2326a0-0f6c-5f8d-8a21-fdded18a9281" {
|
||||
collapsed false;
|
||||
diagram @sa_state_view;
|
||||
element @sa_monitor_initial;
|
||||
position {
|
||||
x 100.0;
|
||||
y 200.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_state_view_sa_monitor_region id "55a74f91-2025-5001-8db8-9566b1dbe783" {
|
||||
collapsed false;
|
||||
diagram @sa_state_view;
|
||||
element @sa_monitor_region;
|
||||
position {
|
||||
x 70.0;
|
||||
y 95.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_state_view_sa_monitoring id "b3af7b04-5a45-5b82-ab69-7eada4b876f0" {
|
||||
collapsed false;
|
||||
diagram @sa_state_view;
|
||||
element @sa_monitoring;
|
||||
position {
|
||||
x 220.0;
|
||||
y 200.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
node sa_state_view_sa_waiting id "57acbb71-ca86-57fc-ae90-42dad195f0e0" {
|
||||
collapsed false;
|
||||
diagram @sa_state_view;
|
||||
element @sa_waiting;
|
||||
position {
|
||||
x 650.0;
|
||||
y 200.0;
|
||||
};
|
||||
size {
|
||||
height 110.0;
|
||||
width 245.0;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user