From d130013155eb514c0208e1b93f1e0a1c41dc286e Mon Sep 17 00:00:00 2001
From: "sorokin.oleg.edu"
Date: Sun, 6 Sep 2026 05:46:51 +0300
Subject: [PATCH] feat(server): expose typed semantic transition review
---
crates/oa-server/src/routes.rs | 170 +
crates/oa-server/tests/http.rs | 2 +
.../tests/http/semantic_transitions.rs | 675 +++
.../oa-server/tests/semantic_http_contract.py | 136 +
crates/oa-server/tests/semantic_schema.py | 205 +
docs/api.html | 120 +-
docs/api.rst | 130 +-
docs/openapi.json | 5136 ++++++++++++++++-
8 files changed, 6555 insertions(+), 19 deletions(-)
create mode 100644 crates/oa-server/tests/http/semantic_transitions.rs
create mode 100644 crates/oa-server/tests/semantic_http_contract.py
create mode 100644 crates/oa-server/tests/semantic_schema.py
diff --git a/crates/oa-server/src/routes.rs b/crates/oa-server/src/routes.rs
index e05b778d..69599141 100644
--- a/crates/oa-server/src/routes.rs
+++ b/crates/oa-server/src/routes.rs
@@ -72,6 +72,18 @@ pub(crate) fn router() -> Router {
"/api/v1/projects/{id}/transitions/apply",
post(commit_transition),
)
+ .route(
+ "/api/v1/projects/{id}/semantic-transitions/query",
+ post(query_semantic_transitions),
+ )
+ .route(
+ "/api/v1/projects/{id}/semantic-transitions/preview",
+ post(preview_semantic_transition),
+ )
+ .route(
+ "/api/v1/projects/{id}/semantic-transitions/apply",
+ post(commit_semantic_transition),
+ )
.fallback(|| async {
ApiError::new(
StatusCode::NOT_FOUND,
@@ -1089,6 +1101,164 @@ struct TransitionApplyRequest {
plan: oa_core::transitions::TransitionPlan,
}
+#[derive(Deserialize)]
+#[serde(deny_unknown_fields)]
+struct SemanticQueryRequest {
+ traces: Vec,
+ #[serde(default)]
+ references: BTreeMap,
+ revision: Option,
+}
+
+fn semantic_rejected(error: impl std::fmt::Display) -> ApiError {
+ ApiError::new(
+ StatusCode::UNPROCESSABLE_ENTITY,
+ "semantic_transition_rejected",
+ error.to_string(),
+ )
+}
+
+async fn query_semantic_transitions(
+ State(state): State,
+ id: ProjectPath,
+ headers: HeaderMap,
+ body: Body,
+) -> ApiResult {
+ let id = path(id)?;
+ media(&headers, "application/json")?;
+ let body = bytes(body)?;
+ blocking(state, move |store| {
+ let request: SemanticQueryRequest = json_body(&body)?;
+ if request.traces.is_empty() || request.traces.len() > 100 || request.references.len() > 5_000 {
+ return Err(ApiError::bad_request("Semantic queries require 1–100 trace IDs and at most 5,000 reference mappings."));
+ }
+ let selected: BTreeSet<_> = request.traces.iter().copied().collect();
+ if selected.len() != request.traces.len() {
+ return Err(ApiError::bad_request("Semantic query trace IDs must be unique."));
+ }
+ let current = store.get(id)?;
+ check_read_revision(¤t, request.revision)?;
+ let mut items = Vec::new();
+ for trace_id in request.traces {
+ let trace = current.model.traces.get(&trace_id).ok_or_else(|| {
+ ApiError::new(StatusCode::NOT_FOUND, "trace_not_found", "Selected trace does not exist.")
+ })?;
+ let facets = oa_core::semantic::semantic_facets(¤t.model, trace, &request.references)
+ .map_err(semantic_rejected)?;
+ let drift = oa_core::semantic::trace_semantic_drift(¤t.model, trace, &request.references)
+ .map_err(semantic_rejected)?;
+ let linked_impacts = oa_core::semantic::linked_semantic_impacts(¤t.model, trace, &request.references)
+ .map_err(semantic_rejected)?;
+ items.push(json!({"trace":trace.id,"oa":trace.oa,"sa":trace.sa,"facets":facets,"drift":drift,"linked_impacts":linked_impacts}));
+ }
+ Ok(response(¤t, StatusCode::OK, json!({"revision":current.revision,"items":items})))
+ }).await
+}
+
+fn check_semantic_request(request: &oa_core::semantic::SemanticTransitionRequest) -> ApiResult<()> {
+ let transition = &request.transition;
+ let decisions = request.reviews.iter().try_fold(0usize, |count, review| {
+ count
+ .checked_add(review.resolutions.len())?
+ .checked_add(review.reset.len())
+ });
+ if transition.sources.len() > 100
+ || transition.mappings.len() > 200
+ || transition.resolutions.len() > 400
+ || request.traces.len() > 100
+ || request.references.len() > 5_000
+ || request.reviews.len() > 100
+ || decisions.is_none_or(|count| count > 5_000)
+ || request.candidates.len() > 200
+ || request.accepted_impacts.len() > 200
+ {
+ return Err(ApiError::bad_request(
+ "Semantic transitions allow at most 100 sources/traces/reviews, 200 mappings/candidates/accepted impacts, 400 prose resolutions and 5,000 reference mappings or combined facet resolutions/resets.",
+ ));
+ }
+ Ok(())
+}
+
+async fn preview_semantic_transition(
+ State(state): State,
+ id: ProjectPath,
+ headers: HeaderMap,
+ body: Body,
+) -> ApiResult {
+ let id = path(id)?;
+ let expected = expected(&headers)?;
+ media(&headers, "application/json")?;
+ let body = bytes(body)?;
+ blocking(state, move |store| {
+ let request: oa_core::semantic::SemanticTransitionRequest = json_body(&body)?;
+ check_semantic_request(&request)?;
+ let current = store.checked(id, &expected)?;
+ let plan = oa_core::semantic::plan_semantic_transition(¤t.model, request)
+ .map_err(semantic_rejected)?;
+ if !plan.commands.is_empty() {
+ check_commands(&plan.commands)?;
+ }
+ if plan.conflicts.is_empty() {
+ let candidate = oa_core::semantic::prepare_semantic_transition(¤t.model, &plan)
+ .map_err(semantic_rejected)?;
+ PreparedProject::from_command(¤t, candidate)?;
+ }
+ Ok(response(
+ ¤t,
+ StatusCode::OK,
+ json!({"base_revision":current.revision,"plan":plan}),
+ ))
+ })
+ .await
+}
+
+#[derive(Deserialize)]
+#[serde(deny_unknown_fields)]
+struct SemanticApplyRequest {
+ base_revision: u64,
+ plan: oa_core::semantic::SemanticTransitionPlan,
+}
+
+async fn commit_semantic_transition(
+ State(state): State,
+ id: ProjectPath,
+ headers: HeaderMap,
+ body: Body,
+) -> ApiResult {
+ let id = path(id)?;
+ let expected = expected(&headers)?;
+ media(&headers, "application/json")?;
+ let body = bytes(body)?;
+ blocking(state, move |store| {
+ let request: SemanticApplyRequest = json_body(&body)?;
+ let current = store.checked(id, &expected)?;
+ if current.revision != request.base_revision {
+ let mut error = ApiError::new(
+ StatusCode::PRECONDITION_FAILED,
+ "plan_revision_conflict",
+ "Semantic preview revision changed. Create a new preview.",
+ );
+ error.current_revision = Some(current.revision);
+ return Err(error);
+ }
+ check_semantic_request(&request.plan.request)?;
+ if !request.plan.commands.is_empty() {
+ check_commands(&request.plan.commands)?;
+ }
+ let candidate =
+ oa_core::semantic::prepare_semantic_transition(¤t.model, &request.plan)
+ .map_err(semantic_rejected)?;
+ let prepared = PreparedProject::from_command(¤t, candidate)?;
+ let (stored, changed) = store.replace(id, &expected, prepared)?;
+ Ok(response(
+ &stored,
+ StatusCode::OK,
+ json!({"revision":stored.revision,"changed":changed,"issues":issues(&stored.model)}),
+ ))
+ })
+ .await
+}
+
async fn commit_transition(
State(state): State,
id: ProjectPath,
diff --git a/crates/oa-server/tests/http.rs b/crates/oa-server/tests/http.rs
index f3c9663b..99e2ca7f 100644
--- a/crates/oa-server/tests/http.rs
+++ b/crates/oa-server/tests/http.rs
@@ -14,6 +14,8 @@ mod data_contracts;
mod port_anchors;
#[path = "http/source_projects.rs"]
mod source_projects;
+#[path = "http/semantic_transitions.rs"]
+mod semantic_transitions;
fn v2_missing_ports() -> Value {
let mut old: Value = serde_json::from_slice(include_bytes!(
diff --git a/crates/oa-server/tests/http/semantic_transitions.rs b/crates/oa-server/tests/http/semantic_transitions.rs
new file mode 100644
index 00000000..cd1d8365
--- /dev/null
+++ b/crates/oa-server/tests/http/semantic_transitions.rs
@@ -0,0 +1,675 @@
+use super::*;
+use oa_core::{semantic::*, transitions::*, *};
+
+fn fixture() -> Project {
+ oa_core::persistence::decode(include_bytes!(
+ "../../../oa-core/tests/fixtures/v4-reviewed-prose.json"
+ ))
+ .unwrap()
+}
+fn key(n: u128) -> Id {
+ Id::from_u128(0x40000000_0000_4000_8000_000000000000 + n)
+}
+fn request(
+ source: Id,
+ target: Id,
+ decisions: Vec<(FacetSelector, SemanticDecision)>,
+) -> SemanticTransitionRequest {
+ let direction = if source == key(3) {
+ TransitionDirection::SaToOa
+ } else {
+ TransitionDirection::OaToSa
+ };
+ let mut transition = TransitionRequest::new(direction, vec![source]);
+ transition.mappings.push(TransitionMapping {
+ source,
+ target: Some(target),
+ target_kind: None,
+ });
+ let mut request = SemanticTransitionRequest::new(transition);
+ request.reviews.push(SemanticReviewRequest {
+ source,
+ resolutions: decisions
+ .into_iter()
+ .map(|(facet, decision)| FacetResolution { facet, decision })
+ .collect(),
+ reset: vec![],
+ });
+ request
+}
+async fn post(
+ server: &TestServer,
+ id: Id,
+ operation: &str,
+ etag: Option<&str>,
+ value: &impl serde::Serialize,
+) -> reqwest::Response {
+ let mut call = server
+ .client
+ .post(server.url(&format!("/projects/{id}/semantic-transitions/{operation}")))
+ .json(value);
+ if let Some(etag) = etag {
+ call = call.header("if-match", etag);
+ }
+ call.send().await.unwrap()
+}
+async fn ok(response: reqwest::Response) -> Value {
+ let status = response.status();
+ let value = response.json().await.unwrap();
+ assert_eq!(status, StatusCode::OK, "{value}");
+ value
+}
+async fn preview(
+ server: &TestServer,
+ stored: &StoredProject,
+ request: &SemanticTransitionRequest,
+) -> Value {
+ ok(post(
+ server,
+ stored.resource_id,
+ "preview",
+ Some(&stored.etag()),
+ request,
+ )
+ .await)
+ .await
+}
+fn assert_pair(stored: &StoredProject) {
+ assert_eq!(
+ oa_core::source_project::compile_bundle(&stored.source_project, Default::default())
+ .unwrap()
+ .decoded
+ .project,
+ stored.model
+ );
+}
+
+#[tokio::test]
+async fn semantic_partial_review_query_source_and_restart_share_one_revision() {
+ let directory = tempfile::tempdir().unwrap();
+ let server = TestServer::start(directory.path(), None).await;
+ let (id, _) = server.import(&fixture()).await;
+ let mut stored = server.get(id).await;
+ let mut bundle = stored.source_project.clone();
+ bundle
+ .files
+ .get_mut(&bundle.entry)
+ .unwrap()
+ .insert_str(0, "// Authored review rationale\n");
+ let changed = server
+ .client
+ .put(server.url(&format!("/projects/{id}/source-project")))
+ .header("if-match", stored.etag())
+ .json(&bundle)
+ .send()
+ .await
+ .unwrap();
+ assert_eq!(changed.status(), StatusCode::OK);
+ stored = server.get(id).await;
+ let disk_path = directory.path().join(format!("{id}.json"));
+ let before_bytes = std::fs::read(&disk_path).unwrap();
+ let query = json!({"traces":[key(4)],"references":{},"revision":stored.revision});
+ let queried = ok(post(&server, id, "query", None, &query).await).await;
+ assert_eq!(queried["items"][0]["drift"]["own"], "Unreviewed");
+ let req = request(
+ key(2),
+ key(3),
+ vec![
+ (
+ FacetSelector::Data(DataFacet::Unit),
+ SemanticDecision::KeepTarget,
+ ),
+ (
+ FacetSelector::Header(HeaderFacet::Name),
+ SemanticDecision::TakeSource,
+ ),
+ ],
+ );
+ let plan = preview(&server, &stored, &req).await;
+ assert_eq!(plan["plan"]["conflicts"], json!([]));
+ assert_eq!(
+ plan["plan"]["reviews"][0]["acknowledged"]
+ .as_array()
+ .unwrap()
+ .len(),
+ 2
+ );
+ assert_eq!(std::fs::read(&disk_path).unwrap(), before_bytes);
+ assert_eq!(server.get(id).await.etag(), stored.etag());
+ let applied = ok(post(&server, id, "apply", Some(&stored.etag()), &plan).await).await;
+ assert_eq!(applied["revision"], stored.revision + 1);
+ let committed = server.get(id).await;
+ assert_pair(&committed);
+ assert!(
+ committed.source_project.files[&committed.source_project.entry]
+ .contains("// Authored review rationale")
+ );
+ assert_eq!(committed.model.elements[&key(3)].name, "OA dimension now");
+ assert!(
+ matches!(committed.model.elements[&key(3)].shared(), Some(SharedBody::DataType { unit, definition: DataTypeDefinition::Real { .. }, .. }) if unit == "ft")
+ );
+ let queried = ok(post(&server, id, "query", None, &json!({"traces":[key(4)]})).await).await;
+ let facts: Vec =
+ serde_json::from_value(queried["items"][0]["facets"].clone()).unwrap();
+ assert_eq!(
+ facts
+ .iter()
+ .find(|f| f.selector == FacetSelector::Data(DataFacet::Unit))
+ .unwrap()
+ .drift,
+ Drift::Unchanged
+ );
+ assert_eq!(
+ facts
+ .iter()
+ .find(|f| f.selector == FacetSelector::Data(DataFacet::Constructor))
+ .unwrap()
+ .drift,
+ Drift::Unreviewed
+ );
+ assert!(
+ queried["items"][0]["drift"]["own_unreviewed"]
+ .as_bool()
+ .unwrap()
+ );
+ let repeat = preview(&server, &committed, &req).await;
+ let reapplied = ok(post(&server, id, "apply", Some(&committed.etag()), &repeat).await).await;
+ assert_eq!(reapplied["changed"], false);
+ assert_eq!(reapplied["revision"], committed.revision);
+ server.stop().await;
+ let server = TestServer::start(directory.path(), None).await;
+ let reopened = server.get(id).await;
+ assert_eq!(reopened.model, committed.model);
+ assert_eq!(reopened.source_project, committed.source_project);
+ assert_eq!(reopened.etag(), committed.etag());
+ server.stop().await;
+}
+
+#[tokio::test]
+async fn semantic_strict_rejection_stale_plans_and_source_only_changes_never_write() {
+ let directory = tempfile::tempdir().unwrap();
+ let server = TestServer::start(directory.path(), None).await;
+ let (id, etag) = server.import(&fixture()).await;
+ let stored = server.get(id).await;
+ let disk_path = directory.path().join(format!("{id}.json"));
+ let before = std::fs::read(&disk_path).unwrap();
+ let req = request(
+ key(2),
+ key(3),
+ vec![(
+ FacetSelector::Data(DataFacet::Unit),
+ SemanticDecision::TakeSource,
+ )],
+ );
+ let plan = preview(&server, &stored, &req).await;
+ for operation in ["preview", "apply"] {
+ let body = if operation == "preview" {
+ serde_json::to_value(&req).unwrap()
+ } else {
+ plan.clone()
+ };
+ assert_eq!(
+ post(&server, id, operation, None, &body).await.status(),
+ StatusCode::PRECONDITION_REQUIRED
+ );
+ }
+ let mut malformed = serde_json::to_value(&req).unwrap();
+ malformed["reviews"][0]["resolutions"][0]["facet"] = json!({"Data":"arbitrary_path"});
+ assert_eq!(
+ post(&server, id, "preview", Some(&etag), &malformed)
+ .await
+ .status(),
+ StatusCode::BAD_REQUEST
+ );
+ malformed = serde_json::to_value(&req).unwrap();
+ malformed["unexpected"] = true.into();
+ assert_eq!(
+ post(&server, id, "preview", Some(&etag), &malformed)
+ .await
+ .status(),
+ StatusCode::BAD_REQUEST
+ );
+ for (query, expected) in [
+ (json!({"traces":[]}), StatusCode::BAD_REQUEST),
+ (json!({"traces":[key(4),key(4)]}), StatusCode::BAD_REQUEST),
+ (json!({"traces":[key(99)]}), StatusCode::NOT_FOUND),
+ (
+ json!({"traces":[key(4)],"revision":99}),
+ StatusCode::CONFLICT,
+ ),
+ ] {
+ assert_eq!(
+ post(&server, id, "query", None, &query).await.status(),
+ expected
+ );
+ }
+ for mutation in [
+ "commands",
+ "base_fingerprint",
+ "prepared_fingerprint",
+ "base_revision",
+ ] {
+ let mut rejected = plan.clone();
+ let expected = if mutation == "base_revision" {
+ rejected[mutation] = 99.into();
+ StatusCode::PRECONDITION_FAILED
+ } else {
+ rejected["plan"][mutation] = if mutation == "commands" {
+ json!([])
+ } else {
+ json!("altered")
+ };
+ StatusCode::UNPROCESSABLE_ENTITY
+ };
+ assert_eq!(
+ post(&server, id, "apply", Some(&etag), &rejected)
+ .await
+ .status(),
+ expected
+ );
+ }
+ let mut duplicate = req.clone();
+ let repeated = duplicate.reviews[0].resolutions[0].clone();
+ duplicate.reviews[0].resolutions.push(repeated);
+ let conflicted = preview(&server, &stored, &duplicate).await;
+ assert!(
+ !conflicted["plan"]["conflicts"]
+ .as_array()
+ .unwrap()
+ .is_empty()
+ );
+ assert_eq!(
+ post(&server, id, "apply", Some(&etag), &conflicted)
+ .await
+ .status(),
+ StatusCode::UNPROCESSABLE_ENTITY
+ );
+ assert_eq!(std::fs::read(&disk_path).unwrap(), before);
+ assert_eq!(server.get(id).await.etag(), etag);
+ let mut bundle = stored.source_project.clone();
+ bundle
+ .files
+ .get_mut(&bundle.entry)
+ .unwrap()
+ .push_str("\n// Source-only concurrent edit\n");
+ let changed = server
+ .client
+ .put(server.url(&format!("/projects/{id}/source-project")))
+ .header("if-match", &etag)
+ .json(&bundle)
+ .send()
+ .await
+ .unwrap();
+ assert_eq!(changed.status(), StatusCode::OK);
+ let current = server.get(id).await;
+ assert_eq!(current.model, stored.model);
+ let bytes = std::fs::read(&disk_path).unwrap();
+ for precondition in [&etag, ¤t.etag()] {
+ assert_eq!(
+ post(&server, id, "apply", Some(precondition), &plan)
+ .await
+ .status(),
+ StatusCode::PRECONDITION_FAILED
+ );
+ }
+ assert_eq!(std::fs::read(&disk_path).unwrap(), bytes);
+ server.stop().await;
+}
+
+#[tokio::test]
+async fn semantic_candidate_constructor_reverse_direction_and_explicit_trace_selection() {
+ let directory = tempfile::tempdir().unwrap();
+ let server = TestServer::start(directory.path(), None).await;
+ let mut model = fixture();
+ let mut second = model.traces[&key(4)].clone();
+ second.id = key(5);
+ second.alias = "second_review".into();
+ second.kind = TraceKind::Manual;
+ model.traces.insert(second.id, second);
+ let (id, _) = server.import(&model).await;
+ let stored = server.get(id).await;
+ let mut req = request(
+ key(3),
+ key(2),
+ vec![
+ (
+ FacetSelector::Data(DataFacet::Constructor),
+ SemanticDecision::TakeSource,
+ ),
+ (
+ FacetSelector::Data(DataFacet::Unit),
+ SemanticDecision::Candidate,
+ ),
+ ],
+ );
+ let ambiguous = preview(&server, &stored, &req).await;
+ assert!(
+ !ambiguous["plan"]["conflicts"]
+ .as_array()
+ .unwrap()
+ .is_empty()
+ );
+ req.traces.insert(key(3), key(5));
+ let mut candidate = model.elements[&key(2)].clone();
+ *candidate.shared_mut().unwrap() = model.elements[&key(3)].shared().unwrap().clone();
+ if let SharedBody::DataType { unit, .. } = candidate.shared_mut().unwrap() {
+ *unit = "cm".into();
+ }
+ req.candidates
+ .push(SemanticRecord::Element(candidate.clone()));
+ req.references.insert(key(900), key(901)); // Historical correspondence survives transport unchanged.
+ let envelope = preview(&server, &stored, &req).await;
+ assert_eq!(
+ envelope["plan"]["request"],
+ serde_json::to_value(&req).unwrap()
+ );
+ assert_eq!(envelope["plan"]["conflicts"], json!([]));
+ ok(post(&server, id, "apply", Some(&stored.etag()), &envelope).await).await;
+ let applied = server.get(id).await;
+ assert_eq!(applied.model.elements[&key(2)], candidate);
+ assert!(
+ applied.model.traces[&key(4)]
+ .baseline
+ .as_ref()
+ .unwrap()
+ .semantic
+ .is_none()
+ );
+ assert!(
+ applied.model.traces[&key(5)]
+ .baseline
+ .as_ref()
+ .unwrap()
+ .semantic
+ .is_some()
+ );
+ assert_pair(&applied);
+ server.stop().await;
+}
+
+#[tokio::test]
+async fn semantic_new_mapping_keeps_preview_generated_identifiers() {
+ let directory = tempfile::tempdir().unwrap();
+ let server = TestServer::start(directory.path(), None).await;
+ let mut model = Project::empty();
+ let source = model
+ .add_element(Kind::Activity, Layer::Oa, "Inspect", None)
+ .unwrap();
+ let (id, _) = server.import(&model).await;
+ let stored = server.get(id).await;
+ let req = SemanticTransitionRequest::new(TransitionRequest::new(
+ TransitionDirection::OaToSa,
+ vec![source],
+ ));
+ let envelope = preview(&server, &stored, &req).await;
+ assert_eq!(envelope["plan"]["conflicts"], json!([]));
+ let plan: SemanticTransitionPlan = serde_json::from_value(envelope["plan"].clone()).unwrap();
+ let expected = oa_core::semantic::apply_semantic_transition(&model, &plan).unwrap();
+ ok(post(&server, id, "apply", Some(&stored.etag()), &envelope).await).await;
+ assert_eq!(server.get(id).await.model, expected);
+ server.stop().await;
+}
+
+#[tokio::test]
+async fn semantic_resets_and_invalid_candidates_preserve_deliberate_review_boundaries() {
+ let directory = tempfile::tempdir().unwrap();
+ let server = TestServer::start(directory.path(), None).await;
+ let model = fixture();
+ let reviewed = oa_core::semantic::plan_semantic_transition(
+ &model,
+ request(
+ key(2),
+ key(3),
+ vec![
+ (
+ FacetSelector::Data(DataFacet::Unit),
+ SemanticDecision::KeepTarget,
+ ),
+ (
+ FacetSelector::Header(HeaderFacet::Name),
+ SemanticDecision::KeepTarget,
+ ),
+ ],
+ ),
+ )
+ .unwrap();
+ let model = oa_core::semantic::apply_semantic_transition(&model, &reviewed).unwrap();
+ let (id, _) = server.import(&model).await;
+ let stored = server.get(id).await;
+ let before = std::fs::read(directory.path().join(format!("{id}.json"))).unwrap();
+ let mut req = request(
+ key(2),
+ key(3),
+ vec![(
+ FacetSelector::Data(DataFacet::Unit),
+ SemanticDecision::Candidate,
+ )],
+ );
+ let mut candidate = model.elements[&key(3)].clone();
+ candidate.name = "Unselected incidental edit".into();
+ req.candidates.push(SemanticRecord::Element(candidate));
+ let invalid = preview(&server, &stored, &req).await;
+ assert!(!invalid["plan"]["conflicts"].as_array().unwrap().is_empty());
+ assert_eq!(
+ post(&server, id, "apply", Some(&stored.etag()), &invalid)
+ .await
+ .status(),
+ StatusCode::UNPROCESSABLE_ENTITY
+ );
+ assert_eq!(
+ std::fs::read(directory.path().join(format!("{id}.json"))).unwrap(),
+ before
+ );
+ req = request(key(2), key(3), vec![]);
+ req.reviews[0]
+ .reset
+ .push(FacetSelector::Data(DataFacet::Unit));
+ let reset = preview(&server, &stored, &req).await;
+ assert_eq!(
+ reset["plan"]["request"]["reviews"][0]["reset"],
+ json!([{"Data":"Unit"}])
+ );
+ assert_eq!(reset["plan"]["conflicts"], json!([]));
+ ok(post(&server, id, "apply", Some(&stored.etag()), &reset).await).await;
+ let current = server.get(id).await;
+ let facts = ¤t.model.traces[&key(4)]
+ .baseline
+ .as_ref()
+ .unwrap()
+ .semantic
+ .as_ref()
+ .unwrap()
+ .facets;
+ assert_eq!(facts.len(), 1);
+ assert_eq!(
+ facts[0].selector(),
+ FacetSelector::Header(HeaderFacet::Name)
+ );
+ assert_eq!(current.model.elements, model.elements);
+ assert_pair(¤t);
+ server.stop().await;
+}
+
+fn cleanup_fixture() -> (Project, Id, Id, Id) {
+ let mut p = Project::empty();
+ let oa = p
+ .add_element(Kind::DataType, Layer::Oa, "Source record", None)
+ .unwrap();
+ let sa = p
+ .add_element(Kind::DataType, Layer::Sa, "Target record", None)
+ .unwrap();
+ let base = p
+ .add_element(Kind::DataType, Layer::Sa, "Base record", None)
+ .unwrap();
+ for (id, supertype) in [(oa, None), (base, None), (sa, Some(base))] {
+ *p.elements.get_mut(&id).unwrap().shared_mut().unwrap() = SharedBody::DataType {
+ definition: DataTypeDefinition::Record { supertype },
+ default: None,
+ unit: String::new(),
+ };
+ }
+ let leaf = p
+ .add_element(Kind::DataField, Layer::Sa, "Coordinate", Some(base))
+ .unwrap();
+ let item = p
+ .add_element(Kind::ExchangeItem, Layer::Sa, "Location", None)
+ .unwrap();
+ let field = p
+ .add_element(Kind::DataField, Layer::Sa, "Payload", Some(item))
+ .unwrap();
+ for (id, type_ref) in [(leaf, TypeRef::Real), (field, TypeRef::Named(sa))] {
+ *p.elements.get_mut(&id).unwrap().shared_mut().unwrap() = SharedBody::DataField {
+ type_ref,
+ minimum: 0,
+ maximum: Some(1),
+ unit: String::new(),
+ direction: ParameterDirection::Unspecified,
+ storage: FieldStorage::Value,
+ default: None,
+ };
+ }
+ let sender = p
+ .add_element(Kind::Function, Layer::Sa, "Send", None)
+ .unwrap();
+ let receiver = p
+ .add_element(Kind::Function, Layer::Sa, "Receive", None)
+ .unwrap();
+ let exchange = p.relate(
+ RelationKind::FunctionalExchange,
+ "Location report",
+ sender,
+ receiver,
+ );
+ let RelationBody::FunctionalExchange {
+ items,
+ source_port,
+ target_port,
+ ..
+ } = &mut p.relations.get_mut(&exchange).unwrap().body
+ else {
+ panic!()
+ };
+ items.push(item);
+ for id in [*source_port, *target_port] {
+ match p.elements.get_mut(&id).unwrap().shared_mut().unwrap() {
+ SharedBody::Port {
+ contract: PortContract::FunctionInput { incoming_items },
+ ..
+ } => incoming_items.push(item),
+ SharedBody::Port {
+ contract: PortContract::FunctionOutput { outgoing_items },
+ ..
+ } => outgoing_items.push(item),
+ _ => panic!(),
+ }
+ }
+ let scenario = p
+ .add_element(Kind::Scenario, Layer::Sa, "Report location", None)
+ .unwrap();
+ let message = p
+ .add_element(Kind::Occurrence, Layer::Sa, "Report", Some(scenario))
+ .unwrap();
+ *p.elements.get_mut(&message).unwrap().shared_mut().unwrap() = SharedBody::Occurrence {
+ body: OccurrenceBody::Exchange {
+ exchange: Some(exchange),
+ sender: None,
+ receiver: None,
+ message_kind: MessageKind::Asynchronous,
+ reply_to: None,
+ values: vec![MessageValue {
+ path: vec![field],
+ field: leaf,
+ expression: "10".into(),
+ }],
+ },
+ precondition: String::new(),
+ postcondition: String::new(),
+ };
+ p.elements
+ .get_mut(&scenario)
+ .unwrap()
+ .steps_mut()
+ .unwrap()
+ .push(message);
+ let trace = Id::new_v4();
+ p.traces.insert(
+ trace,
+ Trace {
+ id: trace,
+ alias: "record_trace".into(),
+ name: "Record correspondence".into(),
+ description: String::new(),
+ oa,
+ sa,
+ kind: TraceKind::Manual,
+ baseline: None,
+ },
+ );
+ (p, oa, sa, message)
+}
+
+#[tokio::test]
+async fn semantic_cleanup_impacts_require_exact_acceptance_before_atomic_apply() {
+ let directory = tempfile::tempdir().unwrap();
+ let server = TestServer::start(directory.path(), None).await;
+ let (model, oa, sa, message) = cleanup_fixture();
+ let (id, _) = server.import(&model).await;
+ let stored = server.get(id).await;
+ let path = directory.path().join(format!("{id}.json"));
+ let before = std::fs::read(&path).unwrap();
+ let mut req = request(
+ oa,
+ sa,
+ vec![(
+ FacetSelector::Data(DataFacet::RecordSupertype),
+ SemanticDecision::TakeSource,
+ )],
+ );
+ let unresolved = preview(&server, &stored, &req).await;
+ assert!(
+ !unresolved["plan"]["conflicts"]
+ .as_array()
+ .unwrap()
+ .is_empty()
+ );
+ let impacts: Vec =
+ serde_json::from_value(unresolved["plan"]["impacts"].clone()).unwrap();
+ assert_eq!(impacts.len(), 1);
+ assert_eq!(impacts[0].object, message);
+ assert_ne!(impacts[0].before, impacts[0].after);
+ assert_eq!(
+ post(&server, id, "apply", Some(&stored.etag()), &unresolved)
+ .await
+ .status(),
+ StatusCode::UNPROCESSABLE_ENTITY
+ );
+ let mut inaccurate = impacts.clone();
+ inaccurate[0].after = inaccurate[0].before.clone();
+ req.accepted_impacts = inaccurate;
+ let inaccurate = preview(&server, &stored, &req).await;
+ assert!(
+ !inaccurate["plan"]["conflicts"]
+ .as_array()
+ .unwrap()
+ .is_empty()
+ );
+ assert_eq!(std::fs::read(&path).unwrap(), before);
+ req.accepted_impacts = impacts;
+ let approved = preview(&server, &stored, &req).await;
+ assert_eq!(approved["plan"]["conflicts"], json!([]));
+ assert_eq!(
+ approved["plan"]["request"]["accepted_impacts"],
+ serde_json::to_value(&req.accepted_impacts).unwrap()
+ );
+ ok(post(&server, id, "apply", Some(&stored.etag()), &approved).await).await;
+ let current = server.get(id).await;
+ assert_eq!(current.revision, stored.revision + 1);
+ assert!(
+ matches!(current.model.elements[&message].shared(), Some(SharedBody::Occurrence { body: OccurrenceBody::Exchange { values, .. }, .. }) if values.is_empty())
+ );
+ assert_pair(¤t);
+ server.stop().await;
+ let server = TestServer::start(directory.path(), None).await;
+ assert_eq!(server.get(id).await.model, current.model);
+ server.stop().await;
+}
diff --git a/crates/oa-server/tests/semantic_http_contract.py b/crates/oa-server/tests/semantic_http_contract.py
new file mode 100644
index 00000000..4af7a777
--- /dev/null
+++ b/crates/oa-server/tests/semantic_http_contract.py
@@ -0,0 +1,136 @@
+"""Validate actual local HTTP responses against served and checked-in OpenAPI.
+
+Requires jsonschema. Usage: python semantic_http_contract.py /path/to/arcadia-server
+The supplied binary is launched on loopback with a fresh temporary store.
+"""
+import copy
+import json
+import os
+import re
+import subprocess
+import sys
+import tempfile
+import urllib.error
+import urllib.request
+from pathlib import Path
+
+from jsonschema import Draft202012Validator, FormatChecker
+
+ROOT = Path(__file__).resolve().parents[3]
+local = json.loads((ROOT / "docs/openapi.json").read_text(encoding="utf-8"))
+for schema in local["components"]["schemas"].values():
+ Draft202012Validator.check_schema(schema)
+
+
+def validator(spec, name):
+ return Draft202012Validator({"$ref": "#/components/schemas/" + name, "components": spec["components"]},
+ format_checker=FormatChecker())
+
+
+with tempfile.TemporaryDirectory(prefix="arcadia-semantic-http-") as directory:
+ env = dict(os.environ)
+ env.pop("ARCADIA_SERVER_TOKEN", None)
+ process = subprocess.Popen([sys.argv[1], "--bind", "127.0.0.1:0", "--data-dir", directory],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, env=env,
+ creationflags=subprocess.CREATE_NO_WINDOW if os.name == "nt" else 0)
+ try:
+ banner = process.stderr.readline()
+ address = re.search(r"listening on (127\.0\.0\.1:\d+)", banner)
+ assert address, banner
+ base = "http://" + address.group(1)
+
+ def call(method, path, body=None, etag=None, expected=200):
+ headers = {"Content-Type": "application/json"}
+ if etag:
+ headers["If-Match"] = etag
+ request = urllib.request.Request(base + path, data=None if body is None else json.dumps(body).encode(),
+ headers=headers, method=method)
+ try:
+ response = urllib.request.urlopen(request, timeout=15)
+ except urllib.error.HTTPError as error:
+ response = error
+ with response:
+ data = json.load(response)
+ assert response.status == expected, (response.status, data)
+ return data, response.headers.get("ETag")
+
+ served, _ = call("GET", "/openapi.json")
+ assert served == local, "Server binary embeds a different OpenAPI file; rebuild it"
+ checked = 0
+
+ def validate(name, value):
+ global checked
+ for spec in (local, served):
+ validator(spec, name).validate(value)
+ checked += 1
+
+ old = json.loads((ROOT / "crates/oa-core/tests/fixtures/v4-reviewed-prose.json").read_text())
+ imported, etag = call("POST", "/api/v1/projects/import", old, expected=201)
+ path = "/api/v1/projects/" + imported["resource_id"]
+ stored, _ = call("GET", path)
+ validate("StoredProject", stored)
+ validate("Project", stored["model"])
+ trace = next(iter(stored["model"]["traces"]))
+ oa = stored["model"]["traces"][trace]["oa"]
+ sa = stored["model"]["traces"][trace]["sa"]
+ query = {"traces": [trace], "references": {oa: sa}, "revision": stored["revision"]}
+ validate("SemanticQueryRequest", query)
+ queried, _ = call("POST", path + "/semantic-transitions/query", query)
+ validate("SemanticQueryResult", queried)
+ request = {"transition": {"direction": "OaToSa", "sources": [oa], "scope": "SelectedOnly",
+ "mappings": [{"source": oa, "target": sa, "target_kind": None}], "fields": [],
+ "resolutions": [], "destination_diagram": None}, "traces": {oa: trace},
+ "references": {}, "reviews": [{"source": oa, "resolutions": [
+ {"facet": {"Header": "Name"}, "decision": "TakeSource"},
+ {"facet": {"Data": "Unit"}, "decision": "KeepTarget"}], "reset": []}],
+ "candidates": [], "accepted_impacts": []}
+ validate("SemanticTransitionRequest", request)
+ one_sided = copy.deepcopy(request)
+ one_sided["reviews"][0]["resolutions"] = [{"facet": {"Literal": {"oa": "Only source"}}, "decision": "KeepTarget"}]
+ validate("SemanticTransitionRequest", one_sided)
+ admitted, _ = call("POST", path + "/semantic-transitions/preview", one_sided, etag)
+ validate("SemanticTransitionEnvelope", admitted)
+ assert admitted["plan"]["conflicts"] # Valid typed input, inapplicable to the integer/real fixture.
+ preview, _ = call("POST", path + "/semantic-transitions/preview", request, etag)
+ validate("SemanticTransitionEnvelope", preview)
+ assert not preview["plan"]["conflicts"], preview
+ result, updated_etag = call("POST", path + "/semantic-transitions/apply", preview, etag)
+ validate("MutationResult", result)
+ stored, _ = call("GET", path)
+ validate("StoredProject", stored)
+ validate("Project", stored["model"])
+ baseline = stored["model"]["traces"][trace]["baseline"]
+ validate("TraceBaseline", baseline)
+ validate("SemanticBaseline", baseline["semantic"])
+ query.pop("revision")
+ queried, _ = call("POST", path + "/semantic-transitions/query", query)
+ validate("SemanticQueryResult", queried)
+ problem, _ = call("POST", path + "/semantic-transitions/apply", preview, etag, expected=412)
+ validate("Problem", problem)
+ assert updated_etag != etag
+
+ invalid = [
+ ("FacetSelector", {"path": ["definition", "minimum"]}),
+ ("FacetSelector", {"Data": "Unsupported"}),
+ ("FacetReview", {"Data": {"IntegerMinimum": {"oa": {"Value": "wrong"}, "sa": {"Value": None}}}}),
+ ("FacetReview", {"Data": {"Unit": {"oa": {"Value": 42}, "sa": "NotApplicable"}}}),
+ ("FacetSelector", {"Literal": {"oa": "literal", "sa": None, "index": 0}}),
+ ("SemanticQueryRequest", {"traces": [trace, trace]}),
+ ("SemanticQueryRequest", {"traces": []}),
+ ("SemanticTransitionEnvelope", {**preview, "unknown": True}),
+ ]
+ obsolete = copy.deepcopy(stored["model"])
+ obsolete["schema_version"] = 4
+ invalid.append(("Project", obsolete))
+ for name, value in invalid:
+ assert not validator(local, name).is_valid(value), (name, value)
+ assert not validator(served, name).is_valid(value), (name, value)
+ # NotApplicable is distinct from Value(null); each leaf fixes the optionality.
+ validate("FacetReview", {"Data": {"IntegerMinimum": {"oa": "NotApplicable", "sa": {"Value": None}}}})
+ validate("FacetSelector", {"Annotation": {"oa": {"path": [oa], "field": sa}, "sa": None}})
+ validate("FacetSelector", {"Annotation": {"oa": {"path": [oa], "field": sa}}})
+ validate("SemanticImpact", {"object": oa, "after": {"Element": stored["model"]["elements"][oa]}})
+ print(f"{len(local['components']['schemas'])} valid schemas; {checked} actual/typed values validated against served+local contracts; {len(invalid)} invalid shapes rejected")
+ finally:
+ process.terminate()
+ process.wait(timeout=15)
diff --git a/crates/oa-server/tests/semantic_schema.py b/crates/oa-server/tests/semantic_schema.py
new file mode 100644
index 00000000..380974be
--- /dev/null
+++ b/crates/oa-server/tests/semantic_schema.py
@@ -0,0 +1,205 @@
+"""Refresh the closed semantic OpenAPI catalog from the frozen Rust leaf table.
+
+Run from any directory with Python 3: semantic_schema.py [--check].
+This generates documentation only, never runtime selectors or model mutations.
+"""
+import copy
+import json
+import re
+import sys
+from pathlib import Path
+
+ROOT = Path(__file__).resolve().parents[3]
+PATH = ROOT / "docs/openapi.json"
+spec = json.loads(PATH.read_text(encoding="utf-8"))
+schemas = spec["components"]["schemas"]
+types = (ROOT / "crates/oa-core/src/semantic/types.rs").read_text(encoding="utf-8")
+model = (ROOT / "crates/oa-core/src/model.rs").read_text(encoding="utf-8")
+
+
+def ref(name):
+ return {"$ref": f"#/components/schemas/{name}"}
+
+
+def obj(properties, required=None):
+ return {"type": "object", "properties": properties,
+ "required": list(properties) if required is None else required,
+ "additionalProperties": False}
+
+
+def array(item, maximum=None):
+ result = {"type": "array", "items": item}
+ if maximum is not None:
+ result["maxItems"] = maximum
+ return result
+
+
+def optional(item):
+ return {"anyOf": [item, {"type": "null"}]}
+
+
+def enum(names):
+ return {"type": "string", "enum": names}
+
+
+def variant(name, value):
+ return obj({name: value})
+
+
+def typed(name):
+ if name.startswith("Option<"):
+ return optional(typed(name[7:-1]))
+ if name.startswith("Vec<"):
+ return array(typed(name[4:-1]))
+ primitives = {"String": {"type": "string"}, "bool": {"type": "boolean"},
+ "u32": {"type": "integer", "minimum": 0, "maximum": 4294967295},
+ "i64": {"type": "integer", "minimum": -9223372036854775808,
+ "maximum": 9223372036854775807}, "f64": {"type": "number"}}
+ return primitives[name] if name in primitives else ref(name)
+
+
+def reviewed(name):
+ key = "Reviewed" + re.sub(r"[^A-Za-z0-9]", "", name)
+ observation = {"oneOf": [enum(["NotApplicable"]), variant("Value", typed(name))]}
+ schemas[key] = obj({"oa": observation, "sa": copy.deepcopy(observation)})
+ return ref(key)
+
+
+def keypair(name):
+ key = "KeyPair" + name
+ schemas[key] = obj({"oa": optional(typed(name)), "sa": optional(typed(name))}, [])
+ return ref(key)
+
+
+for name in ["DataConstructor", "PortConstructor", "OccurrenceConstructor", "EventConstructor",
+ "MessageConstructor", "ReferenceCollection", "OrderedCollection", "IncidentEnd",
+ "ArtifactFacet", "ComponentPortKind", "ComponentPortOrientation", "PortDirection",
+ "FragmentOperator", "StateActionKind", "ArtifactRelation"]:
+ source = types if f"pub enum {name}" in types else model
+ body = re.search(r"pub enum " + name + r"\s*\{([^}]+)\}", source).group(1)
+ body = re.sub(r"//[^\n]*|#\[[^\]]*\]", "", body)
+ names = [value.strip() for value in body.split(",") if value.strip()]
+ assert all(re.fullmatch(r"[A-Za-z]+", value) for value in names), (name, names)
+ schemas[name] = enum(names)
+
+catalog = types.split("macro_rules! scalar_families", 1)[1].split("pub(super) use", 1)[0]
+families = re.findall(r"(\w+), (\w+), (\w+) \{([^}]+)\}", catalog)
+assert len(families) == 13
+selectors, reviews = [], []
+leaf_count = 0
+for family, selector, review, body in families:
+ leaves = re.findall(r"(\w+): ([\w<>]+)", body)
+ leaf_count += len(leaves)
+ schemas[selector] = enum([leaf for leaf, _ in leaves])
+ schemas[review] = {"oneOf": [variant(leaf, reviewed(value)) for leaf, value in leaves]}
+ selectors.append(variant(family, ref(selector)))
+ reviews.append(variant(family, ref(review)))
+assert leaf_count == 84
+schemas["AnnotationKey"] = obj({"path": array(ref("Id")), "field": ref("Id")})
+id_keys, text_keys, annotation_keys = keypair("Id"), keypair("String"), keypair("AnnotationKey")
+artifact_types = {"Presence": "bool", "Name": "String", "Description": "String", "Owner": "Id",
+ "Relation": "ArtifactRelation", "Uri": "String", "Revision": "Option",
+ "Fragment": "Option"}
+schemas["ArtifactReview"] = {"oneOf": [variant(k, reviewed(v)) for k, v in artifact_types.items()]}
+selectors += [variant("Member", obj({"collection": ref("ReferenceCollection"), "keys": id_keys})),
+ variant("Order", ref("OrderedCollection")), variant("Literal", text_keys),
+ variant("Annotation", annotation_keys), variant("Binding", id_keys), variant("Child", id_keys),
+ variant("Incident", obj({"keys": id_keys, "end": ref("IncidentEnd")})),
+ variant("Artifact", obj({"keys": id_keys, "facet": ref("ArtifactFacet")}))]
+reviews += [variant("Member", obj({"collection": ref("ReferenceCollection"), "keys": id_keys, "review": reviewed("bool")})),
+ variant("Order", obj({"collection": ref("OrderedCollection"), "review": reviewed("Vec")})),
+ variant("Literal", obj({"keys": text_keys, "review": reviewed("bool")})),
+ variant("Annotation", obj({"keys": annotation_keys, "review": reviewed("Option")})),
+ variant("Binding", obj({"keys": id_keys, "review": reviewed("Option")})),
+ variant("Child", obj({"keys": id_keys, "review": reviewed("bool")})),
+ variant("Incident", obj({"keys": id_keys, "end": ref("IncidentEnd"), "review": reviewed("bool")})),
+ variant("Artifact", obj({"keys": id_keys, "review": ref("ArtifactReview")}))]
+schemas["FacetSelector"] = {"oneOf": selectors}
+schemas["FacetReview"] = {"oneOf": reviews}
+schemas["SemanticBaseline"] = obj({"facets": array(ref("FacetReview"))})
+schemas["TraceBaseline"]["properties"]["semantic"] = {**optional(ref("SemanticBaseline")), "default": None,
+ "description": "Absent/null means Unreviewed. Historical typed facts never become live graph references."}
+schemas["Project"]["properties"]["schema_version"]["const"] = 5
+schemas["MigrationReport"]["properties"]["from_schema"]["enum"] = [1, 2, 3, 4]
+schemas["MigrationReport"]["properties"]["to_schema"]["const"] = 5
+schemas["MigrationReport"]["description"] = schemas["MigrationReport"]["description"].replace("V1/V2/V3 to V4", "V1/V2/V3/V4 to V5")
+spec["info"]["description"] = spec["info"]["description"].replace("schema-4", "schema-5")
+spec["paths"]["/api/v1/projects/import"]["post"]["description"] = "Schema-5 native JSON is described below. Schema-1/2/3/4 JSON and source are accepted through explicit frozen readers and migration, also on replacement and candidate validation. Prior prose reviews remain intact; absent semantic review stays Unreviewed. Export emits schema 5 / arcadia 5. See docs/language.rst."
+schemas["SourceBundle"]["description"] = schemas["SourceBundle"]["description"].replace("source4 workspace (source3 migrates explicitly)", "source5 workspace (source3/4 migrate explicitly)")
+schemas["Drift"] = enum(["Unreviewed", "Unchanged", "OaChanged", "SaChanged", "BothChanged"])
+schemas["FacetDrift"] = obj({"selector": ref("FacetSelector"), "current": ref("FacetReview"), "drift": ref("Drift")})
+schemas["SemanticDrift"] = obj({"own": ref("Drift"), "linked": ref("Drift"),
+ "own_unreviewed": typed("bool"), "linked_unreviewed": typed("bool")})
+schemas["LinkedSemanticImpact"] = obj({"objects": id_keys, "traces": array(ref("Id")),
+ "drift": ref("Drift"), "unreviewed": typed("bool")})
+for name, members in [("SemanticRecord", ["Element", "Relation", "Artifact"]),
+ ("ImpactRecord", ["Element", "Relation", "Artifact", "Diagram", "Trace"])]:
+ schemas[name] = {"oneOf": [variant(n, ref("ArtifactLink" if n == "Artifact" else n)) for n in members]}
+schemas["SemanticImpact"] = obj({"object": ref("Id"), "before": optional(ref("ImpactRecord")), "after": optional(ref("ImpactRecord"))}, ["object"])
+schemas["SemanticDecision"] = enum(["KeepTarget", "TakeSource", "Candidate"])
+schemas["FacetResolution"] = obj({"facet": ref("FacetSelector"), "decision": ref("SemanticDecision")})
+schemas["SemanticReviewRequest"] = obj({"source": ref("Id"), "resolutions": array(ref("FacetResolution"), 5000),
+ "reset": {**array(ref("FacetSelector"), 5000), "default": []}}, ["source", "resolutions"])
+
+
+def mappings(maximum):
+ return {"type": "object", "propertyNames": {"format": "uuid"},
+ "additionalProperties": ref("Id"), "maxProperties": maximum, "default": {}}
+
+
+schemas["SemanticTransitionRequest"] = obj({"transition": ref("TransitionRequest"), "traces": mappings(100),
+ "references": mappings(5000), "reviews": {**array(ref("SemanticReviewRequest"), 100), "default": []},
+ "candidates": {**array(ref("SemanticRecord"), 200), "default": []},
+ "accepted_impacts": {**array(ref("SemanticImpact"), 200), "default": []}}, ["transition"])
+schemas["SemanticTransitionRequest"]["description"] = "Canonical OA-to-SA references include historical UUIDs. Traces map selected source IDs to trace IDs. Combined resolutions/reset limit: 5,000. Candidates must equal exactly the result of their selected facets; accepted_impacts explicitly acknowledge exact induced changes."
+schemas["SemanticReviewPreview"] = obj({"source": ref("Id"), "target": ref("Id"), "facets": array(ref("FacetDrift")),
+ "acknowledged": array(ref("FacetSelector")), "retired": array(ref("FacetSelector")), "linked_impacts": array(ref("LinkedSemanticImpact"))})
+schemas["SemanticTransitionPlan"] = obj({"base_fingerprint": typed("String"), "request": ref("SemanticTransitionRequest"),
+ "transition": ref("TransitionPlan"), "reviews": array(ref("SemanticReviewPreview")), "impacts": array(ref("SemanticImpact")),
+ "conflicts": array(typed("String")), "commands": array(ref("Command"), 200), "prepared_fingerprint": optional(typed("String"))})
+schemas["SemanticTransitionPlan"]["required"].remove("prepared_fingerprint")
+schemas["SemanticTransitionEnvelope"] = obj({"base_revision": ref("Revision"), "plan": ref("SemanticTransitionPlan")})
+schemas["SemanticQueryRequest"] = obj({"traces": {**array(ref("Id"), 100), "minItems": 1, "uniqueItems": True},
+ "references": mappings(5000), "revision": optional(ref("Revision"))}, ["traces"])
+schemas["SemanticQueryItem"] = obj({"trace": ref("Id"), "oa": ref("Id"), "sa": ref("Id"),
+ "facets": array(ref("FacetDrift")), "drift": ref("SemanticDrift"), "linked_impacts": array(ref("LinkedSemanticImpact"))})
+schemas["SemanticQueryResult"] = obj({"revision": ref("Revision"), "items": array(ref("SemanticQueryItem"), 100)})
+for operation, request, result in [("query", "SemanticQueryRequest", "SemanticQueryResult"),
+ ("preview", "SemanticTransitionRequest", "SemanticTransitionEnvelope"),
+ ("apply", "SemanticTransitionEnvelope", "MutationResult")]:
+ endpoint = copy.deepcopy(spec["paths"]["/api/v1/projects/{id}/transitions/" + ("apply" if operation == "apply" else "preview")])
+ post = endpoint["post"]
+ post["operationId"] = operation + "SemanticTransition"
+ post["summary"] = {"query": "Query typed trace drift and linked impacts without mutation",
+ "preview": "Preview and source-validate a typed semantic transition without writing",
+ "apply": "Conditionally apply a prepared semantic candidate in one model/source revision"}[operation]
+ post["requestBody"]["content"]["application/json"]["schema"] = ref(request)
+ post["responses"]["200"]["content"]["application/json"]["schema"] = ref(result)
+ post["description"] = "Uses the frozen core typed semantic contract. A supplied plan is a client-owned candidate, not a signed receipt; fingerprints check consistency, not original review authorship. Preview validates source writeback when conflict-free. Apply preserves preview-generated IDs and does not replan random identities."
+ if operation == "query":
+ post["parameters"] = [p for p in post["parameters"] if p["in"] != "header"]
+ post["responses"].pop("412", None)
+ post["responses"].pop("428", None)
+ post["responses"]["409"] = {"$ref": "#/components/responses/Problem"}
+ post["description"] = "Read one immutable snapshot. Optional revision mismatch returns409; missing trace returns404; duplicate/empty trace selection returns400. References are canonical OA-to-SA correspondence. No write, baseline refresh or external artifact fetch."
+ spec["paths"]["/api/v1/projects/{id}/semantic-transitions/" + operation] = endpoint
+
+
+def check_refs(value):
+ if isinstance(value, dict):
+ if "$ref" in value and value["$ref"].startswith("#/components/schemas/"):
+ assert value["$ref"].split("/")[-1] in schemas, value
+ for child in value.values():
+ check_refs(child)
+ elif isinstance(value, list):
+ for child in value:
+ check_refs(child)
+
+
+check_refs(spec)
+rendered = json.dumps(spec, indent=2, ensure_ascii=False) + "\n"
+if "--check" in sys.argv:
+ assert json.loads(PATH.read_text(encoding="utf-8")) == spec, "Run semantic_schema.py to refresh OpenAPI"
+else:
+ PATH.write_text(rendered, encoding="utf-8")
+print(f"Closed catalog: {len(families)} families, {leaf_count} scalar leaves; {len(schemas)} schemas")
diff --git a/docs/api.html b/docs/api.html
index 3a7f13d0..f43c3e8f 100644
--- a/docs/api.html
+++ b/docs/api.html
@@ -763,6 +763,18 @@ bearer token, if any. Non-loopback binding requires a configured token.
/api/v1/projects/{id}/transitions/apply |
Conditionally apply that client-held plan and base_revision. |
+POST |
+/api/v1/projects/{id}/semantic-transitions/query |
+Read selected traces' typed facts, own drift and linked impacts. |
+
+POST |
+/api/v1/projects/{id}/semantic-transitions/preview |
+Prepare typed semantic decisions and source writeback without writing. |
+
+POST |
+/api/v1/projects/{id}/semantic-transitions/apply |
+Apply that prepared candidate under its original shared revision/ETag. |
+
Content-Type: application/json is required for JSON requests.
@@ -784,8 +796,8 @@ candidate validation reports the same diagnostic in its 200 response.
Parsing, validation and query processing use snapshot workers, so this work
does not hold the catalog lock or serialize unrelated model preparation.
Import accepts schema-1 JSON through the shared explicit migration adapter,
-as well as schema-2, schema-3 and current schema-4 JSON. Source import uses the shared language parser
-and its supported migrations. Export uses schema 4 / arcadia 4. Native JSON
+as well as schema-2, schema-3, schema-4 and current schema-5 JSON. Source import uses the shared language parser
+and its supported migrations. Export uses schema 5 / arcadia 5. Native JSON
replacement accepts supported older schemas through the same explicit migration.
Only documented query parameters are accepted. In particular, appending
?revision=... to model/source export is an error, not historical retrieval.
@@ -796,7 +808,7 @@ Only documented query parameters are accepted. In particular, appending
{
"entry": "rescue.arcadia",
"files": {
- "rescue.arcadia": "arcadia 4; project rescue \"Rescue\" { include \"oa/work.arcadia\"; }\n",
+ "rescue.arcadia": "arcadia 5; project rescue \"Rescue\" { include \"oa/work.arcadia\"; }\n",
"oa/work.arcadia": "// Engineering rationale\noa_activity assess \"Assess assistance\" {}\n"
}
}
@@ -807,7 +819,7 @@ targets or another hosted resource. All submitted files must be reachable;
missing files, cycles, duplicate keys, case collisions and escaping paths are
rejected. The bundle permits at most 256 files, 32 include edges along a path,
and 1,024 include edges in total. Model and source-byte budgets apply across
-the complete bundle, not separately per file. Current bundle syntax is source4; source3 bundles migrate explicitly while
+the complete bundle, not separately per file. Current bundle syntax is source5; source3/4 bundles migrate explicitly while
preserving their files/includes/comments. V1/V2 single-file migration remains
available through interchange import.
Compilation inserts UUIDs into headers that omit them. Import returns 201 with
@@ -999,7 +1011,7 @@ contract in the same transaction when removing a used interface allocation.
Explicit schema1/2/3 migration preserves prior identities and typed ports. Reports
add semantic defaults, generated interface allocations and unresolved message
values. Old source3 bundles retain files/includes/comments during upgrade; all
-current exports use schema4/source4. Reading an old envelope does not write it or
+current exports use schema5/source5. Reading an old envelope does not write it or
advance its ETag. Canonical exports omit transient migration reports.
@@ -1009,7 +1021,7 @@ advance its ETag. Canonical exports omit transient migration reports.
or:
{"format":"arcadia", "source":"complete source document"}
or:
-{"format":"source-project", "source_project":{"entry":"rescue.arcadia", "files":{"rescue.arcadia":"arcadia 4; project rescue \"Rescue\" {}"}}}
+{"format":"source-project", "source_project":{"entry":"rescue.arcadia", "files":{"rescue.arcadia":"arcadia 5; project rescue \"Rescue\" {}"}}}
A well-formed validation request returns 200 with valid and issues even
if its candidate is invalid, including a model record that fails typed decoding.
Malformed request JSON or an invalid format/payload envelope is a 400.
@@ -1093,6 +1105,102 @@ authenticated as an untouched server preview; the same authenticated client
can submit ordinary typed commands. The core fingerprint is a change detector,
not a security digest. There is no plan token, expiration store or receipt.
+
+Typed semantic transition review
+The sibling semantic-transitions routes use the typed review semantics in language.rst sections 5.1–5.5.
+The original prose transition routes keep
+their existing contract. All new routes use JSON and the existing authentication,
+capacity, worker and error boundaries.
+Query accepts {"traces":["trace-uuid"],"references":{},"revision":1}.
+references is an optional map of canonical OA UUIDs to SA UUIDs, including
+historical deleted identities. It never guesses correspondences from names.
+revision is optional; a mismatch returns 409. Select 1–100 unique existing
+trace IDs; an empty or duplicate selection returns 400 and a missing trace
+returns 404. The response includes the current revision and items containing
+trace, oa, sa, typed facets, drift and linked_impacts.
+Own and linked drift and their unreviewed flags remain distinct. Query reads one
+immutable snapshot, does not refresh baselines, and does not fetch artifact URIs.
+Preview accepts SemanticTransitionRequest:
+{
+ "transition": {
+ "direction": "OaToSa",
+ "sources": ["40000000-0000-4000-8000-000000000002"],
+ "scope": "SelectedOnly",
+ "mappings": [{
+ "source": "40000000-0000-4000-8000-000000000002",
+ "target": "40000000-0000-4000-8000-000000000003",
+ "target_kind": null
+ }],
+ "fields": [], "resolutions": [], "destination_diagram": null
+ },
+ "traces": {}, "references": {},
+ "reviews": [{
+ "source": "40000000-0000-4000-8000-000000000002",
+ "resolutions": [
+ {"facet":{"Header":"Name"}, "decision":"TakeSource"},
+ {"facet":{"Data":"Unit"}, "decision":"KeepTarget"}
+ ],
+ "reset": []
+ }],
+ "candidates": [], "accepted_impacts": []
+}
+The example maps an existing OA data type to its traced SA counterpart, takes
+only its name and acknowledges intentionally different units. Other facets stay
+unreviewed or retain their earlier drift. Select an explicit trace through the
+traces map (source UUID to trace UUID) when multiple trace kinds connect the
+pair. reset deliberately invalidates exact old selectors after changed
+correspondence. The optional collections default to empty. Semantic header
+decisions use typed facets; leave legacy transition.fields and
+transition.resolutions empty.
+Facet selectors are closed enums, for example {"Data":"IntegerMinimum"}
+or {"Member":{"collection":"SignalItems","keys":{"oa":"oa-uuid","sa":"sa-uuid"}}}.
+Annotation keys contain the entire path and field; enum literal keys are exact
+strings. KeepTarget, TakeSource and Candidate operate on independently
+selected facts. Candidate records use existing Element/Relation/ArtifactLink
+types, must preserve identity/alias, and must equal precisely the result of
+the selected facets. Constructor review covers its coupled introduced/removed
+fields. Membership review does not silently acknowledge order; target-only
+members remain independent. OpenAPI defines every selector and typed payload.
+Preview requires If-Match and returns {"base_revision":1,"plan":{...}}.
+The plan contains the original typed request, mapping plan, review facts,
+acknowledged/retired selectors, linked impacts, exact prepared impacts, conflicts,
+commands, and base/prepared fingerprints. A conflict-free preview also prepares
+the complete authored source bundle and checks its model equivalence and capacity.
+No preview changes the model, source, revision or stored bytes.
+If ordinary preparation induces additional cleanup, the plan reports exact typed
+before/after impacts and a conflict. Review those impacts, place the accepted
+records in accepted_impacts, and request another preview. Acceptance cannot
+override a contradictory selected facet. Missing mappings, ambiguous order,
+duplicate decisions, invalid candidates or unresolved impacts cannot be applied.
+This is the shared core planner and command preparation, with no server-specific
+semantic mutation engine.
+Apply accepts the entire preview envelope under the same If-Match. It checks
+base_revision, the model fingerprint, unresolved conflicts, the prepared
+candidate fingerprint, ordinary model validation and coupled source preparation,
+then atomically stores one accepted model/source revision. The final store check
+also catches a concurrent edit during preparation. Source-only edits invalidate
+the preview through the shared ETag even when the model fingerprint is unchanged.
+Stale ETag/revision returns 412; semantic rejection returns 422 with code
+semantic_transition_rejected. Exact no-op candidates preserve revision.
+Read and preview again after a successful changed apply before reviewing further.
+A supplied plan remains a client-owned candidate. Fingerprints detect stale or
+inconsistent proposals; they are not tamper-proof signatures, authentication
+receipts or proof of original review authorship. Apply preserves preview-generated
+identities and does not rerun the planner with fresh random IDs. Authenticated
+clients already have ordinary model/source editing privileges. The server does
+not persist plans, tokens or review sessions.
+Requests allow 100 sources, trace choices and reviews; 200 mappings, candidates
+and accepted impacts; 5,000 canonical reference mappings; and 5,000 facet
+resolutions plus resets across all reviews. The legacy 400 prose-resolution
+limit and 200-command transaction limit still apply. Query has the same 5,000
+reference-map limit. Core bounded linked traversal errors remain observable as
+semantic rejection; no truncated result silently claims complete review.
+Schema/source 5 adds TraceBaseline.semantic. Absence or null is Unreviewed;
+migrating older prose baselines does not fabricate semantic history. The persisted
+baseline contains only closed typed FacetReview facts, not whole candidate
+records or a generic JSON value tree. Historical UUIDs remain historical, including
+after deletion, and source uses explicit uuid tokens for them.
+
Error contract
All errors have Content-Type: application/problem+json. Example:
diff --git a/docs/api.rst b/docs/api.rst
index 6072f7d4..1d3492e6 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -124,6 +124,15 @@ bearer token, if any. Non-loopback binding requires a configured token.
* - POST
- ``/api/v1/projects/{id}/transitions/apply``
- Conditionally apply that client-held plan and base_revision.
+ * - POST
+ - ``/api/v1/projects/{id}/semantic-transitions/query``
+ - Read selected traces' typed facts, own drift and linked impacts.
+ * - POST
+ - ``/api/v1/projects/{id}/semantic-transitions/preview``
+ - Prepare typed semantic decisions and source writeback without writing.
+ * - POST
+ - ``/api/v1/projects/{id}/semantic-transitions/apply``
+ - Apply that prepared candidate under its original shared revision/ETag.
``Content-Type: application/json`` is required for JSON requests.
``text/plain; charset=utf-8`` is used for Arcadia source. The service does not
@@ -146,8 +155,8 @@ Parsing, validation and query processing use snapshot workers, so this work
does not hold the catalog lock or serialize unrelated model preparation.
Import accepts schema-1 JSON through the shared explicit migration adapter,
-as well as schema-2, schema-3 and current schema-4 JSON. Source import uses the shared language parser
-and its supported migrations. Export uses schema 4 / arcadia 4. Native JSON
+as well as schema-2, schema-3, schema-4 and current schema-5 JSON. Source import uses the shared language parser
+and its supported migrations. Export uses schema 5 / arcadia 5. Native JSON
replacement accepts supported older schemas through the same explicit migration.
Only documented query parameters are accepted. In particular, appending
``?revision=...`` to model/source export is an error, not historical retrieval.
@@ -160,7 +169,7 @@ A source bundle contains ``entry`` and a map of ``files``. For example::
{
"entry": "rescue.arcadia",
"files": {
- "rescue.arcadia": "arcadia 4; project rescue \"Rescue\" { include \"oa/work.arcadia\"; }\n",
+ "rescue.arcadia": "arcadia 5; project rescue \"Rescue\" { include \"oa/work.arcadia\"; }\n",
"oa/work.arcadia": "// Engineering rationale\noa_activity assess \"Assess assistance\" {}\n"
}
}
@@ -172,7 +181,7 @@ targets or another hosted resource. All submitted files must be reachable;
missing files, cycles, duplicate keys, case collisions and escaping paths are
rejected. The bundle permits at most 256 files, 32 include edges along a path,
and 1,024 include edges in total. Model and source-byte budgets apply across
-the complete bundle, not separately per file. Current bundle syntax is source4; source3 bundles migrate explicitly while
+the complete bundle, not separately per file. Current bundle syntax is source5; source3/4 bundles migrate explicitly while
preserving their files/includes/comments. V1/V2 single-file migration remains
available through interchange import.
@@ -394,7 +403,7 @@ contract in the same transaction when removing a used interface allocation.
Explicit schema1/2/3 migration preserves prior identities and typed ports. Reports
add semantic defaults, generated interface allocations and unresolved message
values. Old source3 bundles retain files/includes/comments during upgrade; all
-current exports use schema4/source4. Reading an old envelope does not write it or
+current exports use schema5/source5. Reading an old envelope does not write it or
advance its ETag. Canonical exports omit transient migration reports.
Validation
@@ -410,7 +419,7 @@ or::
or::
- {"format":"source-project", "source_project":{"entry":"rescue.arcadia", "files":{"rescue.arcadia":"arcadia 4; project rescue \"Rescue\" {}"}}}
+ {"format":"source-project", "source_project":{"entry":"rescue.arcadia", "files":{"rescue.arcadia":"arcadia 5; project rescue \"Rescue\" {}"}}}
A well-formed validation request returns 200 with ``valid`` and ``issues`` even
if its candidate is invalid, including a model record that fails typed decoding.
@@ -506,6 +515,115 @@ authenticated as an untouched server preview; the same authenticated client
can submit ordinary typed commands. The core fingerprint is a change detector,
not a security digest. There is no plan token, expiration store or receipt.
+Typed semantic transition review
+--------------------------------
+
+The sibling ``semantic-transitions`` routes use the `typed review semantics
+`_ in ``language.rst`` sections 5.1–5.5.
+The original prose transition routes keep
+their existing contract. All new routes use JSON and the existing authentication,
+capacity, worker and error boundaries.
+
+Query accepts ``{"traces":["trace-uuid"],"references":{},"revision":1}``.
+``references`` is an optional map of canonical OA UUIDs to SA UUIDs, including
+historical deleted identities. It never guesses correspondences from names.
+``revision`` is optional; a mismatch returns 409. Select 1–100 unique existing
+trace IDs; an empty or duplicate selection returns 400 and a missing trace
+returns 404. The response includes the current revision and items containing
+``trace``, ``oa``, ``sa``, typed ``facets``, ``drift`` and ``linked_impacts``.
+Own and linked drift and their unreviewed flags remain distinct. Query reads one
+immutable snapshot, does not refresh baselines, and does not fetch artifact URIs.
+
+Preview accepts ``SemanticTransitionRequest``::
+
+ {
+ "transition": {
+ "direction": "OaToSa",
+ "sources": ["40000000-0000-4000-8000-000000000002"],
+ "scope": "SelectedOnly",
+ "mappings": [{
+ "source": "40000000-0000-4000-8000-000000000002",
+ "target": "40000000-0000-4000-8000-000000000003",
+ "target_kind": null
+ }],
+ "fields": [], "resolutions": [], "destination_diagram": null
+ },
+ "traces": {}, "references": {},
+ "reviews": [{
+ "source": "40000000-0000-4000-8000-000000000002",
+ "resolutions": [
+ {"facet":{"Header":"Name"}, "decision":"TakeSource"},
+ {"facet":{"Data":"Unit"}, "decision":"KeepTarget"}
+ ],
+ "reset": []
+ }],
+ "candidates": [], "accepted_impacts": []
+ }
+
+The example maps an existing OA data type to its traced SA counterpart, takes
+only its name and acknowledges intentionally different units. Other facets stay
+unreviewed or retain their earlier drift. Select an explicit trace through the
+``traces`` map (source UUID to trace UUID) when multiple trace kinds connect the
+pair. ``reset`` deliberately invalidates exact old selectors after changed
+correspondence. The optional collections default to empty. Semantic header
+decisions use typed facets; leave legacy ``transition.fields`` and
+``transition.resolutions`` empty.
+
+Facet selectors are closed enums, for example ``{"Data":"IntegerMinimum"}``
+or ``{"Member":{"collection":"SignalItems","keys":{"oa":"oa-uuid","sa":"sa-uuid"}}}``.
+Annotation keys contain the entire path and field; enum literal keys are exact
+strings. ``KeepTarget``, ``TakeSource`` and ``Candidate`` operate on independently
+selected facts. Candidate records use existing Element/Relation/ArtifactLink
+types, must preserve identity/alias, and must equal precisely the result of
+the selected facets. Constructor review covers its coupled introduced/removed
+fields. Membership review does not silently acknowledge order; target-only
+members remain independent. OpenAPI defines every selector and typed payload.
+
+Preview requires ``If-Match`` and returns ``{"base_revision":1,"plan":{...}}``.
+The plan contains the original typed request, mapping plan, review facts,
+acknowledged/retired selectors, linked impacts, exact prepared impacts, conflicts,
+commands, and base/prepared fingerprints. A conflict-free preview also prepares
+the complete authored source bundle and checks its model equivalence and capacity.
+No preview changes the model, source, revision or stored bytes.
+
+If ordinary preparation induces additional cleanup, the plan reports exact typed
+before/after impacts and a conflict. Review those impacts, place the accepted
+records in ``accepted_impacts``, and request another preview. Acceptance cannot
+override a contradictory selected facet. Missing mappings, ambiguous order,
+duplicate decisions, invalid candidates or unresolved impacts cannot be applied.
+This is the shared core planner and command preparation, with no server-specific
+semantic mutation engine.
+
+Apply accepts the entire preview envelope under the same ``If-Match``. It checks
+``base_revision``, the model fingerprint, unresolved conflicts, the prepared
+candidate fingerprint, ordinary model validation and coupled source preparation,
+then atomically stores one accepted model/source revision. The final store check
+also catches a concurrent edit during preparation. Source-only edits invalidate
+the preview through the shared ETag even when the model fingerprint is unchanged.
+Stale ETag/revision returns 412; semantic rejection returns 422 with code
+``semantic_transition_rejected``. Exact no-op candidates preserve revision.
+Read and preview again after a successful changed apply before reviewing further.
+
+A supplied plan remains a client-owned candidate. Fingerprints detect stale or
+inconsistent proposals; they are not tamper-proof signatures, authentication
+receipts or proof of original review authorship. Apply preserves preview-generated
+identities and does not rerun the planner with fresh random IDs. Authenticated
+clients already have ordinary model/source editing privileges. The server does
+not persist plans, tokens or review sessions.
+
+Requests allow 100 sources, trace choices and reviews; 200 mappings, candidates
+and accepted impacts; 5,000 canonical reference mappings; and 5,000 facet
+resolutions plus resets across all reviews. The legacy 400 prose-resolution
+limit and 200-command transaction limit still apply. Query has the same 5,000
+reference-map limit. Core bounded linked traversal errors remain observable as
+semantic rejection; no truncated result silently claims complete review.
+
+Schema/source 5 adds ``TraceBaseline.semantic``. Absence or null is Unreviewed;
+migrating older prose baselines does not fabricate semantic history. The persisted
+baseline contains only closed typed ``FacetReview`` facts, not whole candidate
+records or a generic JSON value tree. Historical UUIDs remain historical, including
+after deletion, and source uses explicit ``uuid`` tokens for them.
+
Error contract
--------------
diff --git a/docs/openapi.json b/docs/openapi.json
index 884b432c..08d1a073 100644
--- a/docs/openapi.json
+++ b/docs/openapi.json
@@ -3,7 +3,7 @@
"info": {
"title": "Arcadia Studio model API",
"version": "1.0.0",
- "description": "Current schema-4 snapshots and conditional atomic writes. Request body limit: 8 MiB; at most 200 nested commands; no retained revisions, request receipts, automatic retries or persistent transition plans. See docs/api.rst. Fixed store capacity: 128 models / 256 MiB serialized envelopes. Stateless transition preview/apply. Artifact URI/revision strings remain opaque core fields. Model admission before structural validation: 5,000 graph objects, 20,000 total records and 50,000 ordered references. Preparation uses snapshots outside the catalog lock; final commits recheck the exact ETag. Each accepted envelope couples model and authored source under one revision. Source-only edits advance the shared ETag. Source bundles resolve logical paths only, preserve authored files/comments, and have a stabilized JSON cap of 8 MiB, 256 files, 32 include edges along a path and 1,024 include edges overall."
+ "description": "Current schema-5 snapshots and conditional atomic writes. Request body limit: 8 MiB; at most 200 nested commands; no retained revisions, request receipts, automatic retries or persistent transition plans. See docs/api.rst. Fixed store capacity: 128 models / 256 MiB serialized envelopes. Stateless transition preview/apply. Artifact URI/revision strings remain opaque core fields. Model admission before structural validation: 5,000 graph objects, 20,000 total records and 50,000 ordered references. Preparation uses snapshots outside the catalog lock; final commits recheck the exact ETag. Each accepted envelope couples model and authored source under one revision. Source-only edits advance the shared ETag. Source bundles resolve logical paths only, preserve authored files/comments, and have a stabilized JSON cap of 8 MiB, 256 files, 32 include edges along a path and 1,024 include edges overall."
},
"servers": [
{
@@ -389,7 +389,7 @@
}
}
},
- "description": "Schema-4 native JSON is described below. Schema-1, schema-2 and schema-3 JSON/source are accepted through explicit frozen readers and migration, also on replacement and candidate validation. Reports list preserved Legacy contracts, generated FE endpoint IDs/aliases and boundary orientation defaults. Export emits schema 4 / arcadia 4. See docs/language.rst."
+ "description": "Schema-5 native JSON is described below. Schema-1/2/3/4 JSON and source are accepted through explicit frozen readers and migration, also on replacement and candidate validation. Prior prose reviews remain intact; absent semantic review stays Unreviewed. Export emits schema 5 / arcadia 5. See docs/language.rst."
}
},
"/api/v1/projects/{id}": {
@@ -1797,6 +1797,192 @@
},
"description": "Compile and validate the full submitted bundle; return accepted text with missing UUIDs inserted. Model and source persist together under the exact If-Match precondition. Comment-only or file-layout edits advance revision; an exact pair no-op retains it. Rejected candidates preserve both representations."
}
+ },
+ "/api/v1/projects/{id}/semantic-transitions/query": {
+ "post": {
+ "operationId": "querySemanticTransition",
+ "summary": "Query typed trace drift and linked impacts without mutation",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "description": "Hosted resource UUID; distinct from editable model ID.",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Validated result; preview may include unresolved conflicts.",
+ "headers": {
+ "ETag": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SemanticQueryResult"
+ }
+ }
+ }
+ },
+ "default": {
+ "$ref": "#/components/responses/Problem"
+ },
+ "409": {
+ "$ref": "#/components/responses/Problem"
+ }
+ },
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SemanticQueryRequest"
+ }
+ }
+ }
+ },
+ "description": "Read one immutable snapshot. Optional revision mismatch returns409; missing trace returns404; duplicate/empty trace selection returns400. References are canonical OA-to-SA correspondence. No write, baseline refresh or external artifact fetch."
+ }
+ },
+ "/api/v1/projects/{id}/semantic-transitions/preview": {
+ "post": {
+ "operationId": "previewSemanticTransition",
+ "summary": "Preview and source-validate a typed semantic transition without writing",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "description": "Hosted resource UUID; distinct from editable model ID.",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "If-Match",
+ "in": "header",
+ "required": true,
+ "description": "One exact strong project ETag. Missing: 428; stale: 412. Weak/list/wildcard unsupported.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Validated result; preview may include unresolved conflicts.",
+ "headers": {
+ "ETag": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SemanticTransitionEnvelope"
+ }
+ }
+ }
+ },
+ "412": {
+ "$ref": "#/components/responses/Problem"
+ },
+ "428": {
+ "$ref": "#/components/responses/Problem"
+ },
+ "default": {
+ "$ref": "#/components/responses/Problem"
+ }
+ },
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SemanticTransitionRequest"
+ }
+ }
+ }
+ },
+ "description": "Uses the frozen core typed semantic contract. A supplied plan is a client-owned candidate, not a signed receipt; fingerprints check consistency, not original review authorship. Preview validates source writeback when conflict-free. Apply preserves preview-generated IDs and does not replan random identities."
+ }
+ },
+ "/api/v1/projects/{id}/semantic-transitions/apply": {
+ "post": {
+ "operationId": "applySemanticTransition",
+ "summary": "Conditionally apply a prepared semantic candidate in one model/source revision",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "description": "Hosted resource UUID; distinct from editable model ID.",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "If-Match",
+ "in": "header",
+ "required": true,
+ "description": "One exact strong project ETag. Missing: 428; stale: 412. Weak/list/wildcard unsupported.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Validated result; preview may include unresolved conflicts.",
+ "headers": {
+ "ETag": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/MutationResult"
+ }
+ }
+ }
+ },
+ "412": {
+ "$ref": "#/components/responses/Problem"
+ },
+ "428": {
+ "$ref": "#/components/responses/Problem"
+ },
+ "default": {
+ "$ref": "#/components/responses/Problem"
+ }
+ },
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SemanticTransitionEnvelope"
+ }
+ }
+ }
+ },
+ "description": "Uses the frozen core typed semantic contract. A supplied plan is a client-owned candidate, not a signed receipt; fingerprints check consistency, not original review authorship. Preview validates source writeback when conflict-free. Apply preserves preview-generated IDs and does not replan random identities."
+ }
}
},
"components": {
@@ -4210,6 +4396,18 @@
},
"sa": {
"$ref": "#/components/schemas/TracedProperties"
+ },
+ "semantic": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/SemanticBaseline"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null,
+ "description": "Absent/null means Unreviewed. Historical typed facts never become live graph references."
}
},
"required": [
@@ -4287,7 +4485,7 @@
"properties": {
"schema_version": {
"type": "integer",
- "const": 4
+ "const": 5
},
"id": {
"type": "string",
@@ -6453,12 +6651,13 @@
"enum": [
1,
2,
- 3
+ 3,
+ 4
]
},
"to_schema": {
"type": "integer",
- "const": 4
+ "const": 5
},
"preserved_ports": {
"type": "array",
@@ -6645,11 +6844,11 @@
"required_resolutions"
],
"additionalProperties": false,
- "description": "Transient observations from explicit V1/V2/V3 to V4 migration. New report lists default to empty when reading older responses. Reading an old envelope neither saves nor changes its revision. Allocation UUIDv5 uses project namespace and v2-interface-item::- ."
+ "description": "Transient observations from explicit V1/V2/V3/V4 to V5 migration. New report lists default to empty when reading older responses. Reading an old envelope neither saves nor changes its revision. Allocation UUIDv5 uses project namespace and v2-interface-item::
- ."
},
"SourceBundle": {
"type": "object",
- "description": "Complete source4 workspace (source3 migrates explicitly). The entry is a root filename. Files use canonical portable slash-separated relative .arcadia paths and all must be reachable. Includes resolve only against this map, never the service filesystem. Up to 256 files, 32 include edges along a path and 1,024 include edges overall. Serialized bundle JSON is at most 8 MiB, checked again after missing UUIDs are inserted. GET returns exact accepted stable text.",
+ "description": "Complete source5 workspace (source3/4 migrate explicitly). The entry is a root filename. Files use canonical portable slash-separated relative .arcadia paths and all must be reachable. Includes resolve only against this map, never the service filesystem. Up to 256 files, 32 include edges along a path and 1,024 include edges overall. Serialized bundle JSON is at most 8 MiB, checked again after missing UUIDs are inserted. GET returns exact accepted stable text.",
"properties": {
"entry": {
"type": "string"
@@ -6865,6 +7064,4929 @@
"additionalProperties": false
}
]
+ },
+ "DataConstructor": {
+ "type": "string",
+ "enum": [
+ "Boolean",
+ "Integer",
+ "Real",
+ "String",
+ "Enumeration",
+ "Record"
+ ]
+ },
+ "PortConstructor": {
+ "type": "string",
+ "enum": [
+ "FunctionInput",
+ "FunctionOutput",
+ "Component",
+ "Legacy"
+ ]
+ },
+ "OccurrenceConstructor": {
+ "type": "string",
+ "enum": [
+ "Exchange",
+ "Action",
+ "Control",
+ "SequenceReference",
+ "ScenarioUse",
+ "State",
+ "Fragment",
+ "Branch"
+ ]
+ },
+ "EventConstructor": {
+ "type": "string",
+ "enum": [
+ "Signal",
+ "Time",
+ "Change"
+ ]
+ },
+ "MessageConstructor": {
+ "type": "string",
+ "enum": [
+ "Asynchronous",
+ "Call",
+ "Reply",
+ "Create",
+ "Delete",
+ "Timer"
+ ]
+ },
+ "ReferenceCollection": {
+ "type": "string",
+ "enum": [
+ "Steps",
+ "FragmentBranches",
+ "FunctionInputItems",
+ "FunctionOutputItems",
+ "SignalItems",
+ "ExchangeItems",
+ "TransitionTriggers",
+ "TransitionEffects",
+ "Constrained"
+ ]
+ },
+ "OrderedCollection": {
+ "type": "string",
+ "enum": [
+ "Steps",
+ "FragmentBranches"
+ ]
+ },
+ "IncidentEnd": {
+ "type": "string",
+ "enum": [
+ "Source",
+ "Target"
+ ]
+ },
+ "ArtifactFacet": {
+ "type": "string",
+ "enum": [
+ "Presence",
+ "Name",
+ "Description",
+ "Owner",
+ "Relation",
+ "Uri",
+ "Revision",
+ "Fragment"
+ ]
+ },
+ "ComponentPortKind": {
+ "type": "string",
+ "enum": [
+ "Standard",
+ "Flow"
+ ]
+ },
+ "ComponentPortOrientation": {
+ "type": "string",
+ "enum": [
+ "Unset",
+ "In",
+ "Out",
+ "InOut"
+ ]
+ },
+ "PortDirection": {
+ "type": "string",
+ "enum": [
+ "In",
+ "Out",
+ "InOut"
+ ]
+ },
+ "FragmentOperator": {
+ "type": "string",
+ "enum": [
+ "Alternative",
+ "Parallel",
+ "Loop",
+ "Optional"
+ ]
+ },
+ "StateActionKind": {
+ "type": "string",
+ "enum": [
+ "Entry",
+ "Do",
+ "Exit"
+ ]
+ },
+ "ArtifactRelation": {
+ "type": "string",
+ "enum": [
+ "References",
+ "Satisfies",
+ "Verifies",
+ "Implements",
+ "DerivedFrom"
+ ]
+ },
+ "HeaderFacet": {
+ "type": "string",
+ "enum": [
+ "Name",
+ "Description",
+ "Parent"
+ ]
+ },
+ "ReviewedString": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptionId": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/Id"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/Id"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "HeaderReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Name": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Name"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Description": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Description"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Parent": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Parent"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ExchangeItemFacet": {
+ "type": "string",
+ "enum": [
+ "Nature",
+ "Mechanism",
+ "Supertype"
+ ]
+ },
+ "ReviewedExchangeItemKind": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ExchangeItemKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ExchangeItemKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedExchangeMechanism": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ExchangeMechanism"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ExchangeMechanism"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ExchangeItemReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Nature": {
+ "$ref": "#/components/schemas/ReviewedExchangeItemKind"
+ }
+ },
+ "required": [
+ "Nature"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Mechanism": {
+ "$ref": "#/components/schemas/ReviewedExchangeMechanism"
+ }
+ },
+ "required": [
+ "Mechanism"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Supertype": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Supertype"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "InterfaceFacet": {
+ "type": "string",
+ "enum": [
+ "Supertype"
+ ]
+ },
+ "InterfaceReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Supertype": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Supertype"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "DataFacet": {
+ "type": "string",
+ "enum": [
+ "Constructor",
+ "IntegerMinimum",
+ "IntegerMaximum",
+ "RealMinimum",
+ "RealMaximum",
+ "StringMinimumLength",
+ "StringMaximumLength",
+ "RecordSupertype",
+ "Default",
+ "Unit"
+ ]
+ },
+ "ReviewedDataConstructor": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/DataConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/DataConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptioni64": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "minimum": -9223372036854775808,
+ "maximum": 9223372036854775807
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "minimum": -9223372036854775808,
+ "maximum": 9223372036854775807
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptionf64": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "Reviewedu32": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 4294967295
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 4294967295
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptionu32": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 4294967295
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 4294967295
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptionDataValue": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/DataValue"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/DataValue"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "DataReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Constructor": {
+ "$ref": "#/components/schemas/ReviewedDataConstructor"
+ }
+ },
+ "required": [
+ "Constructor"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "IntegerMinimum": {
+ "$ref": "#/components/schemas/ReviewedOptioni64"
+ }
+ },
+ "required": [
+ "IntegerMinimum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "IntegerMaximum": {
+ "$ref": "#/components/schemas/ReviewedOptioni64"
+ }
+ },
+ "required": [
+ "IntegerMaximum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "RealMinimum": {
+ "$ref": "#/components/schemas/ReviewedOptionf64"
+ }
+ },
+ "required": [
+ "RealMinimum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "RealMaximum": {
+ "$ref": "#/components/schemas/ReviewedOptionf64"
+ }
+ },
+ "required": [
+ "RealMaximum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "StringMinimumLength": {
+ "$ref": "#/components/schemas/Reviewedu32"
+ }
+ },
+ "required": [
+ "StringMinimumLength"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "StringMaximumLength": {
+ "$ref": "#/components/schemas/ReviewedOptionu32"
+ }
+ },
+ "required": [
+ "StringMaximumLength"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "RecordSupertype": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "RecordSupertype"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Default": {
+ "$ref": "#/components/schemas/ReviewedOptionDataValue"
+ }
+ },
+ "required": [
+ "Default"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Unit": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Unit"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "FieldFacet": {
+ "type": "string",
+ "enum": [
+ "Type",
+ "Minimum",
+ "Maximum",
+ "Unit",
+ "Direction",
+ "Storage",
+ "Default"
+ ]
+ },
+ "ReviewedTypeRef": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/TypeRef"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/TypeRef"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedParameterDirection": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ParameterDirection"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ParameterDirection"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedFieldStorage": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/FieldStorage"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/FieldStorage"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptionVecDataValue": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DataValue"
+ }
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DataValue"
+ }
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "FieldReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Type": {
+ "$ref": "#/components/schemas/ReviewedTypeRef"
+ }
+ },
+ "required": [
+ "Type"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Minimum": {
+ "$ref": "#/components/schemas/Reviewedu32"
+ }
+ },
+ "required": [
+ "Minimum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Maximum": {
+ "$ref": "#/components/schemas/ReviewedOptionu32"
+ }
+ },
+ "required": [
+ "Maximum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Unit": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Unit"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Direction": {
+ "$ref": "#/components/schemas/ReviewedParameterDirection"
+ }
+ },
+ "required": [
+ "Direction"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Storage": {
+ "$ref": "#/components/schemas/ReviewedFieldStorage"
+ }
+ },
+ "required": [
+ "Storage"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Default": {
+ "$ref": "#/components/schemas/ReviewedOptionVecDataValue"
+ }
+ },
+ "required": [
+ "Default"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "PortFacet": {
+ "type": "string",
+ "enum": [
+ "Constructor",
+ "ComponentKind",
+ "Orientation",
+ "LegacyDirection",
+ "LegacyInterface"
+ ]
+ },
+ "ReviewedPortConstructor": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/PortConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/PortConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedComponentPortKind": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ComponentPortKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ComponentPortKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedComponentPortOrientation": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ComponentPortOrientation"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ComponentPortOrientation"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedPortDirection": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/PortDirection"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/PortDirection"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "PortReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Constructor": {
+ "$ref": "#/components/schemas/ReviewedPortConstructor"
+ }
+ },
+ "required": [
+ "Constructor"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ComponentKind": {
+ "$ref": "#/components/schemas/ReviewedComponentPortKind"
+ }
+ },
+ "required": [
+ "ComponentKind"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Orientation": {
+ "$ref": "#/components/schemas/ReviewedComponentPortOrientation"
+ }
+ },
+ "required": [
+ "Orientation"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "LegacyDirection": {
+ "$ref": "#/components/schemas/ReviewedPortDirection"
+ }
+ },
+ "required": [
+ "LegacyDirection"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "LegacyInterface": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "LegacyInterface"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ScenarioFacet": {
+ "type": "string",
+ "enum": [
+ "Viewpoint",
+ "Context",
+ "Precondition",
+ "Postcondition"
+ ]
+ },
+ "ReviewedScenarioViewpoint": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ScenarioViewpoint"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ScenarioViewpoint"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ScenarioReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Viewpoint": {
+ "$ref": "#/components/schemas/ReviewedScenarioViewpoint"
+ }
+ },
+ "required": [
+ "Viewpoint"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Context": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Context"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Precondition": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Precondition"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Postcondition": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Postcondition"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "LifelineFacet": {
+ "type": "string",
+ "enum": [
+ "Represented"
+ ]
+ },
+ "LifelineReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Represented": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Represented"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "OccurrenceFacet": {
+ "type": "string",
+ "enum": [
+ "Constructor",
+ "Precondition",
+ "Postcondition",
+ "Exchange",
+ "Sender",
+ "Receiver",
+ "MessageKind",
+ "TimerExpression",
+ "ReplyTo",
+ "Action",
+ "ActionLifeline",
+ "ControlKind",
+ "Sequence",
+ "Scenario",
+ "State",
+ "StateLifeline",
+ "FragmentOperator",
+ "BranchGuard"
+ ]
+ },
+ "ReviewedOccurrenceConstructor": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/OccurrenceConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/OccurrenceConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedMessageConstructor": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/MessageConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/MessageConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedControlKind": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ControlKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ControlKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedFragmentOperator": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/FragmentOperator"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/FragmentOperator"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "OccurrenceReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Constructor": {
+ "$ref": "#/components/schemas/ReviewedOccurrenceConstructor"
+ }
+ },
+ "required": [
+ "Constructor"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Precondition": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Precondition"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Postcondition": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Postcondition"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Exchange": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Exchange"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Sender": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Sender"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Receiver": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Receiver"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "MessageKind": {
+ "$ref": "#/components/schemas/ReviewedMessageConstructor"
+ }
+ },
+ "required": [
+ "MessageKind"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TimerExpression": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "TimerExpression"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ReplyTo": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "ReplyTo"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Action": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Action"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ActionLifeline": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "ActionLifeline"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ControlKind": {
+ "$ref": "#/components/schemas/ReviewedControlKind"
+ }
+ },
+ "required": [
+ "ControlKind"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Sequence": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Sequence"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Scenario": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "Scenario"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "State": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "State"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "StateLifeline": {
+ "$ref": "#/components/schemas/ReviewedOptionId"
+ }
+ },
+ "required": [
+ "StateLifeline"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "FragmentOperator": {
+ "$ref": "#/components/schemas/ReviewedFragmentOperator"
+ }
+ },
+ "required": [
+ "FragmentOperator"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "BranchGuard": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "BranchGuard"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "EventFacet": {
+ "type": "string",
+ "enum": [
+ "Constructor",
+ "TimeKind",
+ "TimeExpression",
+ "ChangeExpression"
+ ]
+ },
+ "ReviewedEventConstructor": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/EventConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/EventConstructor"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedTimeEventKind": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/TimeEventKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/TimeEventKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "EventReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Constructor": {
+ "$ref": "#/components/schemas/ReviewedEventConstructor"
+ }
+ },
+ "required": [
+ "Constructor"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TimeKind": {
+ "$ref": "#/components/schemas/ReviewedTimeEventKind"
+ }
+ },
+ "required": [
+ "TimeKind"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TimeExpression": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "TimeExpression"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ChangeExpression": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "ChangeExpression"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "StateFacet": {
+ "type": "string",
+ "enum": [
+ "Kind",
+ "Entry",
+ "Exit",
+ "DoActivity"
+ ]
+ },
+ "ReviewedStateKind": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/StateKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/StateKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "StateReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Kind": {
+ "$ref": "#/components/schemas/ReviewedStateKind"
+ }
+ },
+ "required": [
+ "Kind"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Entry": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Entry"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Exit": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Exit"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "DoActivity": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "DoActivity"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ConstraintFacet": {
+ "type": "string",
+ "enum": [
+ "Expression"
+ ]
+ },
+ "ConstraintReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Expression": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Expression"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "RelationFacet": {
+ "type": "string",
+ "enum": [
+ "Source",
+ "Target",
+ "AllocationOrder",
+ "Transmission",
+ "Acquisition",
+ "SourceRole",
+ "TargetRole",
+ "SourceMinimum",
+ "SourceMaximum",
+ "TargetMinimum",
+ "TargetMaximum",
+ "SourceNavigable",
+ "TargetNavigable",
+ "SourcePort",
+ "TargetPort",
+ "Oriented",
+ "ExtendCondition",
+ "SequenceGuard",
+ "TransitionKind",
+ "Trigger",
+ "Guard",
+ "Effect",
+ "StateActionPhase"
+ ]
+ },
+ "ReviewedId": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/Id"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/Id"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedTransmissionProtocol": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/TransmissionProtocol"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/TransmissionProtocol"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedAcquisitionProtocol": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/AcquisitionProtocol"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/AcquisitionProtocol"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "Reviewedbool": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedTransitionKind": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/TransitionKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/TransitionKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedStateActionKind": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/StateActionKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/StateActionKind"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "RelationReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Source": {
+ "$ref": "#/components/schemas/ReviewedId"
+ }
+ },
+ "required": [
+ "Source"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Target": {
+ "$ref": "#/components/schemas/ReviewedId"
+ }
+ },
+ "required": [
+ "Target"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "AllocationOrder": {
+ "$ref": "#/components/schemas/Reviewedu32"
+ }
+ },
+ "required": [
+ "AllocationOrder"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Transmission": {
+ "$ref": "#/components/schemas/ReviewedTransmissionProtocol"
+ }
+ },
+ "required": [
+ "Transmission"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Acquisition": {
+ "$ref": "#/components/schemas/ReviewedAcquisitionProtocol"
+ }
+ },
+ "required": [
+ "Acquisition"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "SourceRole": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "SourceRole"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TargetRole": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "TargetRole"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "SourceMinimum": {
+ "$ref": "#/components/schemas/Reviewedu32"
+ }
+ },
+ "required": [
+ "SourceMinimum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "SourceMaximum": {
+ "$ref": "#/components/schemas/ReviewedOptionu32"
+ }
+ },
+ "required": [
+ "SourceMaximum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TargetMinimum": {
+ "$ref": "#/components/schemas/Reviewedu32"
+ }
+ },
+ "required": [
+ "TargetMinimum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TargetMaximum": {
+ "$ref": "#/components/schemas/ReviewedOptionu32"
+ }
+ },
+ "required": [
+ "TargetMaximum"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "SourceNavigable": {
+ "$ref": "#/components/schemas/Reviewedbool"
+ }
+ },
+ "required": [
+ "SourceNavigable"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TargetNavigable": {
+ "$ref": "#/components/schemas/Reviewedbool"
+ }
+ },
+ "required": [
+ "TargetNavigable"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "SourcePort": {
+ "$ref": "#/components/schemas/ReviewedId"
+ }
+ },
+ "required": [
+ "SourcePort"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TargetPort": {
+ "$ref": "#/components/schemas/ReviewedId"
+ }
+ },
+ "required": [
+ "TargetPort"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Oriented": {
+ "$ref": "#/components/schemas/Reviewedbool"
+ }
+ },
+ "required": [
+ "Oriented"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ExtendCondition": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "ExtendCondition"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "SequenceGuard": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "SequenceGuard"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "TransitionKind": {
+ "$ref": "#/components/schemas/ReviewedTransitionKind"
+ }
+ },
+ "required": [
+ "TransitionKind"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Trigger": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Trigger"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Guard": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Guard"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Effect": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Effect"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "StateActionPhase": {
+ "$ref": "#/components/schemas/ReviewedStateActionKind"
+ }
+ },
+ "required": [
+ "StateActionPhase"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "AnnotationKey": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Id"
+ }
+ },
+ "field": {
+ "$ref": "#/components/schemas/Id"
+ }
+ },
+ "required": [
+ "path",
+ "field"
+ ],
+ "additionalProperties": false
+ },
+ "KeyPairId": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/Id"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "sa": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/Id"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [],
+ "additionalProperties": false
+ },
+ "KeyPairString": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "sa": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [],
+ "additionalProperties": false
+ },
+ "KeyPairAnnotationKey": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/AnnotationKey"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "sa": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/AnnotationKey"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [],
+ "additionalProperties": false
+ },
+ "ReviewedArtifactRelation": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ArtifactRelation"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "$ref": "#/components/schemas/ArtifactRelation"
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptionString": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ArtifactReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Presence": {
+ "$ref": "#/components/schemas/Reviewedbool"
+ }
+ },
+ "required": [
+ "Presence"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Name": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Name"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Description": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Description"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Owner": {
+ "$ref": "#/components/schemas/ReviewedId"
+ }
+ },
+ "required": [
+ "Owner"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Relation": {
+ "$ref": "#/components/schemas/ReviewedArtifactRelation"
+ }
+ },
+ "required": [
+ "Relation"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Uri": {
+ "$ref": "#/components/schemas/ReviewedString"
+ }
+ },
+ "required": [
+ "Uri"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Revision": {
+ "$ref": "#/components/schemas/ReviewedOptionString"
+ }
+ },
+ "required": [
+ "Revision"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Fragment": {
+ "$ref": "#/components/schemas/ReviewedOptionString"
+ }
+ },
+ "required": [
+ "Fragment"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ReviewedVecId": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Id"
+ }
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Id"
+ }
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptionMessageValue": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/MessageValue"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/MessageValue"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "ReviewedOptionLifelineBinding": {
+ "type": "object",
+ "properties": {
+ "oa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/LifelineBinding"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "sa": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "NotApplicable"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Value": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/LifelineBinding"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "Value"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "oa",
+ "sa"
+ ],
+ "additionalProperties": false
+ },
+ "FacetSelector": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Header": {
+ "$ref": "#/components/schemas/HeaderFacet"
+ }
+ },
+ "required": [
+ "Header"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ExchangeItem": {
+ "$ref": "#/components/schemas/ExchangeItemFacet"
+ }
+ },
+ "required": [
+ "ExchangeItem"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Interface": {
+ "$ref": "#/components/schemas/InterfaceFacet"
+ }
+ },
+ "required": [
+ "Interface"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Data": {
+ "$ref": "#/components/schemas/DataFacet"
+ }
+ },
+ "required": [
+ "Data"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Field": {
+ "$ref": "#/components/schemas/FieldFacet"
+ }
+ },
+ "required": [
+ "Field"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Port": {
+ "$ref": "#/components/schemas/PortFacet"
+ }
+ },
+ "required": [
+ "Port"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Scenario": {
+ "$ref": "#/components/schemas/ScenarioFacet"
+ }
+ },
+ "required": [
+ "Scenario"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Lifeline": {
+ "$ref": "#/components/schemas/LifelineFacet"
+ }
+ },
+ "required": [
+ "Lifeline"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Occurrence": {
+ "$ref": "#/components/schemas/OccurrenceFacet"
+ }
+ },
+ "required": [
+ "Occurrence"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Event": {
+ "$ref": "#/components/schemas/EventFacet"
+ }
+ },
+ "required": [
+ "Event"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "State": {
+ "$ref": "#/components/schemas/StateFacet"
+ }
+ },
+ "required": [
+ "State"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Constraint": {
+ "$ref": "#/components/schemas/ConstraintFacet"
+ }
+ },
+ "required": [
+ "Constraint"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Relation": {
+ "$ref": "#/components/schemas/RelationFacet"
+ }
+ },
+ "required": [
+ "Relation"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Member": {
+ "type": "object",
+ "properties": {
+ "collection": {
+ "$ref": "#/components/schemas/ReferenceCollection"
+ },
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairId"
+ }
+ },
+ "required": [
+ "collection",
+ "keys"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Member"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Order": {
+ "$ref": "#/components/schemas/OrderedCollection"
+ }
+ },
+ "required": [
+ "Order"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Literal": {
+ "$ref": "#/components/schemas/KeyPairString"
+ }
+ },
+ "required": [
+ "Literal"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Annotation": {
+ "$ref": "#/components/schemas/KeyPairAnnotationKey"
+ }
+ },
+ "required": [
+ "Annotation"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Binding": {
+ "$ref": "#/components/schemas/KeyPairId"
+ }
+ },
+ "required": [
+ "Binding"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Child": {
+ "$ref": "#/components/schemas/KeyPairId"
+ }
+ },
+ "required": [
+ "Child"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Incident": {
+ "type": "object",
+ "properties": {
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairId"
+ },
+ "end": {
+ "$ref": "#/components/schemas/IncidentEnd"
+ }
+ },
+ "required": [
+ "keys",
+ "end"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Incident"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Artifact": {
+ "type": "object",
+ "properties": {
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairId"
+ },
+ "facet": {
+ "$ref": "#/components/schemas/ArtifactFacet"
+ }
+ },
+ "required": [
+ "keys",
+ "facet"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Artifact"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "FacetReview": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Header": {
+ "$ref": "#/components/schemas/HeaderReview"
+ }
+ },
+ "required": [
+ "Header"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ExchangeItem": {
+ "$ref": "#/components/schemas/ExchangeItemReview"
+ }
+ },
+ "required": [
+ "ExchangeItem"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Interface": {
+ "$ref": "#/components/schemas/InterfaceReview"
+ }
+ },
+ "required": [
+ "Interface"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Data": {
+ "$ref": "#/components/schemas/DataReview"
+ }
+ },
+ "required": [
+ "Data"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Field": {
+ "$ref": "#/components/schemas/FieldReview"
+ }
+ },
+ "required": [
+ "Field"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Port": {
+ "$ref": "#/components/schemas/PortReview"
+ }
+ },
+ "required": [
+ "Port"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Scenario": {
+ "$ref": "#/components/schemas/ScenarioReview"
+ }
+ },
+ "required": [
+ "Scenario"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Lifeline": {
+ "$ref": "#/components/schemas/LifelineReview"
+ }
+ },
+ "required": [
+ "Lifeline"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Occurrence": {
+ "$ref": "#/components/schemas/OccurrenceReview"
+ }
+ },
+ "required": [
+ "Occurrence"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Event": {
+ "$ref": "#/components/schemas/EventReview"
+ }
+ },
+ "required": [
+ "Event"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "State": {
+ "$ref": "#/components/schemas/StateReview"
+ }
+ },
+ "required": [
+ "State"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Constraint": {
+ "$ref": "#/components/schemas/ConstraintReview"
+ }
+ },
+ "required": [
+ "Constraint"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Relation": {
+ "$ref": "#/components/schemas/RelationReview"
+ }
+ },
+ "required": [
+ "Relation"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Member": {
+ "type": "object",
+ "properties": {
+ "collection": {
+ "$ref": "#/components/schemas/ReferenceCollection"
+ },
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairId"
+ },
+ "review": {
+ "$ref": "#/components/schemas/Reviewedbool"
+ }
+ },
+ "required": [
+ "collection",
+ "keys",
+ "review"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Member"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Order": {
+ "type": "object",
+ "properties": {
+ "collection": {
+ "$ref": "#/components/schemas/OrderedCollection"
+ },
+ "review": {
+ "$ref": "#/components/schemas/ReviewedVecId"
+ }
+ },
+ "required": [
+ "collection",
+ "review"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Order"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Literal": {
+ "type": "object",
+ "properties": {
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairString"
+ },
+ "review": {
+ "$ref": "#/components/schemas/Reviewedbool"
+ }
+ },
+ "required": [
+ "keys",
+ "review"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Literal"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Annotation": {
+ "type": "object",
+ "properties": {
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairAnnotationKey"
+ },
+ "review": {
+ "$ref": "#/components/schemas/ReviewedOptionMessageValue"
+ }
+ },
+ "required": [
+ "keys",
+ "review"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Annotation"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Binding": {
+ "type": "object",
+ "properties": {
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairId"
+ },
+ "review": {
+ "$ref": "#/components/schemas/ReviewedOptionLifelineBinding"
+ }
+ },
+ "required": [
+ "keys",
+ "review"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Binding"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Child": {
+ "type": "object",
+ "properties": {
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairId"
+ },
+ "review": {
+ "$ref": "#/components/schemas/Reviewedbool"
+ }
+ },
+ "required": [
+ "keys",
+ "review"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Child"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Incident": {
+ "type": "object",
+ "properties": {
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairId"
+ },
+ "end": {
+ "$ref": "#/components/schemas/IncidentEnd"
+ },
+ "review": {
+ "$ref": "#/components/schemas/Reviewedbool"
+ }
+ },
+ "required": [
+ "keys",
+ "end",
+ "review"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Incident"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Artifact": {
+ "type": "object",
+ "properties": {
+ "keys": {
+ "$ref": "#/components/schemas/KeyPairId"
+ },
+ "review": {
+ "$ref": "#/components/schemas/ArtifactReview"
+ }
+ },
+ "required": [
+ "keys",
+ "review"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "Artifact"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "SemanticBaseline": {
+ "type": "object",
+ "properties": {
+ "facets": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FacetReview"
+ }
+ }
+ },
+ "required": [
+ "facets"
+ ],
+ "additionalProperties": false
+ },
+ "Drift": {
+ "type": "string",
+ "enum": [
+ "Unreviewed",
+ "Unchanged",
+ "OaChanged",
+ "SaChanged",
+ "BothChanged"
+ ]
+ },
+ "FacetDrift": {
+ "type": "object",
+ "properties": {
+ "selector": {
+ "$ref": "#/components/schemas/FacetSelector"
+ },
+ "current": {
+ "$ref": "#/components/schemas/FacetReview"
+ },
+ "drift": {
+ "$ref": "#/components/schemas/Drift"
+ }
+ },
+ "required": [
+ "selector",
+ "current",
+ "drift"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticDrift": {
+ "type": "object",
+ "properties": {
+ "own": {
+ "$ref": "#/components/schemas/Drift"
+ },
+ "linked": {
+ "$ref": "#/components/schemas/Drift"
+ },
+ "own_unreviewed": {
+ "type": "boolean"
+ },
+ "linked_unreviewed": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "own",
+ "linked",
+ "own_unreviewed",
+ "linked_unreviewed"
+ ],
+ "additionalProperties": false
+ },
+ "LinkedSemanticImpact": {
+ "type": "object",
+ "properties": {
+ "objects": {
+ "$ref": "#/components/schemas/KeyPairId"
+ },
+ "traces": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Id"
+ }
+ },
+ "drift": {
+ "$ref": "#/components/schemas/Drift"
+ },
+ "unreviewed": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "objects",
+ "traces",
+ "drift",
+ "unreviewed"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticRecord": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Element": {
+ "$ref": "#/components/schemas/Element"
+ }
+ },
+ "required": [
+ "Element"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Relation": {
+ "$ref": "#/components/schemas/Relation"
+ }
+ },
+ "required": [
+ "Relation"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Artifact": {
+ "$ref": "#/components/schemas/ArtifactLink"
+ }
+ },
+ "required": [
+ "Artifact"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "ImpactRecord": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "Element": {
+ "$ref": "#/components/schemas/Element"
+ }
+ },
+ "required": [
+ "Element"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Relation": {
+ "$ref": "#/components/schemas/Relation"
+ }
+ },
+ "required": [
+ "Relation"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Artifact": {
+ "$ref": "#/components/schemas/ArtifactLink"
+ }
+ },
+ "required": [
+ "Artifact"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Diagram": {
+ "$ref": "#/components/schemas/Diagram"
+ }
+ },
+ "required": [
+ "Diagram"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "Trace": {
+ "$ref": "#/components/schemas/Trace"
+ }
+ },
+ "required": [
+ "Trace"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "SemanticImpact": {
+ "type": "object",
+ "properties": {
+ "object": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "before": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/ImpactRecord"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "after": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/ImpactRecord"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "object"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticDecision": {
+ "type": "string",
+ "enum": [
+ "KeepTarget",
+ "TakeSource",
+ "Candidate"
+ ]
+ },
+ "FacetResolution": {
+ "type": "object",
+ "properties": {
+ "facet": {
+ "$ref": "#/components/schemas/FacetSelector"
+ },
+ "decision": {
+ "$ref": "#/components/schemas/SemanticDecision"
+ }
+ },
+ "required": [
+ "facet",
+ "decision"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticReviewRequest": {
+ "type": "object",
+ "properties": {
+ "source": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "resolutions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FacetResolution"
+ },
+ "maxItems": 5000
+ },
+ "reset": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FacetSelector"
+ },
+ "maxItems": 5000,
+ "default": []
+ }
+ },
+ "required": [
+ "source",
+ "resolutions"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticTransitionRequest": {
+ "type": "object",
+ "properties": {
+ "transition": {
+ "$ref": "#/components/schemas/TransitionRequest"
+ },
+ "traces": {
+ "type": "object",
+ "propertyNames": {
+ "format": "uuid"
+ },
+ "additionalProperties": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "maxProperties": 100,
+ "default": {}
+ },
+ "references": {
+ "type": "object",
+ "propertyNames": {
+ "format": "uuid"
+ },
+ "additionalProperties": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "maxProperties": 5000,
+ "default": {}
+ },
+ "reviews": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SemanticReviewRequest"
+ },
+ "maxItems": 100,
+ "default": []
+ },
+ "candidates": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SemanticRecord"
+ },
+ "maxItems": 200,
+ "default": []
+ },
+ "accepted_impacts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SemanticImpact"
+ },
+ "maxItems": 200,
+ "default": []
+ }
+ },
+ "required": [
+ "transition"
+ ],
+ "additionalProperties": false,
+ "description": "Canonical OA-to-SA references include historical UUIDs. Traces map selected source IDs to trace IDs. Combined resolutions/reset limit: 5,000. Candidates must equal exactly the result of their selected facets; accepted_impacts explicitly acknowledge exact induced changes."
+ },
+ "SemanticReviewPreview": {
+ "type": "object",
+ "properties": {
+ "source": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "target": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "facets": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FacetDrift"
+ }
+ },
+ "acknowledged": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FacetSelector"
+ }
+ },
+ "retired": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FacetSelector"
+ }
+ },
+ "linked_impacts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LinkedSemanticImpact"
+ }
+ }
+ },
+ "required": [
+ "source",
+ "target",
+ "facets",
+ "acknowledged",
+ "retired",
+ "linked_impacts"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticTransitionPlan": {
+ "type": "object",
+ "properties": {
+ "base_fingerprint": {
+ "type": "string"
+ },
+ "request": {
+ "$ref": "#/components/schemas/SemanticTransitionRequest"
+ },
+ "transition": {
+ "$ref": "#/components/schemas/TransitionPlan"
+ },
+ "reviews": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SemanticReviewPreview"
+ }
+ },
+ "impacts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SemanticImpact"
+ }
+ },
+ "conflicts": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "commands": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Command"
+ },
+ "maxItems": 200
+ },
+ "prepared_fingerprint": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "base_fingerprint",
+ "request",
+ "transition",
+ "reviews",
+ "impacts",
+ "conflicts",
+ "commands"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticTransitionEnvelope": {
+ "type": "object",
+ "properties": {
+ "base_revision": {
+ "$ref": "#/components/schemas/Revision"
+ },
+ "plan": {
+ "$ref": "#/components/schemas/SemanticTransitionPlan"
+ }
+ },
+ "required": [
+ "base_revision",
+ "plan"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticQueryRequest": {
+ "type": "object",
+ "properties": {
+ "traces": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "maxItems": 100,
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "references": {
+ "type": "object",
+ "propertyNames": {
+ "format": "uuid"
+ },
+ "additionalProperties": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "maxProperties": 5000,
+ "default": {}
+ },
+ "revision": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/Revision"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "traces"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticQueryItem": {
+ "type": "object",
+ "properties": {
+ "trace": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "oa": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "sa": {
+ "$ref": "#/components/schemas/Id"
+ },
+ "facets": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FacetDrift"
+ }
+ },
+ "drift": {
+ "$ref": "#/components/schemas/SemanticDrift"
+ },
+ "linked_impacts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LinkedSemanticImpact"
+ }
+ }
+ },
+ "required": [
+ "trace",
+ "oa",
+ "sa",
+ "facets",
+ "drift",
+ "linked_impacts"
+ ],
+ "additionalProperties": false
+ },
+ "SemanticQueryResult": {
+ "type": "object",
+ "properties": {
+ "revision": {
+ "$ref": "#/components/schemas/Revision"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SemanticQueryItem"
+ },
+ "maxItems": 100
+ }
+ },
+ "required": [
+ "revision",
+ "items"
+ ],
+ "additionalProperties": false
}
}
}