Checkpoint source 7 workflows and in-progress diagram authoring redesign
Rust checks / check (ubuntu-latest) (push) Canceled after 0s
Rust checks / check (windows-latest) (push) Canceled after 0s

Preserve current core, source, REST, desktop, recovery, documentation and validation work, including AGENTS.md and the development summary. This is a work-in-progress checkpoint: the new compact palette has outstanding compilation errors and native acceptance; earlier passing gates retain their documented scope.
This commit is contained in:
Codex
2026-09-10 10:06:55 -07:00
parent 4b6b5fc197
commit e2ecfea69b
162 changed files with 17595 additions and 926 deletions
+97 -7
View File
@@ -81,6 +81,12 @@ pub struct CommunicationEndpointDecision {
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct OperationOmission {
pub source: Id,
pub rationale: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TransitionRequest {
pub direction: TransitionDirection,
pub sources: Vec<Id>,
@@ -91,6 +97,8 @@ pub struct TransitionRequest {
pub destination_diagram: Option<Id>,
#[serde(default)]
pub communication_endpoints: Vec<CommunicationEndpointDecision>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub operation_omissions: Vec<OperationOmission>,
}
impl TransitionRequest {
pub fn new(direction: TransitionDirection, sources: Vec<Id>) -> Self {
@@ -103,6 +111,7 @@ impl TransitionRequest {
resolutions: vec![],
destination_diagram: None,
communication_endpoints: vec![],
operation_omissions: vec![],
}
}
}
@@ -319,6 +328,7 @@ fn mapped_relation(r: &Relation, direction: TransitionDirection) -> Option<Relat
| RelationBody::MissionInvolvement { .. }
| RelationBody::MissionCapability { .. }
| RelationBody::SequenceLink { .. }
| RelationBody::ContextualLink { .. }
| RelationBody::ChainInvolvement { .. }
| RelationBody::BoundaryExchange { .. }
| RelationBody::InterfaceProvision { .. }
@@ -500,7 +510,16 @@ pub fn plan_transition(
continue;
}
if let Some(e) = project.elements.get(&id) {
selected.extend(crate::references::element_references(e));
let mut dependencies = e.clone();
if request.direction == TransitionDirection::SaToOa
&& let Some(SharedBody::Occurrence {
body: OccurrenceBody::Exchange { operation, .. },
..
}) = dependencies.shared_mut()
{
*operation = None;
}
selected.extend(crate::references::element_references(&dependencies));
// Allocations are owned by interfaces. Independent data
// associations travel only when both endpoint types are
// already required; they do not expand the dictionary.
@@ -523,12 +542,13 @@ pub fn plan_transition(
// their endpoint involvements, independently of list order.
if matches!(e.kind(), Kind::Process | Kind::FunctionalChain) {
selected.extend(project.relations.values().filter_map(|relation| {
(relation.kind() == RelationKind::SequenceLink
&& project
.elements
.get(&relation.source())
.and_then(|e| e.parent)
== Some(id))
(relation.contextual_owner() == Some(id)
|| (relation.kind() == RelationKind::SequenceLink
&& project
.elements
.get(&relation.source())
.and_then(|e| e.parent)
== Some(id)))
.then_some(relation.id)
}));
}
@@ -594,6 +614,67 @@ pub fn plan_transition(
false
} else { true }
});
let mut operation_omissions = BTreeSet::new();
for decision in &request.operation_omissions {
if request.direction != TransitionDirection::SaToOa
|| !selected.contains(&decision.source)
|| !matches!(
project
.elements
.get(&decision.source)
.and_then(Element::shared),
Some(SharedBody::Occurrence {
body: OccurrenceBody::Exchange {
operation: Some(_),
message_kind: MessageKind::Call | MessageKind::Asynchronous,
..
},
..
})
)
|| decision.rationale.trim().is_empty()
|| !validation::valid_text(&decision.rationale)
|| !operation_omissions.insert(decision.source)
{
conflict(
&mut plan,
Some(decision.source),
None,
None,
"Operation omission needs one selected SA invocation, SA→OA direction, and a nonempty rationale; irrelevant or duplicate decisions reject.",
);
} else {
plan.warnings.push(format!(
"Reviewed operation omission: {} ({}): {}. Source contract is preserved.",
project.named(decision.source),
decision.source,
decision.rationale
));
}
}
if request.direction == TransitionDirection::SaToOa {
for source in &selected {
if matches!(
project.elements.get(source).and_then(Element::shared),
Some(SharedBody::Occurrence {
body: OccurrenceBody::Exchange {
operation: Some(_),
..
},
..
})
) && !operation_omissions.contains(source)
{
conflict(
&mut plan,
Some(*source),
None,
None,
"This technical operation has no OA operation slot. Review an explicit per-invocation omission with rationale; Reply derives the Call's decision.",
);
}
}
}
let mut choices = BTreeMap::new();
for mapping in &request.mappings {
if choices.insert(mapping.source, mapping).is_some() {
@@ -787,6 +868,15 @@ pub fn plan_transition(
let mut created = e.clone();
created.id = target;
created.body = body;
if request.direction == TransitionDirection::SaToOa
&& operation_omissions.contains(source)
&& let Some(SharedBody::Occurrence {
body: OccurrenceBody::Exchange { operation, .. },
..
}) = created.shared_mut()
{
*operation = None;
}
created.alias = working.fresh_alias(
&format!(
"{}_{}",