Verify qualified scenario values through HTTP and record R6 evidence
This commit is contained in:
@@ -315,3 +315,420 @@ async fn existing_schema3_coupled_envelope_upgrades_in_memory_until_explicit_sav
|
|||||||
assert_eq!(std::fs::read(&filename).unwrap(), bytes);
|
assert_eq!(std::fs::read(&filename).unwrap(), bytes);
|
||||||
server.stop().await;
|
server.stop().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn qualified_call_reply_values_reject_invalid_edits_and_survive_identity_source_and_restart()
|
||||||
|
{
|
||||||
|
use oa_core::{
|
||||||
|
Element, FieldStorage, MessageKind, MessageValue, OccurrenceBody, ParameterDirection,
|
||||||
|
PortContract, RelationBody, ScenarioViewpoint, TypeRef,
|
||||||
|
};
|
||||||
|
fn values(model: &Project, occurrence: Id) -> &[MessageValue] {
|
||||||
|
let Some(SharedBody::Occurrence {
|
||||||
|
body: OccurrenceBody::Exchange { values, .. },
|
||||||
|
..
|
||||||
|
}) = model.elements[&occurrence].shared()
|
||||||
|
else {
|
||||||
|
panic!("Expected message");
|
||||||
|
};
|
||||||
|
values
|
||||||
|
}
|
||||||
|
fn edited_values(model: &Project, occurrence: Id, next: Vec<MessageValue>) -> Element {
|
||||||
|
let mut element = model.elements[&occurrence].clone();
|
||||||
|
let Some(SharedBody::Occurrence {
|
||||||
|
body: OccurrenceBody::Exchange { values, .. },
|
||||||
|
..
|
||||||
|
}) = element.shared_mut()
|
||||||
|
else {
|
||||||
|
panic!("Expected message");
|
||||||
|
};
|
||||||
|
*values = next;
|
||||||
|
element
|
||||||
|
}
|
||||||
|
let mut model = documented_data();
|
||||||
|
let operation = id(&model, "navigate");
|
||||||
|
let coordinate = id(&model, "coordinate");
|
||||||
|
let located = id(&model, "located");
|
||||||
|
let latitude = id(&model, "latitude");
|
||||||
|
let origin = id(&model, "origin");
|
||||||
|
let destination = id(&model, "destination");
|
||||||
|
let accepted = id(&model, "accepted");
|
||||||
|
// The second parameter inherits the very same latitude identity.
|
||||||
|
let Some(SharedBody::DataField { type_ref, .. }) =
|
||||||
|
model.elements.get_mut(&destination).unwrap().shared_mut()
|
||||||
|
else {
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
*type_ref = TypeRef::Named(located);
|
||||||
|
let next = model
|
||||||
|
.add_element(
|
||||||
|
Kind::DataField,
|
||||||
|
Layer::Sa,
|
||||||
|
"Next coordinate",
|
||||||
|
Some(coordinate),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
*model.elements.get_mut(&next).unwrap().shared_mut().unwrap() = SharedBody::DataField {
|
||||||
|
type_ref: TypeRef::Named(coordinate),
|
||||||
|
minimum: 0,
|
||||||
|
maximum: Some(1),
|
||||||
|
direction: ParameterDirection::Unspecified,
|
||||||
|
storage: FieldStorage::Value,
|
||||||
|
unit: String::new(),
|
||||||
|
default: None,
|
||||||
|
};
|
||||||
|
let requester = model
|
||||||
|
.add_element(Kind::Function, Layer::Sa, "Request navigation", None)
|
||||||
|
.unwrap();
|
||||||
|
let provider = model
|
||||||
|
.add_element(Kind::Function, Layer::Sa, "Provide navigation", None)
|
||||||
|
.unwrap();
|
||||||
|
let output = Id::new_v4();
|
||||||
|
let input = Id::new_v4();
|
||||||
|
for (port, contract) in [
|
||||||
|
(
|
||||||
|
output,
|
||||||
|
PortContract::FunctionOutput {
|
||||||
|
outgoing_items: vec![operation],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
input,
|
||||||
|
PortContract::FunctionInput {
|
||||||
|
incoming_items: vec![operation],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
] {
|
||||||
|
let (owner, name) = if port == output {
|
||||||
|
(requester, "Navigation output")
|
||||||
|
} else {
|
||||||
|
(provider, "Navigation input")
|
||||||
|
};
|
||||||
|
let element = oa_core::ports::make_port(&model, port, owner, name, contract).unwrap();
|
||||||
|
model.elements.insert(port, element);
|
||||||
|
}
|
||||||
|
let exchange = model.relate(
|
||||||
|
RelationKind::FunctionalExchange,
|
||||||
|
"Navigation request",
|
||||||
|
requester,
|
||||||
|
provider,
|
||||||
|
);
|
||||||
|
model.relations.get_mut(&exchange).unwrap().body = RelationBody::FunctionalExchange {
|
||||||
|
source: requester,
|
||||||
|
target: provider,
|
||||||
|
source_port: output,
|
||||||
|
target_port: input,
|
||||||
|
items: vec![operation],
|
||||||
|
};
|
||||||
|
let scenario = model
|
||||||
|
.add_element(Kind::Scenario, Layer::Sa, "Navigation conversation", None)
|
||||||
|
.unwrap();
|
||||||
|
let Some(SharedBody::Scenario { viewpoint, .. }) =
|
||||||
|
model.elements.get_mut(&scenario).unwrap().shared_mut()
|
||||||
|
else {
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
*viewpoint = ScenarioViewpoint::Functional;
|
||||||
|
let sender = model
|
||||||
|
.add_element(Kind::Lifeline, Layer::Sa, "Requester line", Some(scenario))
|
||||||
|
.unwrap();
|
||||||
|
let receiver = model
|
||||||
|
.add_element(Kind::Lifeline, Layer::Sa, "Provider line", Some(scenario))
|
||||||
|
.unwrap();
|
||||||
|
for (line, represented) in [(sender, requester), (receiver, provider)] {
|
||||||
|
*model.elements.get_mut(&line).unwrap().shared_mut().unwrap() = SharedBody::Lifeline {
|
||||||
|
represented: Some(represented),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let call = model
|
||||||
|
.add_element(
|
||||||
|
Kind::Occurrence,
|
||||||
|
Layer::Sa,
|
||||||
|
"Navigation call",
|
||||||
|
Some(scenario),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let reply = model
|
||||||
|
.add_element(
|
||||||
|
Kind::Occurrence,
|
||||||
|
Layer::Sa,
|
||||||
|
"Navigation reply",
|
||||||
|
Some(scenario),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
for (occurrence, message_kind, from, to, reply_to) in [
|
||||||
|
(call, MessageKind::Call, sender, receiver, None),
|
||||||
|
(reply, MessageKind::Reply, receiver, sender, Some(call)),
|
||||||
|
] {
|
||||||
|
*model
|
||||||
|
.elements
|
||||||
|
.get_mut(&occurrence)
|
||||||
|
.unwrap()
|
||||||
|
.shared_mut()
|
||||||
|
.unwrap() = SharedBody::Occurrence {
|
||||||
|
body: OccurrenceBody::Exchange {
|
||||||
|
exchange: Some(exchange),
|
||||||
|
sender: Some(from),
|
||||||
|
receiver: Some(to),
|
||||||
|
message_kind,
|
||||||
|
reply_to,
|
||||||
|
values: vec![],
|
||||||
|
},
|
||||||
|
precondition: String::new(),
|
||||||
|
postcondition: String::new(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
model
|
||||||
|
.elements
|
||||||
|
.get_mut(&scenario)
|
||||||
|
.unwrap()
|
||||||
|
.steps_mut()
|
||||||
|
.unwrap()
|
||||||
|
.extend([call, reply]);
|
||||||
|
oa_core::validate_candidate(&model).unwrap();
|
||||||
|
|
||||||
|
let directory = tempfile::tempdir().unwrap();
|
||||||
|
let server = TestServer::start(directory.path(), None).await;
|
||||||
|
let (resource, _) = server.import(&model).await;
|
||||||
|
let before = server.get(resource).await;
|
||||||
|
let call_values = vec![
|
||||||
|
MessageValue {
|
||||||
|
path: vec![origin],
|
||||||
|
field: latitude,
|
||||||
|
expression: " origin.latitude\n+ 0.25 ".into(),
|
||||||
|
},
|
||||||
|
MessageValue {
|
||||||
|
path: vec![destination],
|
||||||
|
field: latitude,
|
||||||
|
expression: "destination.latitude".into(),
|
||||||
|
},
|
||||||
|
MessageValue {
|
||||||
|
path: vec![origin, next],
|
||||||
|
field: latitude,
|
||||||
|
expression: "previous.latitude".into(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
let reply_values = vec![MessageValue {
|
||||||
|
path: vec![],
|
||||||
|
field: accepted,
|
||||||
|
expression: "true".into(),
|
||||||
|
}];
|
||||||
|
let response = commands(
|
||||||
|
&server,
|
||||||
|
&before,
|
||||||
|
vec![
|
||||||
|
Command::EditElement(call, edited_values(&model, call, call_values.clone())),
|
||||||
|
Command::EditElement(reply, edited_values(&model, reply, reply_values.clone())),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
response.status(),
|
||||||
|
StatusCode::OK,
|
||||||
|
"{}",
|
||||||
|
response.text().await.unwrap()
|
||||||
|
);
|
||||||
|
let authored = server.get(resource).await;
|
||||||
|
assert_eq!(authored.revision, before.revision + 1);
|
||||||
|
assert_eq!(values(&authored.model, call), call_values);
|
||||||
|
assert_eq!(values(&authored.model, reply), reply_values);
|
||||||
|
assert_eq!(
|
||||||
|
authored.model.elements[&latitude],
|
||||||
|
model.elements[&latitude]
|
||||||
|
);
|
||||||
|
assert_pair(&authored);
|
||||||
|
let filename = directory.path().join(format!("{resource}.json"));
|
||||||
|
let bytes = std::fs::read(&filename).unwrap();
|
||||||
|
for (occurrence, value, code) in [
|
||||||
|
(
|
||||||
|
call,
|
||||||
|
MessageValue {
|
||||||
|
path: vec![],
|
||||||
|
field: accepted,
|
||||||
|
expression: "wrong call phase".into(),
|
||||||
|
},
|
||||||
|
"message_parameter_phase",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
reply,
|
||||||
|
MessageValue {
|
||||||
|
path: vec![origin],
|
||||||
|
field: latitude,
|
||||||
|
expression: "wrong reply phase".into(),
|
||||||
|
},
|
||||||
|
"message_parameter_phase",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
call,
|
||||||
|
MessageValue {
|
||||||
|
path: vec![origin, accepted],
|
||||||
|
field: latitude,
|
||||||
|
expression: "unrelated hop".into(),
|
||||||
|
},
|
||||||
|
"message_value_field",
|
||||||
|
),
|
||||||
|
] {
|
||||||
|
let invalid = edited_values(&authored.model, occurrence, vec![value]);
|
||||||
|
let mut invalid_model = authored.model.clone();
|
||||||
|
invalid_model.elements.insert(occurrence, invalid.clone());
|
||||||
|
let response = commands(
|
||||||
|
&server,
|
||||||
|
&authored,
|
||||||
|
vec![Command::EditElement(occurrence, invalid)],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY);
|
||||||
|
let problem: Value = response.json().await.unwrap();
|
||||||
|
assert_eq!(problem["code"], "command_rejected", "{problem}");
|
||||||
|
assert!(
|
||||||
|
problem["detail"].as_str().unwrap().starts_with(code),
|
||||||
|
"{problem}"
|
||||||
|
);
|
||||||
|
// Transactions report the first rejection; validation supplies located issues.
|
||||||
|
let validation: Value = server
|
||||||
|
.client
|
||||||
|
.post(server.url(&format!("/projects/{resource}/validation")))
|
||||||
|
.json(&json!({"format":"json", "model":invalid_model}))
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.error_for_status()
|
||||||
|
.unwrap()
|
||||||
|
.json()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(validation["valid"], false);
|
||||||
|
assert!(
|
||||||
|
validation["issues"]
|
||||||
|
.as_array()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.any(|issue| issue["code"] == code
|
||||||
|
&& issue["object_id"] == json!(occurrence)
|
||||||
|
&& issue["field"] == "values.path"),
|
||||||
|
"{problem}"
|
||||||
|
);
|
||||||
|
let unchanged = server.get(resource).await;
|
||||||
|
assert_eq!(unchanged.etag(), authored.etag());
|
||||||
|
assert_eq!(unchanged.model, authored.model);
|
||||||
|
assert_eq!(unchanged.source_project, authored.source_project);
|
||||||
|
assert_eq!(std::fs::read(&filename).unwrap(), bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source transport changes one argument without conflating the shared leaf.
|
||||||
|
let source = server
|
||||||
|
.client
|
||||||
|
.get(server.url(&format!("/projects/{resource}/source")))
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.error_for_status()
|
||||||
|
.unwrap()
|
||||||
|
.text()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let edited_source = source.replace(
|
||||||
|
"\"destination.latitude\"",
|
||||||
|
"\"destination.corrected_latitude\"",
|
||||||
|
);
|
||||||
|
assert_ne!(edited_source, source);
|
||||||
|
let response = server
|
||||||
|
.client
|
||||||
|
.put(server.url(&format!("/projects/{resource}/source")))
|
||||||
|
.header("if-match", authored.etag())
|
||||||
|
.header("content-type", "text/plain")
|
||||||
|
.body(edited_source)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
response.status(),
|
||||||
|
StatusCode::OK,
|
||||||
|
"{}",
|
||||||
|
response.text().await.unwrap()
|
||||||
|
);
|
||||||
|
let source_edited = server.get(resource).await;
|
||||||
|
assert_eq!(source_edited.revision, authored.revision + 1);
|
||||||
|
let mut expected_call = call_values.clone();
|
||||||
|
expected_call[1].expression = "destination.corrected_latitude".into();
|
||||||
|
assert_eq!(values(&source_edited.model, call), expected_call);
|
||||||
|
assert_eq!(values(&source_edited.model, reply), reply_values);
|
||||||
|
assert_pair(&source_edited);
|
||||||
|
|
||||||
|
// Reidentify every kind of enclosing hop, the shared terminal, and its base type.
|
||||||
|
let mapping = [origin, destination, next, latitude, coordinate]
|
||||||
|
.into_iter()
|
||||||
|
.map(|old| (old, Id::new_v4()))
|
||||||
|
.collect::<BTreeMap<_, _>>();
|
||||||
|
let response = commands(
|
||||||
|
&server,
|
||||||
|
&source_edited,
|
||||||
|
mapping
|
||||||
|
.iter()
|
||||||
|
.map(|(old, new)| Command::Reidentify(*old, *new))
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
response.status(),
|
||||||
|
StatusCode::OK,
|
||||||
|
"{}",
|
||||||
|
response.text().await.unwrap()
|
||||||
|
);
|
||||||
|
let changed = server.get(resource).await;
|
||||||
|
assert_eq!(changed.revision, source_edited.revision + 1);
|
||||||
|
for value in &mut expected_call {
|
||||||
|
value.path = value.path.iter().map(|hop| mapping[hop]).collect();
|
||||||
|
value.field = mapping[&value.field];
|
||||||
|
}
|
||||||
|
assert_eq!(values(&changed.model, call), expected_call);
|
||||||
|
assert_eq!(values(&changed.model, reply), reply_values);
|
||||||
|
assert_eq!(
|
||||||
|
changed.model.elements[&mapping[&latitude]].parent,
|
||||||
|
Some(mapping[&coordinate])
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
matches!(changed.model.elements[&located].shared(), Some(SharedBody::DataType {
|
||||||
|
definition: DataTypeDefinition::Record { supertype: Some(base) }, ..
|
||||||
|
}) if *base == mapping[&coordinate])
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
oa_core::data::effective_fields(&changed.model, located)
|
||||||
|
.iter()
|
||||||
|
.any(|field| field.id == mapping[&latitude])
|
||||||
|
);
|
||||||
|
for old in mapping.keys() {
|
||||||
|
assert!(!changed.model.contains(*old));
|
||||||
|
}
|
||||||
|
assert!(
|
||||||
|
matches!(changed.model.elements[&reply].shared(), Some(SharedBody::Occurrence {
|
||||||
|
body: OccurrenceBody::Exchange { reply_to: Some(correlation), .. }, ..
|
||||||
|
}) if *correlation == call)
|
||||||
|
);
|
||||||
|
assert_pair(&changed);
|
||||||
|
let source = server
|
||||||
|
.client
|
||||||
|
.get(server.url(&format!("/projects/{resource}/source")))
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.error_for_status()
|
||||||
|
.unwrap()
|
||||||
|
.text()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(source.starts_with("arcadia 4;"));
|
||||||
|
assert_eq!(oa_core::language::parse(&source).unwrap(), changed.model);
|
||||||
|
let saved = std::fs::read(&filename).unwrap();
|
||||||
|
server.stop().await;
|
||||||
|
let server = TestServer::start(directory.path(), None).await;
|
||||||
|
let reopened = server.get(resource).await;
|
||||||
|
assert_eq!(reopened.etag(), changed.etag());
|
||||||
|
assert_eq!(reopened.model, changed.model);
|
||||||
|
assert_eq!(reopened.source_project, changed.source_project);
|
||||||
|
assert_eq!(values(&reopened.model, call), expected_call);
|
||||||
|
assert_eq!(values(&reopened.model, reply), reply_values);
|
||||||
|
assert_pair(&reopened);
|
||||||
|
assert_eq!(std::fs::read(&filename).unwrap(), saved);
|
||||||
|
server.stop().await;
|
||||||
|
}
|
||||||
|
|||||||
+4
-3
@@ -984,9 +984,10 @@ declares <span class="docutils literal">outgoing_items</span>; <span class="docu
|
|||||||
The lists contain distinct same-layer ExchangeItem references. A functional
|
The lists contain distinct same-layer ExchangeItem references. A functional
|
||||||
exchange MUST reference output/input ports owned by its respective functions,
|
exchange MUST reference output/input ports owned by its respective functions,
|
||||||
and each carried item MUST fit both declarations. Empty declarations accept
|
and each carried item MUST fit both declarations. Empty declarations accept
|
||||||
no items. Item compatibility is identity equality; future specialization is
|
no items. A carried item satisfies an identical declaration or a declaration
|
||||||
not inferred from names. Port declarations remain independent of incident
|
of one of its explicit base items. A base item does not satisfy a more
|
||||||
exchanges after creation.</p>
|
specialized declaration; names imply no compatibility. Port declarations
|
||||||
|
remain independent of incident exchanges after creation.</p>
|
||||||
<p>A <span class="docutils literal">Component</span> contract belongs to an SA System or SystemActor and stores
|
<p>A <span class="docutils literal">Component</span> contract belongs to an SA System or SystemActor and stores
|
||||||
<span class="docutils literal">kind</span> (Standard or Flow) and <span class="docutils literal">orientation</span> (Unset, In, Out, InOut).
|
<span class="docutils literal">kind</span> (Standard or Flow) and <span class="docutils literal">orientation</span> (Unset, In, Out, InOut).
|
||||||
Standard requires Unset. Flow Unset is an incomplete draft, not InOut. Typed
|
Standard requires Unset. Flow Unset is an incomplete draft, not InOut. Typed
|
||||||
|
|||||||
+4
-3
@@ -311,9 +311,10 @@ declares ``outgoing_items``; ``FunctionInput`` declares ``incoming_items``.
|
|||||||
The lists contain distinct same-layer ExchangeItem references. A functional
|
The lists contain distinct same-layer ExchangeItem references. A functional
|
||||||
exchange MUST reference output/input ports owned by its respective functions,
|
exchange MUST reference output/input ports owned by its respective functions,
|
||||||
and each carried item MUST fit both declarations. Empty declarations accept
|
and each carried item MUST fit both declarations. Empty declarations accept
|
||||||
no items. Item compatibility is identity equality; future specialization is
|
no items. A carried item satisfies an identical declaration or a declaration
|
||||||
not inferred from names. Port declarations remain independent of incident
|
of one of its explicit base items. A base item does not satisfy a more
|
||||||
exchanges after creation.
|
specialized declaration; names imply no compatibility. Port declarations
|
||||||
|
remain independent of incident exchanges after creation.
|
||||||
|
|
||||||
A ``Component`` contract belongs to an SA System or SystemActor and stores
|
A ``Component`` contract belongs to an SA System or SystemActor and stores
|
||||||
``kind`` (Standard or Flow) and ``orientation`` (Unset, In, Out, InOut).
|
``kind`` (Standard or Flow) and ``orientation`` (Unset, In, Out, InOut).
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Deliver the first release of Arcadia Studio for system engineers: complete Operational Analysis and System Analysis/System Architecture workflows, equivalent graphical and textual models, clear artifact traceability and a deployable/programmatically accessible Rust service. Logical/Physical Architecture and later Arcadia layers are future releases, as the new objective explicitly states.
|
Deliver the first release of Arcadia Studio for system engineers: complete Operational Analysis and System Analysis/System Architecture workflows, equivalent graphical and textual models, clear artifact traceability and a deployable/programmatically accessible Rust service. Logical/Physical Architecture and later Arcadia layers are future releases, as the new objective explicitly states.
|
||||||
|
|
||||||
The authoritative objective is attachment07aee762-7d27-4cbe-81c3-2e82c7170711/goal-objective.md. It retains first-release scope and source/include, drag-selection and direct behavior editing requirements, and strengthens domain coherence, alternative evaluation and target-user task evidence. TASK_LEDGER.md separates given/verified facts, assumptions and open candidates; STATE.md records progress. The accepted0.2.0 prototype is the baseline, not proof of release completeness. Its source is preserved at D:/CodexBuilds/Capella2-release1-01a06e2e/v2-source-baseline.zip and existing archives remain in dist until replacement passes acceptance.
|
The authoritative objective is attachment10134df9-bea2-4c02-a820-67b53d6b86f7/goal-objective.md. It retains first-release scope and source/include, drag-selection and direct behavior editing requirements, and strengthens domain coherence, alternative evaluation and target-user task evidence. TASK_LEDGER.md separates given/verified facts, assumptions and open candidates; STATE.md records progress. The accepted0.2.0 prototype is the baseline, not proof of release completeness. Its source is preserved at D:/CodexBuilds/Capella2-release1-01a06e2e/v2-source-baseline.zip and existing archives remain in dist until replacement passes acceptance.
|
||||||
|
|
||||||
## Existing architecture and retained decisions
|
## Existing architecture and retained decisions
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -7,7 +7,7 @@ Operational Analysis and System Analysis/System Architecture, equivalent graphic
|
|||||||
textual and REST semantics, artifact traceability, directly editable behavior,
|
textual and REST semantics, artifact traceability, directly editable behavior,
|
||||||
offline guidance, and Windows/Linux release evidence. Later Arcadia layers remain
|
offline guidance, and Windows/Linux release evidence. Later Arcadia layers remain
|
||||||
future releases. The full authoritative objective was reread on 2026-09-06:
|
future releases. The full authoritative objective was reread on 2026-09-06:
|
||||||
attachment07aee762-7d27-4cbe-81c3-2e82c7170711/goal-objective.md.
|
attachment10134df9-bea2-4c02-a820-67b53d6b86f7/goal-objective.md.
|
||||||
PLAN.md retains the entire release scope; no subsystem acceptance completes it.
|
PLAN.md retains the entire release scope; no subsystem acceptance completes it.
|
||||||
|
|
||||||
Direct state-machine editing is accepted through production316dc55. The main
|
Direct state-machine editing is accepted through production316dc55. The main
|
||||||
@@ -82,9 +82,9 @@ Core15 R6 +28workflow tests passed again after final allocation-arrow suppressio
|
|||||||
Linux0b58107 full core307 tests passed (one explicit probe ignored by default),
|
Linux0b58107 full core307 tests passed (one explicit probe ignored by default),
|
||||||
with strict all-target core Clippy. Earlier13ports/14scenarios and115 source/lib
|
with strict all-target core Clippy. Earlier13ports/14scenarios and115 source/lib
|
||||||
tests also passed. Desktop final257 tests and strict all-target Clippy pass;
|
tests also passed. Desktop final257 tests and strict all-target Clippy pass;
|
||||||
the optimized Windows desktop build is in progress for native acceptance.
|
optimized Windows desktop build b403039 passed. Its SHA256 is recorded in the R6 verification note; native acceptance remains pending.
|
||||||
|
|
||||||
Root41 server tests pass, including3 new actual HTTP workflows for the published
|
Root41 server tests passed; a fourth R6 HTTP workflow now also passes, alongside all4 data HTTP tests and strict server Clippy. The original3 actual HTTP workflows for the published
|
||||||
data example, protocol/artifact identity, atomic rejected defaults, query/export,
|
data example, protocol/artifact identity, atomic rejected defaults, query/export,
|
||||||
reidentify/delete/restart, source3 bundle migration reports and old coupled3
|
reidentify/delete/restart, source3 bundle migration reports and old coupled3
|
||||||
envelope upgrade without write/revision. Tests exposed dropped bundle reports and
|
envelope upgrade without write/revision. Tests exposed dropped bundle reports and
|
||||||
@@ -107,8 +107,7 @@ and imported finite paths; same-phase styles/same-exchange reselection preserve
|
|||||||
valid drafts. Read-only follow-up found no new path/style defect. Paging resets
|
valid drafts. Read-only follow-up found no new path/style defect. Paging resets
|
||||||
only on actual layer/document changes; its regression failed before and passes now.
|
only on actual layer/document changes; its regression failed before and passes now.
|
||||||
Root found another unresolved scale issue: scenario creation still enumerates every
|
Root found another unresolved scale issue: scenario creation still enumerates every
|
||||||
carried field into both a dropdown and individual input rows. Native reproduction
|
carried field into both a dropdown and individual input rows. A bounded focused value editor is now implemented and under automated/independent review; actual native operation remains required before R6 acceptance.
|
||||||
and a bounded focused value editor remain required before R6 acceptance.
|
|
||||||
|
|
||||||
Current ownership: drawing_correctness owns desktop except root-owned guide.rs and
|
Current ownership: drawing_correctness owns desktop except root-owned guide.rs and
|
||||||
the dedicated Windows Cargo target. state_architecture_review independently reviews
|
the dedicated Windows Cargo target. state_architecture_review independently reviews
|
||||||
@@ -131,6 +130,7 @@ Root owns API/OpenAPI/reST, docs, integration and native input. No concurrent wr
|
|||||||
|
|
||||||
## Environment and native ownership
|
## Environment and native ownership
|
||||||
|
|
||||||
|
Native input is paused after physical Escape; no R6 native trial has run.
|
||||||
Root exclusively owns native input. Latest saved Windows trial is window1706782,
|
Root exclusively owns native input. Latest saved Windows trial is window1706782,
|
||||||
ui-state-navigation-windows,49objects/28links/1 expected missing-owner warning.
|
ui-state-navigation-windows,49objects/28links/1 expected missing-owner warning.
|
||||||
Linux navigation trial3148598 closed normally, exec46107 exit0; baseline Linux
|
Linux navigation trial3148598 closed normally, exec46107 exit0; baseline Linux
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Task Ledger — first release
|
# Task Ledger — first release
|
||||||
|
|
||||||
Authoritative objective: attachment07aee762-7d27-4cbe-81c3-2e82c7170711/
|
Authoritative objective: attachment10134df9-bea2-4c02-a820-67b53d6b86f7/
|
||||||
goal-objective.md, read fully2026-09-06. STATE.md records execution; PLAN.md retains
|
goal-objective.md, read fully2026-09-06. STATE.md records execution; PLAN.md retains
|
||||||
scope; DECISIONS.md and linked contracts preserve rationale.
|
scope; DECISIONS.md and linked contracts preserve rationale.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# R6 data contracts — verification in progress
|
||||||
|
|
||||||
|
R6 is not accepted. Main remains at state-editing acceptance a8f451e. The updated
|
||||||
|
objective10134df9-bea2-4c02-a820-67b53d6b86f7 was read fully on2026-09-06; product
|
||||||
|
scope is unchanged and reasoning effort must match the delegated task. The full
|
||||||
|
first release remains incomplete. Native input is paused after physical Escape.
|
||||||
|
|
||||||
|
## Current evidence
|
||||||
|
|
||||||
|
- Core0b58107: Linux307 tests pass, one explicitly ignored benchmark; strict
|
||||||
|
all-target core Clippy passes. Windows15 R6+28 workflows pass after final
|
||||||
|
allocation-edge filtering. Source migration/compatibility evidence is retained.
|
||||||
|
- Desktopb403039: Windows257 tests, strict all-target desktop Clippy and release
|
||||||
|
build pass. Binary D:/CodexBuilds/Capella2-data-target/release/arcadia-studio.exe,
|
||||||
|
SHA256 d4aa6ae7d36f429c0cb639cdf57e33cb8b99d158a9629c95a1510d24e406fab5.
|
||||||
|
The later bounded scenario editor is not covered by this binary.
|
||||||
|
- Optimized empty inheritance chains250/500/1000: Windows21.070/89.088/391.590ms;
|
||||||
|
Linux22.381/111.662/408.129ms. These are single-run validation measurements.
|
||||||
|
- Server41 prior tests passed. The new qualified Call/Reply workflow and all4 R6
|
||||||
|
HTTP tests now pass with strict all-target server Clippy. Actual HTTP proves
|
||||||
|
distinct reused/inherited/recursive field paths, preserved expression whitespace,
|
||||||
|
phase/path422 with unchanged ETag/model/source/disk, source edits, enclosing-hop
|
||||||
|
and terminal/base reidentification, correlation and exact restart persistence.
|
||||||
|
Initial new-test failures were fixture misuse of untyped Port construction and
|
||||||
|
incorrect assumption that transaction errors carry structured issues. Tests now
|
||||||
|
use make_port and the documented command_rejected/detail plus validation endpoint.
|
||||||
|
- Published data example was imported into actual frozen server32033FFE. Complete
|
||||||
|
Project/StoredProject responses passed served/local OpenAPI validation; obsolete
|
||||||
|
shapes rejected. reST strict rendering and81 OpenAPI schemas passed.
|
||||||
|
- Independent spec review found one stale identity-only port-compatibility paragraph;
|
||||||
|
fixed to directional explicit ancestry and strict HTML rendering passed. No other
|
||||||
|
material R6 spec/API contradiction found in that review.
|
||||||
|
|
||||||
|
Logs are under D:/CodexBuilds/Capella2-release1-01a06e2e:
|
||||||
|
r6-http-paths-final.log, r6-http-all-data.log, r6-http-paths-clippy.log,
|
||||||
|
r6-server-tests-after.log and api-r6-contract. Linux core evidence is under
|
||||||
|
D:/CodexBuilds/Capella2-data-linux-review/target/linux-verification/report.md.
|
||||||
|
|
||||||
|
## Active checks and remaining gates
|
||||||
|
|
||||||
|
The isolated Linux checkout was fast-forwarded to b403039; full workspace tests are
|
||||||
|
running in exec98587 with its dedicated data-linux-target. Initial filesystem wait
|
||||||
|
was verified as a live Cargo process in p9_client_rpc; it subsequently compiled.
|
||||||
|
Do not restart from an observation timeout. Bounded scenario editor production and
|
||||||
|
regressions are being tested by the desktop worker. Independent review found stale
|
||||||
|
values hiding an alternative reply call; its fix is included in that worker pass.
|
||||||
|
|
||||||
|
Before acceptance: integrated Windows/Linux checks, native data/association/scenario
|
||||||
|
value workflows at normal/minimum sizes, source3 migration diagnostics, Save/reopen,
|
||||||
|
and closure of material review findings. No R6 visual or real-app acceptance claim.
|
||||||
Reference in New Issue
Block a user