Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
684061ec0f |
@@ -12,6 +12,7 @@
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.zip binary
|
||||
harness/prerelease37-independent-9e8r6t-20260924/** -text whitespace=cr-at-eol
|
||||
|
||||
# Exact source/recovery oracles and archived ledgers retain their measured bytes.
|
||||
# Keep ordinary text diffs; only disable checkout/check-in newline conversion.
|
||||
|
||||
@@ -210,6 +210,7 @@ impl SemanticPlan {
|
||||
pub fn project(&self) -> &Project {
|
||||
&self.candidate
|
||||
}
|
||||
#[cfg(test)]
|
||||
pub fn index(&self) -> &ViewIndex {
|
||||
&self.index
|
||||
}
|
||||
@@ -484,57 +485,6 @@ pub struct PresentationContext {
|
||||
pub target: Option<TargetPresentation>,
|
||||
}
|
||||
|
||||
impl PresentationContext {
|
||||
fn header_visible(self, header: Rect, outgoing: bool) -> bool {
|
||||
if !outgoing {
|
||||
return self.viewport.contains(header);
|
||||
}
|
||||
// Leaving a performer must not require fitting the entire work card
|
||||
// inside the camera. Retain a 24px grab region so the result stays
|
||||
// directly reachable; geometry/model admission is independent.
|
||||
let width = (header.position.x + header.size.width)
|
||||
.min(self.viewport.position.x + self.viewport.size.width)
|
||||
- header.position.x.max(self.viewport.position.x);
|
||||
let height = (header.position.y + header.size.height)
|
||||
.min(self.viewport.position.y + self.viewport.size.height)
|
||||
- header.position.y.max(self.viewport.position.y);
|
||||
width * self.zoom >= 24. && height * self.zoom >= 24.
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outgoing_header_retains_a_grab_region_without_requiring_full_camera_containment() {
|
||||
let context = PresentationContext {
|
||||
viewport: Rect {
|
||||
position: Position { x: 0., y: 0. },
|
||||
size: Size {
|
||||
width: 800.,
|
||||
height: 400.,
|
||||
},
|
||||
},
|
||||
zoom: 0.75,
|
||||
target: None,
|
||||
};
|
||||
let mut header = Rect {
|
||||
position: Position { x: -100., y: 30. },
|
||||
size: Size {
|
||||
width: 224.,
|
||||
height: 62.,
|
||||
},
|
||||
};
|
||||
assert!(context.header_visible(header, true));
|
||||
assert!(!context.header_visible(header, false));
|
||||
header.position.x = -192.; // exactly 32 world pixels = 24 logical pixels
|
||||
assert!(context.header_visible(header, true));
|
||||
header.position.x -= 1.;
|
||||
assert!(!context.header_visible(header, true));
|
||||
header.position.x = 0.;
|
||||
header.position.y = 368.;
|
||||
assert!(context.header_visible(header, true));
|
||||
header.position.y += 1.;
|
||||
assert!(!context.header_visible(header, true));
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PlacementPlan {
|
||||
pub diagram: Diagram,
|
||||
@@ -546,8 +496,8 @@ pub struct PlacementPlan {
|
||||
commands: Vec<Command>,
|
||||
}
|
||||
|
||||
/// `requested` preserves the frozen pointer offset unless the caller proposes
|
||||
/// bounded outward clearance for an outgoing drop. Snap only
|
||||
/// `requested` is the original selected placement position plus pointer motion
|
||||
/// in the frozen transform (therefore preserving the press offset). Snap only
|
||||
/// this root; apply the resulting identical delta to captured Q and its routes.
|
||||
/// No whole Project clone, validator or semantic ViewIndex rebuild occurs here.
|
||||
pub fn place(
|
||||
@@ -627,7 +577,7 @@ pub fn place(
|
||||
height: selected.size.height.min(62.),
|
||||
},
|
||||
};
|
||||
if !presentation.header_visible(header, plan.destination == Destination::OutsidePerformers) {
|
||||
if !presentation.viewport.contains(header) {
|
||||
return Err(Refusal::LayoutRequired(
|
||||
"Make room or adjust the view, then drag again.".into(),
|
||||
));
|
||||
|
||||
@@ -188,7 +188,7 @@ pub fn place(
|
||||
};
|
||||
geometry::check_rigid(&plan.before_expanded, &expanded, &plan.placements, delta)?;
|
||||
scenes?;
|
||||
geometry::check_headers(&view, &plan.selected, presentation, false)?;
|
||||
geometry::check_headers(&view, &plan.selected, presentation.viewport)?;
|
||||
Ok(PlacementPlan {
|
||||
diagram,
|
||||
view,
|
||||
|
||||
@@ -398,12 +398,7 @@ pub fn place(
|
||||
&expanded,
|
||||
)?;
|
||||
geometry::check_rigid(&scope.0.before_expanded, &expanded, scope.affected(), delta)?;
|
||||
geometry::check_headers(
|
||||
&view,
|
||||
scope.selected(),
|
||||
presentation,
|
||||
plan.destination == Destination::OutsidePerformers,
|
||||
)?;
|
||||
geometry::check_headers(&view, scope.selected(), presentation.viewport)?;
|
||||
Ok(PlacementPlan {
|
||||
diagram,
|
||||
view,
|
||||
|
||||
@@ -170,8 +170,7 @@ pub(super) fn check_rigid(
|
||||
pub(super) fn check_headers(
|
||||
view: &ProjectedView,
|
||||
selected: &BTreeMap<Id, Id>,
|
||||
presentation: PresentationContext,
|
||||
outgoing: bool,
|
||||
viewport: Rect,
|
||||
) -> Result<(), Refusal> {
|
||||
for (id, element) in selected {
|
||||
let node = view
|
||||
@@ -186,7 +185,7 @@ pub(super) fn check_headers(
|
||||
height: node.size.height.min(62.),
|
||||
},
|
||||
};
|
||||
if !presentation.header_visible(header, outgoing) {
|
||||
if !viewport.contains(header) {
|
||||
return Err(Refusal::LayoutRequired(
|
||||
"Make room or adjust the view, then drag again.".into(),
|
||||
));
|
||||
|
||||
@@ -14,8 +14,6 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
mod clearance;
|
||||
|
||||
pub const FINISH_EDIT: &str =
|
||||
"Finish or cancel the current edit before selecting or moving elements.";
|
||||
|
||||
@@ -58,7 +56,6 @@ pub struct Target {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Frozen {
|
||||
pub targets: Vec<Target>,
|
||||
pub moving: Vec<Rectangle>,
|
||||
cards: Vec<Rectangle>,
|
||||
controls: Vec<Rectangle>,
|
||||
edges: Vec<(Point, Point)>,
|
||||
@@ -85,16 +82,14 @@ impl Frozen {
|
||||
) -> Self {
|
||||
let mut targets = Vec::new();
|
||||
let mut cards = Vec::new();
|
||||
let mut moving = Vec::new();
|
||||
for n in &view.nodes {
|
||||
if affected.contains_key(&n.id) {
|
||||
continue;
|
||||
}
|
||||
let region = Rectangle::new(
|
||||
Point::new(n.position.x, n.position.y),
|
||||
iced::Size::new(n.size.width, n.size.height),
|
||||
);
|
||||
if affected.contains_key(&n.id) {
|
||||
moving.push(region);
|
||||
continue;
|
||||
}
|
||||
let Some(e) = project.elements.get(&n.element) else {
|
||||
cards.push(region);
|
||||
continue;
|
||||
@@ -177,7 +172,6 @@ impl Frozen {
|
||||
}
|
||||
Self {
|
||||
targets,
|
||||
moving,
|
||||
cards,
|
||||
controls,
|
||||
edges,
|
||||
@@ -413,6 +407,7 @@ impl Candidate {
|
||||
Self::Performers(p) => &p.accepted,
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
pub fn index(&self) -> &view_options::ViewIndex {
|
||||
match self {
|
||||
Self::Singleton(p) => p.index(),
|
||||
@@ -530,8 +525,6 @@ pub(crate) struct Feedback {
|
||||
pub inspection_targets: Vec<usize>,
|
||||
pub text: String,
|
||||
pub refused: bool,
|
||||
/// Pointer-following outline only; it never authorizes a model change.
|
||||
pub ghost_delta: Option<Vector>,
|
||||
}
|
||||
impl Feedback {
|
||||
pub fn inspection_identity(&self) -> String {
|
||||
@@ -1062,26 +1055,7 @@ impl App {
|
||||
viewport: stamp.viewport(), zoom: stamp.zoom,
|
||||
target: target.map(|i| plan::TargetPresentation { placement: active.frozen.as_ref().unwrap().targets[i].placement }),
|
||||
};
|
||||
let exact = candidate.place(requested, presentation);
|
||||
let placed = if destination == plan::Destination::OutsidePerformers
|
||||
&& matches!(&exact, Err(plan::Refusal::LayoutRequired(_)))
|
||||
{
|
||||
let affected = match &active.prepared {
|
||||
Prepared::Singleton(scope) => Some(&scope.placements),
|
||||
Prepared::Assignment(scope) => Some(scope.affected()),
|
||||
_ => None,
|
||||
};
|
||||
affected.and_then(|affected| {
|
||||
clearance::requests(
|
||||
(self.project(), self.document.view_index()),
|
||||
(candidate.project(), candidate.index()), stamp.context.diagram,
|
||||
affected, *anchor, requested,
|
||||
(stamp.world(press.start), stamp.world(pointer.unwrap())),
|
||||
).into_iter().find_map(|position| candidate.place(position, presentation).ok())
|
||||
}).map_or(exact, Ok)
|
||||
} else {
|
||||
exact
|
||||
}.map_err(|r| refusal(&r))?;
|
||||
let placed = candidate.place(requested, presentation).map_err(|r| refusal(&r))?;
|
||||
let label = candidate.label();
|
||||
if release {
|
||||
if let Some(command) = candidate.finish(self.project(), &placed).map_err(|r| refusal(&r))? {
|
||||
@@ -1108,14 +1082,6 @@ impl App {
|
||||
} else {
|
||||
let inspection_targets = active.inspection_targets.clone();
|
||||
let frozen = active.frozen.clone();
|
||||
// A rejected intermediate position is not a return gesture. Keep the
|
||||
// last admitted scene and show current motion separately; release
|
||||
// always recomputes admission and never commits this retained view.
|
||||
if refused && in_bounds && preview.is_none() {
|
||||
preview = self.allocation_drag.preview.take();
|
||||
}
|
||||
let ghost_delta = (refused && in_bounds)
|
||||
.then(|| (pointer.unwrap() - press.start) * (1. / stamp.zoom));
|
||||
self.allocation_drag.active = Some(active);
|
||||
self.allocation_drag.preview = preview;
|
||||
self.allocation_drag.feedback = Some(Feedback {
|
||||
@@ -1126,7 +1092,6 @@ impl App {
|
||||
inspection_targets,
|
||||
text,
|
||||
refused,
|
||||
ghost_delta,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,595 +0,0 @@
|
||||
//! Bounded outgoing clearance proposals. The ordinary placement and semantic
|
||||
//! validators still decide whether any proposal may be previewed or committed.
|
||||
use iced::Point;
|
||||
use oa_core::{Id, NodePlacement, Position, Project, projection, view_options::ViewIndex};
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
const GRID: f32 = 10.;
|
||||
const GAP: f32 = 10.;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Bounds {
|
||||
left: f32,
|
||||
top: f32,
|
||||
right: f32,
|
||||
bottom: f32,
|
||||
}
|
||||
|
||||
impl Bounds {
|
||||
fn node(node: &projection::ProjectedNode) -> Option<Self> {
|
||||
let result = Self {
|
||||
left: node.position.x,
|
||||
top: node.position.y,
|
||||
right: node.position.x + node.size.width,
|
||||
bottom: node.position.y + node.size.height,
|
||||
};
|
||||
([result.left, result.top, result.right, result.bottom]
|
||||
.iter()
|
||||
.all(|value| value.is_finite())
|
||||
&& result.right > result.left
|
||||
&& result.bottom > result.top)
|
||||
.then_some(result)
|
||||
}
|
||||
|
||||
fn union(self, other: Self) -> Self {
|
||||
Self {
|
||||
left: self.left.min(other.left),
|
||||
top: self.top.min(other.top),
|
||||
right: self.right.max(other.right),
|
||||
bottom: self.bottom.max(other.bottom),
|
||||
}
|
||||
}
|
||||
|
||||
fn overlaps(self, other: Self) -> bool {
|
||||
self.left < other.right
|
||||
&& other.left < self.right
|
||||
&& self.top < other.bottom
|
||||
&& other.top < self.bottom
|
||||
}
|
||||
}
|
||||
|
||||
/// Called only after an OutsidePerformers candidate fails ordinary placement.
|
||||
/// Coordinates use the frozen world transform. The entire affected footprint
|
||||
/// receives one anchor translation; this never moves or packs other cards.
|
||||
pub(super) fn requests(
|
||||
accepted: (&Project, &ViewIndex),
|
||||
candidate: (&Project, &ViewIndex),
|
||||
diagram: Id,
|
||||
affected: &BTreeMap<Id, NodePlacement>,
|
||||
anchor: Id,
|
||||
requested: Position,
|
||||
motion: (Point, Point),
|
||||
) -> Vec<Position> {
|
||||
let (accepted, accepted_index) = accepted;
|
||||
let (candidate, candidate_index) = candidate;
|
||||
let (start, pointer) = motion;
|
||||
if ![
|
||||
requested.x,
|
||||
requested.y,
|
||||
start.x,
|
||||
start.y,
|
||||
pointer.x,
|
||||
pointer.y,
|
||||
]
|
||||
.iter()
|
||||
.all(|value| value.is_finite())
|
||||
{
|
||||
return Vec::new();
|
||||
}
|
||||
let (Some(original), Some(base), Some(anchor)) = (
|
||||
accepted.diagrams.get(&diagram),
|
||||
candidate.diagrams.get(&diagram),
|
||||
affected.get(&anchor),
|
||||
) else {
|
||||
return Vec::new();
|
||||
};
|
||||
let snapped = Position {
|
||||
x: (requested.x / GRID).round() * GRID,
|
||||
y: (requested.y / GRID).round() * GRID,
|
||||
};
|
||||
let delta = Position {
|
||||
x: snapped.x - anchor.position.x,
|
||||
y: snapped.y - anchor.position.y,
|
||||
};
|
||||
let before = projection::project_diagram_with_index(accepted, original, accepted_index);
|
||||
let before_nodes: BTreeMap<_, _> = before.nodes.iter().map(|node| (node.id, node)).collect();
|
||||
let mut sources = BTreeSet::new();
|
||||
for node in before
|
||||
.nodes
|
||||
.iter()
|
||||
.filter(|node| affected.contains_key(&node.id))
|
||||
{
|
||||
let mut parent = node.visual_parent;
|
||||
let mut seen = BTreeSet::new();
|
||||
while let Some(id) = parent {
|
||||
if !seen.insert(id) {
|
||||
return Vec::new();
|
||||
}
|
||||
let Some(node) = before_nodes.get(&id) else {
|
||||
break;
|
||||
};
|
||||
if !affected.contains_key(&id)
|
||||
&& accepted
|
||||
.elements
|
||||
.get(&node.element)
|
||||
.is_some_and(|element| element.kind().is_performer())
|
||||
{
|
||||
sources.insert(id);
|
||||
}
|
||||
parent = node.visual_parent;
|
||||
}
|
||||
}
|
||||
if sources.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
// Projection after responsibility removal supplies the former performer's
|
||||
// remaining enclosure, including other allocated work. Projecting the moved
|
||||
// block also includes the full visible descendant enclosure of every root.
|
||||
let mut moved = base.clone();
|
||||
for (id, captured) in affected {
|
||||
let Some(node) = moved.nodes.get_mut(id) else {
|
||||
return Vec::new();
|
||||
};
|
||||
node.position = Position {
|
||||
x: captured.position.x + delta.x,
|
||||
y: captured.position.y + delta.y,
|
||||
};
|
||||
if ![
|
||||
node.position.x,
|
||||
node.position.y,
|
||||
node.size.width,
|
||||
node.size.height,
|
||||
]
|
||||
.iter()
|
||||
.all(|value| value.is_finite())
|
||||
{
|
||||
return Vec::new();
|
||||
}
|
||||
}
|
||||
let after = projection::project_diagram_with_index(candidate, &moved, candidate_index);
|
||||
let mut footprint: Option<Bounds> = None;
|
||||
for node in after
|
||||
.nodes
|
||||
.iter()
|
||||
.filter(|node| affected.contains_key(&node.id))
|
||||
{
|
||||
let Some(bounds) = Bounds::node(node) else {
|
||||
return Vec::new();
|
||||
};
|
||||
footprint = Some(footprint.map_or(bounds, |previous| previous.union(bounds)));
|
||||
}
|
||||
let Some(footprint) = footprint else {
|
||||
return Vec::new();
|
||||
};
|
||||
let mut overlaps = Vec::new();
|
||||
for node in after.nodes.iter().filter(|node| sources.contains(&node.id)) {
|
||||
let (Some(old), Some(current)) = (Bounds::node(before_nodes[&node.id]), Bounds::node(node))
|
||||
else {
|
||||
return Vec::new();
|
||||
};
|
||||
if footprint.overlaps(current) {
|
||||
overlaps.push((old, current));
|
||||
}
|
||||
}
|
||||
if overlaps.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
// Each entry is a half-plane actually crossed by the pointer. At a corner,
|
||||
// prefer the boundary reached first on the press-to-pointer segment. The
|
||||
// direction index is a stable tie-break, independent of placement UUIDs.
|
||||
let mut crossings = [None::<f32>; 4];
|
||||
for (old, _) in &overlaps {
|
||||
for (direction, initial, final_, boundary, outward) in [
|
||||
(
|
||||
0,
|
||||
start.x,
|
||||
pointer.x,
|
||||
old.left,
|
||||
pointer.x < old.left && start.x >= old.left,
|
||||
),
|
||||
(
|
||||
1,
|
||||
start.x,
|
||||
pointer.x,
|
||||
old.right,
|
||||
pointer.x >= old.right && start.x < old.right,
|
||||
),
|
||||
(
|
||||
2,
|
||||
start.y,
|
||||
pointer.y,
|
||||
old.top,
|
||||
pointer.y < old.top && start.y >= old.top,
|
||||
),
|
||||
(
|
||||
3,
|
||||
start.y,
|
||||
pointer.y,
|
||||
old.bottom,
|
||||
pointer.y >= old.bottom && start.y < old.bottom,
|
||||
),
|
||||
] {
|
||||
if outward {
|
||||
let fraction = (boundary - initial) / (final_ - initial);
|
||||
if fraction.is_finite() && (0. ..=1.).contains(&fraction) {
|
||||
crossings[direction] =
|
||||
Some(crossings[direction].map_or(fraction, |old| old.min(fraction)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut directions: Vec<_> = crossings
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.filter_map(|(direction, fraction)| fraction.map(|fraction| (direction, fraction)))
|
||||
.collect();
|
||||
directions.sort_by(|a, b| a.1.total_cmp(&b.1).then(a.0.cmp(&b.0)));
|
||||
let mut result = Vec::new();
|
||||
for (direction, _) in directions {
|
||||
let mut corrected = snapped;
|
||||
match direction {
|
||||
0 => {
|
||||
let edge = overlaps
|
||||
.iter()
|
||||
.map(|(_, current)| current.left)
|
||||
.fold(f32::INFINITY, f32::min);
|
||||
corrected.x = ((snapped.x + edge - GAP - footprint.right) / GRID).floor() * GRID;
|
||||
}
|
||||
1 => {
|
||||
let edge = overlaps
|
||||
.iter()
|
||||
.map(|(_, current)| current.right)
|
||||
.fold(f32::NEG_INFINITY, f32::max);
|
||||
corrected.x = ((snapped.x + edge + GAP - footprint.left) / GRID).ceil() * GRID;
|
||||
}
|
||||
2 => {
|
||||
let edge = overlaps
|
||||
.iter()
|
||||
.map(|(_, current)| current.top)
|
||||
.fold(f32::INFINITY, f32::min);
|
||||
corrected.y = ((snapped.y + edge - GAP - footprint.bottom) / GRID).floor() * GRID;
|
||||
}
|
||||
3 => {
|
||||
let edge = overlaps
|
||||
.iter()
|
||||
.map(|(_, current)| current.bottom)
|
||||
.fold(f32::NEG_INFINITY, f32::max);
|
||||
corrected.y = ((snapped.y + edge + GAP - footprint.top) / GRID).ceil() * GRID;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
if corrected.x.is_finite() && corrected.y.is_finite() && !result.contains(&corrected) {
|
||||
result.push(corrected);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::allocation_drag as plan;
|
||||
use oa_core::{Kind, Layer, ProjectionKind, RelationKind, Size};
|
||||
|
||||
struct Fixture {
|
||||
project: Project,
|
||||
diagram: Id,
|
||||
performer: Id,
|
||||
work: Id,
|
||||
node: Id,
|
||||
}
|
||||
|
||||
fn xy(x: f32, y: f32) -> Position {
|
||||
Position { x, y }
|
||||
}
|
||||
|
||||
fn fixture(layer: Layer) -> Fixture {
|
||||
let mut project = Project::empty();
|
||||
let (performer, work) = match layer {
|
||||
Layer::Oa => (Kind::Entity, Kind::Activity),
|
||||
Layer::Sa => (Kind::System, Kind::Function),
|
||||
};
|
||||
let performer = project
|
||||
.add_element(performer, layer, "Performer", None)
|
||||
.unwrap();
|
||||
let work = project.add_element(work, layer, "Work", None).unwrap();
|
||||
let diagram = project.ensure_diagram(layer);
|
||||
project.diagrams.get_mut(&diagram).unwrap().projection = ProjectionKind::Allocation;
|
||||
let performer = project.place(diagram, performer, xy(100., 100.));
|
||||
project
|
||||
.diagrams
|
||||
.get_mut(&diagram)
|
||||
.unwrap()
|
||||
.nodes
|
||||
.get_mut(&performer)
|
||||
.unwrap()
|
||||
.size = Size {
|
||||
width: 400.,
|
||||
height: 250.,
|
||||
};
|
||||
let node = project.place(diagram, work, xy(160., 180.));
|
||||
let owner = project.diagrams[&diagram].nodes[&performer].element;
|
||||
project.relate(RelationKind::Allocation, "Responsibility", owner, work);
|
||||
Fixture {
|
||||
project,
|
||||
diagram,
|
||||
performer,
|
||||
work,
|
||||
node,
|
||||
}
|
||||
}
|
||||
|
||||
fn semantic(f: &Fixture) -> (plan::Scope, plan::SemanticPlan) {
|
||||
let scope = plan::capture(&f.project, f.diagram, f.work, f.node).unwrap();
|
||||
let semantic = plan::plan_semantics(
|
||||
&f.project,
|
||||
&scope,
|
||||
plan::Destination::OutsidePerformers,
|
||||
&BTreeMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
(scope, semantic)
|
||||
}
|
||||
|
||||
fn presentation() -> plan::PresentationContext {
|
||||
plan::PresentationContext {
|
||||
viewport: plan::Rect {
|
||||
position: xy(-2000., -2000.),
|
||||
size: Size {
|
||||
width: 5000.,
|
||||
height: 5000.,
|
||||
},
|
||||
},
|
||||
zoom: 1.,
|
||||
target: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_outgoing_edge_clears_the_source_and_passes_ordinary_placement() {
|
||||
for layer in [Layer::Oa, Layer::Sa] {
|
||||
let f = fixture(layer);
|
||||
let (scope, semantic) = semantic(&f);
|
||||
for (start, pointer, requested, expected) in [
|
||||
(
|
||||
Point::new(170., 210.),
|
||||
Point::new(99., 210.),
|
||||
xy(89., 180.),
|
||||
xy(-140., 180.),
|
||||
),
|
||||
(
|
||||
Point::new(340., 210.),
|
||||
Point::new(501., 210.),
|
||||
xy(321., 180.),
|
||||
xy(510., 180.),
|
||||
),
|
||||
(
|
||||
Point::new(200., 190.),
|
||||
Point::new(200., 99.),
|
||||
xy(160., 89.),
|
||||
xy(160., -10.),
|
||||
),
|
||||
(
|
||||
Point::new(200., 260.),
|
||||
Point::new(200., 351.),
|
||||
xy(160., 271.),
|
||||
xy(160., 360.),
|
||||
),
|
||||
] {
|
||||
assert!(matches!(
|
||||
plan::place(&semantic, requested, presentation()),
|
||||
Err(plan::Refusal::LayoutRequired(_))
|
||||
));
|
||||
let proposed = requests(
|
||||
(&f.project, &ViewIndex::new(&f.project)),
|
||||
(semantic.project(), semantic.index()),
|
||||
f.diagram,
|
||||
&scope.placements,
|
||||
f.node,
|
||||
requested,
|
||||
(start, pointer),
|
||||
);
|
||||
assert_eq!(proposed, vec![expected]);
|
||||
let placed = plan::place(&semantic, proposed[0], presentation()).unwrap();
|
||||
assert!(
|
||||
plan::finish(&semantic, &f.project, &placed)
|
||||
.unwrap()
|
||||
.is_some()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn source_shrink_uses_candidate_enclosure_not_frozen_target() {
|
||||
let mut f = fixture(Layer::Oa);
|
||||
f.project
|
||||
.diagrams
|
||||
.get_mut(&f.diagram)
|
||||
.unwrap()
|
||||
.nodes
|
||||
.get_mut(&f.performer)
|
||||
.unwrap()
|
||||
.size = Size {
|
||||
width: 224.,
|
||||
height: 94.,
|
||||
};
|
||||
let (scope, semantic) = semantic(&f);
|
||||
let proposed = requests(
|
||||
(&f.project, &ViewIndex::new(&f.project)),
|
||||
(semantic.project(), semantic.index()),
|
||||
f.diagram,
|
||||
&scope.placements,
|
||||
f.node,
|
||||
xy(229., 180.),
|
||||
(Point::new(340., 210.), Point::new(409., 210.)),
|
||||
);
|
||||
assert_eq!(proposed, vec![xy(340., 180.)]);
|
||||
plan::place(&semantic, proposed[0], presentation()).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn corner_order_follows_boundary_crossing_and_is_deterministic() {
|
||||
let f = fixture(Layer::Sa);
|
||||
let (scope, semantic) = semantic(&f);
|
||||
// Right crossed at 160/161 of the segment; bottom at 90/91.
|
||||
let args = (
|
||||
xy(321., 271.),
|
||||
Point::new(340., 260.),
|
||||
Point::new(501., 351.),
|
||||
);
|
||||
let proposed = requests(
|
||||
(&f.project, &ViewIndex::new(&f.project)),
|
||||
(semantic.project(), semantic.index()),
|
||||
f.diagram,
|
||||
&scope.placements,
|
||||
f.node,
|
||||
args.0,
|
||||
(args.1, args.2),
|
||||
);
|
||||
assert_eq!(proposed, vec![xy(320., 360.), xy(510., 270.)]);
|
||||
assert_eq!(
|
||||
proposed,
|
||||
requests(
|
||||
(&f.project, &ViewIndex::new(&f.project)),
|
||||
(semantic.project(), semantic.index()),
|
||||
f.diagram,
|
||||
&scope.placements,
|
||||
f.node,
|
||||
args.0,
|
||||
(args.1, args.2)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_crossing_no_overlap_no_source_and_nonfinite_requests_are_empty() {
|
||||
let f = fixture(Layer::Oa);
|
||||
let (scope, semantic) = semantic(&f);
|
||||
for (requested, pointer) in [
|
||||
(xy(170., 180.), Point::new(210., 210.)),
|
||||
(xy(700., 180.), Point::new(740., 210.)),
|
||||
(xy(f32::NAN, 180.), Point::new(99., 210.)),
|
||||
(xy(89., 180.), Point::new(f32::INFINITY, 210.)),
|
||||
] {
|
||||
assert!(
|
||||
requests(
|
||||
(&f.project, &ViewIndex::new(&f.project)),
|
||||
(semantic.project(), semantic.index()),
|
||||
f.diagram,
|
||||
&scope.placements,
|
||||
f.node,
|
||||
requested,
|
||||
(Point::new(200., 210.), pointer)
|
||||
)
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
assert!(
|
||||
requests(
|
||||
(semantic.project(), semantic.index()),
|
||||
(semantic.project(), semantic.index()),
|
||||
f.diagram,
|
||||
&scope.placements,
|
||||
f.node,
|
||||
xy(89., 180.),
|
||||
(Point::new(200., 210.), Point::new(99., 210.))
|
||||
)
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn descendant_footprint_controls_clearance_without_mutating_projects() {
|
||||
for layer in [Layer::Oa, Layer::Sa] {
|
||||
let mut f = fixture(layer);
|
||||
let kind = f.project.elements[&f.work].kind();
|
||||
let child = f
|
||||
.project
|
||||
.add_element(kind, layer, "Child", Some(f.work))
|
||||
.unwrap();
|
||||
let child_node = f.project.place(f.diagram, child, xy(240., 270.));
|
||||
// First-child allocation transfer is normally performed by commands;
|
||||
// this fixture expresses the resulting leaf allocation directly.
|
||||
f.project.relations.clear();
|
||||
let owner = f.project.diagrams[&f.diagram].nodes[&f.performer].element;
|
||||
f.project.relate(
|
||||
RelationKind::Allocation,
|
||||
"Leaf responsibility",
|
||||
owner,
|
||||
child,
|
||||
);
|
||||
let (scope, semantic) = semantic(&f);
|
||||
assert!(scope.placements.contains_key(&child_node));
|
||||
let before = f.project.clone();
|
||||
let candidate = semantic.project().clone();
|
||||
let proposed = requests(
|
||||
(&f.project, &ViewIndex::new(&f.project)),
|
||||
(&candidate, semantic.index()),
|
||||
f.diagram,
|
||||
&scope.placements,
|
||||
f.node,
|
||||
xy(89., 180.),
|
||||
(Point::new(170., 210.), Point::new(99., 210.)),
|
||||
);
|
||||
assert_eq!(proposed, vec![xy(-240., 180.)]);
|
||||
let placed = plan::place(&semantic, proposed[0], presentation()).unwrap();
|
||||
let root = &placed.diagram.nodes[&f.node];
|
||||
let child = &placed.diagram.nodes[&child_node];
|
||||
assert_eq!(child.position.x - root.position.x, 80.);
|
||||
assert_eq!(child.position.y - root.position.y, 90.);
|
||||
assert_eq!(f.project, before);
|
||||
assert_eq!(semantic.project(), &candidate);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn independent_selected_roots_keep_one_rigid_group_translation() {
|
||||
for layer in [Layer::Oa, Layer::Sa] {
|
||||
let mut f = fixture(layer);
|
||||
let kind = f.project.elements[&f.work].kind();
|
||||
let second = f
|
||||
.project
|
||||
.add_element(kind, layer, "Second work", None)
|
||||
.unwrap();
|
||||
let second_node = f.project.place(f.diagram, second, xy(240., 300.));
|
||||
let owner = f.project.diagrams[&f.diagram].nodes[&f.performer].element;
|
||||
f.project.relate(
|
||||
RelationKind::Allocation,
|
||||
"Second responsibility",
|
||||
owner,
|
||||
second,
|
||||
);
|
||||
let selected = BTreeMap::from([(f.node, f.work), (second_node, second)]);
|
||||
let scope =
|
||||
plan::assignment::capture(&f.project, f.diagram, &selected, f.node).unwrap();
|
||||
let semantic = plan::assignment::plan_semantics(
|
||||
&scope,
|
||||
plan::Destination::OutsidePerformers,
|
||||
&BTreeMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
let proposed = requests(
|
||||
(&f.project, &ViewIndex::new(&f.project)),
|
||||
(semantic.project(), semantic.index()),
|
||||
f.diagram,
|
||||
scope.affected(),
|
||||
f.node,
|
||||
xy(89., 180.),
|
||||
(Point::new(170., 210.), Point::new(99., 210.)),
|
||||
);
|
||||
assert_eq!(proposed, vec![xy(-220., 180.)]);
|
||||
let placed = plan::assignment::place(&semantic, proposed[0], presentation()).unwrap();
|
||||
let root = &placed.diagram.nodes[&f.node];
|
||||
let second = &placed.diagram.nodes[&second_node];
|
||||
assert_eq!(second.position.x - root.position.x, 80.);
|
||||
assert_eq!(second.position.y - root.position.y, 120.);
|
||||
assert!(
|
||||
plan::assignment::finish(&semantic, &f.project, &placed)
|
||||
.unwrap()
|
||||
.is_some()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,117 +30,6 @@ async fn mount() -> (Fixture, Mounted) {
|
||||
mounted.settle(&mut f.app).await;
|
||||
(f, mounted)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn actual_tree_outgoing_boundary_motion_preview_release_and_cancel() {
|
||||
for layer in [Layer::Oa, Layer::Sa] {
|
||||
let mut f = outgoing_fixture(layer);
|
||||
f.app.layer = layer;
|
||||
f.app.window_size = iced::Size::new(1440., 900.);
|
||||
let _ = f.app.update(Message::Select(f.work));
|
||||
let mut mounted = Mounted::new(&mut f.app).await;
|
||||
f.app.zoom = 0.75;
|
||||
f.app.pan = Vector::new(20., 15.);
|
||||
f.app.fit_to_view = false;
|
||||
mounted.settle(&mut f.app).await;
|
||||
let original = f.app.project().clone();
|
||||
let source = f.app.document.bundle().clone();
|
||||
let from = at(&mut mounted, &f, xy(660., 225.));
|
||||
mounted
|
||||
.batch(
|
||||
&mut f.app,
|
||||
&[
|
||||
Input::Mouse(mouse::Event::CursorMoved { position: from }),
|
||||
Input::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)),
|
||||
],
|
||||
mouse::Cursor::Available(from),
|
||||
)
|
||||
.await;
|
||||
// Separate input/update/layout turns expose the held boundary transition
|
||||
// that a one-batch distant drop cannot exercise.
|
||||
for x in [620., 560., 510., 499., 490.] {
|
||||
let to = at(&mut mounted, &f, xy(x, 225.));
|
||||
mounted
|
||||
.batch(
|
||||
&mut f.app,
|
||||
&[Input::Mouse(mouse::Event::CursorMoved { position: to })],
|
||||
mouse::Cursor::Available(to),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(f.app.project(), &original);
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
assert!(
|
||||
!f.app.allocation_drag.feedback.as_ref().unwrap().refused,
|
||||
"{layer:?} x={x}: {}",
|
||||
f.app.status
|
||||
);
|
||||
assert!(f.app.allocation_drag.preview.is_some());
|
||||
let _ = mounted.pixels(&f.app);
|
||||
}
|
||||
let expected = f
|
||||
.app
|
||||
.allocation_drag
|
||||
.preview
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.placement
|
||||
.diagram
|
||||
.clone();
|
||||
let to = at(&mut mounted, &f, xy(490., 225.));
|
||||
mounted
|
||||
.batch(
|
||||
&mut f.app,
|
||||
&[Input::Mouse(mouse::Event::ButtonReleased(
|
||||
mouse::Button::Left,
|
||||
))],
|
||||
mouse::Cursor::Available(to),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(&f.app.project().diagrams[&f.diagram], &expected);
|
||||
assert!(
|
||||
!f.app
|
||||
.project()
|
||||
.relations
|
||||
.values()
|
||||
.any(|r| r.kind() == RelationKind::Allocation && r.target() == f.work)
|
||||
);
|
||||
let _ = f.app.update(Message::Undo);
|
||||
mounted.settle(&mut f.app).await;
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
let from = at(&mut mounted, &f, xy(660., 225.));
|
||||
let to = at(&mut mounted, &f, xy(490., 225.));
|
||||
mounted
|
||||
.batch(
|
||||
&mut f.app,
|
||||
&[
|
||||
Input::Mouse(mouse::Event::CursorMoved { position: from }),
|
||||
Input::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)),
|
||||
Input::Mouse(mouse::Event::CursorMoved { position: to }),
|
||||
],
|
||||
mouse::Cursor::Available(to),
|
||||
)
|
||||
.await;
|
||||
mounted
|
||||
.batch(
|
||||
&mut f.app,
|
||||
&[key(keyboard::key::Named::Escape)],
|
||||
mouse::Cursor::Available(to),
|
||||
)
|
||||
.await;
|
||||
mounted
|
||||
.batch(
|
||||
&mut f.app,
|
||||
&[Input::Mouse(mouse::Event::ButtonReleased(
|
||||
mouse::Button::Left,
|
||||
))],
|
||||
mouse::Cursor::Available(to),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
assert!(f.app.allocation_drag.preview.is_none());
|
||||
assert!(!f.app.document.can_undo());
|
||||
}
|
||||
}
|
||||
fn canvas_bounds(mounted: &mut Mounted, app: &App) -> Rectangle {
|
||||
mounted
|
||||
.geometry(app)
|
||||
@@ -592,7 +481,6 @@ async fn actual_app_tree_exact_incoming_drag_keeps_destination_visible_and_canva
|
||||
if pan.y == -100. {
|
||||
// A genuine clipping refusal in the same held gesture, then
|
||||
// recovery at the original exact point: no camera rebasing.
|
||||
let retained = f.app.allocation_drag.preview.clone().unwrap();
|
||||
let clipped = at(&mut mounted, &f, xy(160., 110.));
|
||||
mounted
|
||||
.batch(
|
||||
@@ -604,19 +492,7 @@ async fn actual_app_tree_exact_incoming_drag_keeps_destination_visible_and_canva
|
||||
)
|
||||
.await;
|
||||
assert!(f.app.allocation_drag.feedback.as_ref().unwrap().refused);
|
||||
assert!(Arc::ptr_eq(
|
||||
f.app.allocation_drag.preview.as_ref().unwrap(),
|
||||
&retained
|
||||
));
|
||||
assert!(
|
||||
f.app
|
||||
.allocation_drag
|
||||
.feedback
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.ghost_delta
|
||||
.is_some()
|
||||
);
|
||||
assert!(f.app.allocation_drag.preview.is_none());
|
||||
assert_eq!(canvas_bounds(&mut mounted, &f.app), canvas);
|
||||
assert_eq!(destination_bounds(&mut mounted, &f.app), slot);
|
||||
assert_eq!(f.app.project(), &before);
|
||||
|
||||
@@ -1239,7 +1239,6 @@ fn destination_identity_does_not_describe_blocked_or_outside_viewport_as_unalloc
|
||||
inspection_targets: vec![],
|
||||
text: "A card blocks this drop".into(),
|
||||
refused: true,
|
||||
ghost_delta: None,
|
||||
};
|
||||
assert_eq!(feedback.destination_identity(), "No eligible destination");
|
||||
feedback.text = "Release inside the captured canvas".into();
|
||||
@@ -1247,361 +1246,3 @@ fn destination_identity_does_not_describe_blocked_or_outside_viewport_as_unalloc
|
||||
feedback.refused = false;
|
||||
assert_eq!(feedback.destination_identity(), "Outside performers");
|
||||
}
|
||||
|
||||
fn outgoing_fixture(layer: Layer) -> Fixture {
|
||||
let mut f = fixture(layer);
|
||||
drag(&mut f, screen(xy(160., 190.)));
|
||||
let mut project = f.app.project().clone();
|
||||
let d = project.diagrams.get_mut(&f.diagram).unwrap();
|
||||
let performer = d.nodes.values_mut().find(|n| n.element == f.a).unwrap();
|
||||
performer.position = xy(500., 100.);
|
||||
performer.size = Size {
|
||||
width: 300.,
|
||||
height: 300.,
|
||||
};
|
||||
d.nodes.get_mut(&f.node).unwrap().position = xy(540., 190.);
|
||||
replace(&mut f, project);
|
||||
f
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outgoing_boundary_drop_clears_source_without_changing_other_placements() {
|
||||
for layer in [Layer::Oa, Layer::Sa] {
|
||||
let mut f = outgoing_fixture(layer);
|
||||
let before = f.app.project().clone();
|
||||
let source = f.app.document.bundle().clone();
|
||||
let from = screen(xy(660., 225.));
|
||||
let to = screen(xy(490., 225.));
|
||||
let mut events = batch(&f.app, from, to);
|
||||
let release = events.pop().unwrap();
|
||||
send(&mut f.app, events);
|
||||
let feedback = f.app.allocation_drag.feedback.as_ref().unwrap();
|
||||
assert!(!feedback.refused, "{}", feedback.text);
|
||||
let preview = f.app.allocation_drag.preview.as_ref().unwrap();
|
||||
let expected_diagram = preview.placement.diagram.clone();
|
||||
let work = &expected_diagram.nodes[&f.node];
|
||||
assert!(work.position.x + work.size.width <= 490.);
|
||||
assert_eq!(work.position.y, 190.);
|
||||
for (id, node) in &before.diagrams[&f.diagram].nodes {
|
||||
if *id != f.node {
|
||||
assert_eq!(&expected_diagram.nodes[id], node);
|
||||
}
|
||||
}
|
||||
assert_eq!(f.app.project(), &before);
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
let _ = f.app.update(release);
|
||||
assert_eq!(&f.app.project().diagrams[&f.diagram], &expected_diagram);
|
||||
assert!(
|
||||
!f.app
|
||||
.project()
|
||||
.relations
|
||||
.values()
|
||||
.any(|r| r.kind() == RelationKind::Allocation && r.target() == f.work)
|
||||
);
|
||||
let after = f.app.project().clone();
|
||||
let saved = f.app.document.bundle().clone();
|
||||
let _ = f.app.update(Message::Undo);
|
||||
assert_eq!(f.app.project(), &before);
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
assert!(!f.app.document.can_undo());
|
||||
let _ = f.app.update(Message::Redo);
|
||||
assert_eq!(f.app.project(), &after);
|
||||
assert_eq!(f.app.document.bundle(), &saved);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outgoing_clearance_collision_refuses_release_without_source_or_history_mutation() {
|
||||
for layer in [Layer::Oa, Layer::Sa] {
|
||||
let mut f = outgoing_fixture(layer);
|
||||
let mut project = f.app.project().clone();
|
||||
let obstacle = project
|
||||
.add_element(
|
||||
project.elements[&f.work].kind(),
|
||||
layer,
|
||||
"Unrelated work",
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
let obstacle_node = project.place(f.diagram, obstacle, xy(240., 190.));
|
||||
replace(&mut f, project);
|
||||
// A refused release must preserve an existing redo branch, too.
|
||||
let _ = f.app.update(Message::Command(Command::Rename(
|
||||
f.work,
|
||||
"Temporary".into(),
|
||||
)));
|
||||
let _ = f.app.update(Message::Undo);
|
||||
let before = f.app.project().clone();
|
||||
let source = f.app.document.bundle().clone();
|
||||
let snapshot = f.app.document.snapshot();
|
||||
let revision = f.app.document.revision();
|
||||
let from = screen(xy(660., 225.));
|
||||
let to = screen(xy(490., 225.));
|
||||
let mut events = batch(&f.app, from, to);
|
||||
let release = events.pop().unwrap();
|
||||
send(&mut f.app, events);
|
||||
|
||||
let active = f.app.allocation_drag.active.as_ref().unwrap();
|
||||
let p = &active.press;
|
||||
let frozen = active.frozen.as_ref().unwrap();
|
||||
let owner = frozen.targets.iter().find(|t| t.element == f.a).unwrap();
|
||||
assert_eq!(p.start, from);
|
||||
assert!(contains(owner.region, p.stamp.world(from)));
|
||||
assert!(p.stamp.world(to).x < owner.region.x);
|
||||
assert_eq!(
|
||||
frozen.resolve(p.stamp, Some(to), false),
|
||||
Hit::Destination(plan::Destination::OutsidePerformers, None),
|
||||
"The pointer must reach empty canvas, not be occluded by the obstacle"
|
||||
);
|
||||
let candidate = active
|
||||
.cache
|
||||
.iter()
|
||||
.find(|(destination, _)| *destination == plan::Destination::OutsidePerformers)
|
||||
.unwrap()
|
||||
.1
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let affected = match &active.prepared {
|
||||
Prepared::Singleton(scope) => &scope.placements,
|
||||
Prepared::Assignment(scope) => scope.affected(),
|
||||
_ => panic!("expected assignment gesture"),
|
||||
};
|
||||
let requested = xy(370., 190.);
|
||||
let presentation = plan::PresentationContext {
|
||||
viewport: p.stamp.viewport(),
|
||||
zoom: p.stamp.zoom,
|
||||
target: None,
|
||||
};
|
||||
assert!(matches!(
|
||||
candidate.place(requested, presentation),
|
||||
Err(plan::Refusal::LayoutRequired(_))
|
||||
));
|
||||
let proposed = clearance::requests(
|
||||
(f.app.project(), f.app.document.view_index()),
|
||||
(candidate.project(), candidate.index()),
|
||||
f.diagram,
|
||||
affected,
|
||||
f.node,
|
||||
requested,
|
||||
(p.stamp.world(from), p.stamp.world(to)),
|
||||
);
|
||||
assert_eq!(
|
||||
proposed.len(),
|
||||
1,
|
||||
"a genuine left crossing must propose clearance"
|
||||
);
|
||||
assert!(proposed[0].x < requested.x);
|
||||
let work = &before.diagrams[&f.diagram].nodes[&f.node];
|
||||
let obstacle = &before.diagrams[&f.diagram].nodes[&obstacle_node];
|
||||
assert!(obstacle.position.x + obstacle.size.width < 490.);
|
||||
assert!(proposed[0].x + work.size.width <= owner.region.x - 10.);
|
||||
assert!(proposed[0].x < obstacle.position.x + obstacle.size.width);
|
||||
assert!(obstacle.position.x < proposed[0].x + work.size.width);
|
||||
assert_eq!(proposed[0].y, obstacle.position.y);
|
||||
assert!(matches!(
|
||||
candidate.place(proposed[0], presentation),
|
||||
Err(plan::Refusal::LayoutRequired(message)) if message.contains("overlapping cards")
|
||||
));
|
||||
let feedback = f.app.allocation_drag.feedback.as_ref().unwrap();
|
||||
assert!(feedback.refused, "{}", feedback.text);
|
||||
assert!(feedback.ghost_delta.is_some());
|
||||
assert!(f.app.allocation_drag.preview.is_none());
|
||||
assert_eq!(f.app.project(), &before);
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
assert!(Arc::ptr_eq(&snapshot, &f.app.document.snapshot()));
|
||||
let _ = f.app.update(release);
|
||||
assert!(
|
||||
f.app.status.contains("overlapping cards"),
|
||||
"{}",
|
||||
f.app.status
|
||||
);
|
||||
assert!(f.app.allocation_drag.active.is_none());
|
||||
assert!(f.app.allocation_drag.preview.is_none());
|
||||
assert_eq!(f.app.project(), &before);
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
assert_eq!(f.app.document.revision(), revision);
|
||||
assert!(Arc::ptr_eq(&snapshot, &f.app.document.snapshot()));
|
||||
assert!(!f.app.document.can_undo());
|
||||
assert!(f.app.document.can_redo());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outgoing_clearance_preserves_source_enclosure_and_allocated_sibling() {
|
||||
for layer in [Layer::Oa, Layer::Sa] {
|
||||
let mut f = outgoing_fixture(layer);
|
||||
let mut project = f.app.project().clone();
|
||||
let sibling = project
|
||||
.add_element(
|
||||
project.elements[&f.work].kind(),
|
||||
layer,
|
||||
"Remaining work",
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
let sibling_node = project.place(f.diagram, sibling, xy(540., 450.));
|
||||
let allocation = project.relate(
|
||||
RelationKind::Allocation,
|
||||
"Keep responsibility",
|
||||
f.a,
|
||||
sibling,
|
||||
);
|
||||
replace(&mut f, project);
|
||||
let before = f.app.project().clone();
|
||||
let source = f.app.document.bundle().clone();
|
||||
let view = projection::project_view(&before, f.diagram);
|
||||
let owner = view.nodes.iter().find(|n| n.element == f.a).unwrap();
|
||||
let bottom = owner.position.y + owner.size.height;
|
||||
let stored_owner = &before.diagrams[&f.diagram].nodes[&owner.id];
|
||||
assert!(
|
||||
bottom > stored_owner.position.y + stored_owner.size.height,
|
||||
"The retained sibling must enlarge the projected source enclosure"
|
||||
);
|
||||
let from = screen(xy(660., 225.));
|
||||
let to = screen(xy(660., bottom + 1.));
|
||||
let mut events = batch(&f.app, from, to);
|
||||
let release = events.pop().unwrap();
|
||||
send(&mut f.app, events);
|
||||
let active = f.app.allocation_drag.active.as_ref().unwrap();
|
||||
let p = &active.press;
|
||||
let frozen = active.frozen.as_ref().unwrap();
|
||||
let target = frozen.targets.iter().find(|t| t.element == f.a).unwrap();
|
||||
assert_eq!(p.start, from);
|
||||
assert!(contains(target.region, p.stamp.world(from)));
|
||||
assert!(p.stamp.world(to).y >= target.region.y + target.region.height);
|
||||
assert_eq!(
|
||||
frozen.resolve(p.stamp, Some(to), false),
|
||||
Hit::Destination(plan::Destination::OutsidePerformers, None)
|
||||
);
|
||||
let preview = f.app.allocation_drag.preview.as_ref().expect(&f.app.status);
|
||||
assert!(!f.app.allocation_drag.feedback.as_ref().unwrap().refused);
|
||||
let requested = xy(540., 190. + to.y - from.y);
|
||||
assert!(matches!(
|
||||
preview.candidate.place(
|
||||
requested,
|
||||
plan::PresentationContext {
|
||||
viewport: p.stamp.viewport(),
|
||||
zoom: p.stamp.zoom,
|
||||
target: None,
|
||||
}
|
||||
),
|
||||
Err(plan::Refusal::LayoutRequired(_))
|
||||
));
|
||||
let moved = &preview.placement.diagram.nodes[&f.node];
|
||||
assert_eq!(moved.position.x, 540.);
|
||||
assert!(moved.position.y >= bottom + 10.);
|
||||
assert!(moved.position.y > requested.y);
|
||||
assert_eq!(
|
||||
preview
|
||||
.placement
|
||||
.view
|
||||
.nodes
|
||||
.iter()
|
||||
.find(|n| n.id == owner.id)
|
||||
.unwrap(),
|
||||
owner
|
||||
);
|
||||
let remaining = preview
|
||||
.placement
|
||||
.view
|
||||
.nodes
|
||||
.iter()
|
||||
.find(|n| n.id == sibling_node)
|
||||
.unwrap();
|
||||
assert_eq!(remaining.visual_parent, Some(owner.id));
|
||||
assert_eq!(
|
||||
remaining.position,
|
||||
before.diagrams[&f.diagram].nodes[&sibling_node].position
|
||||
);
|
||||
assert_eq!(
|
||||
&preview.project().relations[&allocation],
|
||||
&before.relations[&allocation]
|
||||
);
|
||||
for (id, node) in &before.diagrams[&f.diagram].nodes {
|
||||
if *id != f.node {
|
||||
assert_eq!(&preview.placement.diagram.nodes[id], node);
|
||||
}
|
||||
}
|
||||
let mut expected = preview.project().clone();
|
||||
expected
|
||||
.diagrams
|
||||
.insert(f.diagram, preview.placement.diagram.clone());
|
||||
assert_eq!(f.app.project(), &before);
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
let _ = f.app.update(release);
|
||||
assert_eq!(f.app.project(), &expected, "{}", f.app.status);
|
||||
assert_eq!(f.app.document.revision(), 1);
|
||||
assert_eq!(
|
||||
validation::effective_performer(f.app.project(), f.work),
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
validation::effective_performer(f.app.project(), sibling),
|
||||
Some(f.a)
|
||||
);
|
||||
assert_eq!(
|
||||
&f.app.project().relations[&allocation],
|
||||
&before.relations[&allocation]
|
||||
);
|
||||
let after = f.app.document.bundle().clone();
|
||||
let _ = f.app.update(Message::Undo);
|
||||
assert_eq!(f.app.project(), &before);
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
assert!(!f.app.document.can_undo());
|
||||
let _ = f.app.update(Message::Redo);
|
||||
assert_eq!(f.app.project(), &expected);
|
||||
assert_eq!(f.app.document.bundle(), &after);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn refused_motion_retains_last_scene_but_release_never_commits_it() {
|
||||
let mut f = outgoing_fixture(Layer::Sa);
|
||||
let mut project = f.app.project().clone();
|
||||
let obstacle = project
|
||||
.add_element(Kind::Function, Layer::Sa, "Unrelated work", None)
|
||||
.unwrap();
|
||||
project.place(f.diagram, obstacle, xy(1250., 120.));
|
||||
replace(&mut f, project);
|
||||
let original = f.app.project().clone();
|
||||
let source = f.app.document.bundle().clone();
|
||||
let p = admit_press(&mut f);
|
||||
let clear = screen(xy(450., 225.));
|
||||
let _ = f.app.update(Message::WorkDrag(Event::Preview(
|
||||
p.stamp,
|
||||
p.token,
|
||||
Some(clear),
|
||||
)));
|
||||
let last = f.app.allocation_drag.preview.clone().expect(&f.app.status);
|
||||
// Another work card blocks this location: the prior legal outgoing scene is display
|
||||
// state only, and must not become a fallback command on release.
|
||||
let blocked = screen(xy(1260., 130.));
|
||||
let _ = f.app.update(Message::WorkDrag(Event::Preview(
|
||||
p.stamp,
|
||||
p.token,
|
||||
Some(blocked),
|
||||
)));
|
||||
assert!(f.app.allocation_drag.feedback.as_ref().unwrap().refused);
|
||||
assert!(
|
||||
f.app
|
||||
.allocation_drag
|
||||
.feedback
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.ghost_delta
|
||||
.is_some()
|
||||
);
|
||||
assert!(Arc::ptr_eq(
|
||||
f.app.allocation_drag.preview.as_ref().unwrap(),
|
||||
&last
|
||||
));
|
||||
let _ = f.app.update(Message::WorkDrag(Event::Release(
|
||||
p.stamp,
|
||||
p.token,
|
||||
Some(blocked),
|
||||
)));
|
||||
assert_eq!(f.app.project(), &original);
|
||||
assert_eq!(f.app.document.bundle(), &source);
|
||||
assert!(!f.app.document.can_undo());
|
||||
assert!(f.app.allocation_drag.preview.is_none());
|
||||
}
|
||||
|
||||
@@ -243,21 +243,6 @@ impl canvas::Program<Message> for WorkFeedback<'_> {
|
||||
let Some(frozen) = &feedback.frozen else {
|
||||
return vec![];
|
||||
};
|
||||
if let Some(delta) = feedback.ghost_delta {
|
||||
for region in &frozen.moving {
|
||||
let top = Point::new(
|
||||
(region.x + delta.x) * self.0.zoom + self.0.pan.x,
|
||||
(region.y + delta.y) * self.0.zoom + self.0.pan.y,
|
||||
);
|
||||
frame.stroke(
|
||||
&Path::rectangle(
|
||||
top,
|
||||
iced::Size::new(region.width * self.0.zoom, region.height * self.0.zoom),
|
||||
),
|
||||
Stroke::default().with_color(color).with_width(2.),
|
||||
);
|
||||
}
|
||||
}
|
||||
for index in &feedback.targets {
|
||||
let target = &frozen.targets[*index];
|
||||
let region = target.region;
|
||||
|
||||
+1
-13
@@ -2702,19 +2702,7 @@ performer change with diagram placement. The preview MUST identify the
|
||||
destination and preserve readable work and destination identity. Destination
|
||||
identity is shown outside the canvas, independently of explanatory or refusal
|
||||
text. The outlined target's hit region remains fixed throughout the gesture;
|
||||
feedback MUST NOT obscure the work. Preserve pointer-relative placement when
|
||||
the requested position is valid. When an outgoing drop would leave work
|
||||
overlapping its former performer, the editor MAY propose a minimal grid-aligned
|
||||
translation through a crossed performer boundary, with one grid unit of
|
||||
clearance. It MUST preview that exact position, translate the complete affected
|
||||
work group rigidly, and recheck all semantic and collision constraints on release.
|
||||
It MUST NOT move unrelated placements or search arbitrary free space. If no
|
||||
proposal is valid, a pointer-following outline MAY accompany the last valid
|
||||
preview; that retained preview MUST NOT authorize a refused release.
|
||||
Outgoing work headers MAY be partly outside the viewport provided each retains
|
||||
at least a 24-by-24 logical-pixel grab region. Releasing the pointer outside the
|
||||
viewport still cancels. Other assignment and Arrange gestures retain their
|
||||
complete-header visibility requirement.
|
||||
feedback MUST NOT obscure the work or change its pointer-relative placement.
|
||||
A clean click selects without applying unrelated drafts. A refused work press
|
||||
with an unapplied property draft MUST preserve its text, caret and focused
|
||||
editor. An accepted drag is one atomic model/source/history transaction:
|
||||
|
||||
+1
-13
@@ -2128,19 +2128,7 @@ performer change with diagram placement. The preview MUST identify the
|
||||
destination and preserve readable work and destination identity. Destination
|
||||
identity is shown outside the canvas, independently of explanatory or refusal
|
||||
text. The outlined target's hit region remains fixed throughout the gesture;
|
||||
feedback MUST NOT obscure the work. Preserve pointer-relative placement when
|
||||
the requested position is valid. When an outgoing drop would leave work
|
||||
overlapping its former performer, the editor MAY propose a minimal grid-aligned
|
||||
translation through a crossed performer boundary, with one grid unit of
|
||||
clearance. It MUST preview that exact position, translate the complete affected
|
||||
work group rigidly, and recheck all semantic and collision constraints on release.
|
||||
It MUST NOT move unrelated placements or search arbitrary free space. If no
|
||||
proposal is valid, a pointer-following outline MAY accompany the last valid
|
||||
preview; that retained preview MUST NOT authorize a refused release.
|
||||
Outgoing work headers MAY be partly outside the viewport provided each retains
|
||||
at least a 24-by-24 logical-pixel grab region. Releasing the pointer outside the
|
||||
viewport still cancels. Other assignment and Arrange gestures retain their
|
||||
complete-header visibility requirement.
|
||||
feedback MUST NOT obscure the work or change its pointer-relative placement.
|
||||
A clean click selects without applying unrelated drafts. A refused work press
|
||||
with an unapplied property draft MUST preserve its text, caret and focused
|
||||
editor. An accepted drag is one atomic model/source/history transaction:
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
# Outgoing allocation dragging
|
||||
|
||||
Scope: [issue 40](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/40),
|
||||
based on published Windows source `715036e132677dd2bc2fb37ed316d93dc9987aec`.
|
||||
This contribution is not integrated release acceptance. User requirements remain
|
||||
in `PROJECT_GOAL.md`; this note records a revision to derived interaction policy.
|
||||
|
||||
## Reproduction and cause
|
||||
|
||||
The released executable SHA256
|
||||
`2c03bd6cc3f1110c219e4f57ab94874a121590f83779239a93289b7170664399`
|
||||
opened a copied Allocation/Process companion fixture on Windows. At 1440x900,
|
||||
72% Fit, the OA assign view's X-receive was dragged from window (486,546) to
|
||||
(365,546), just beyond A's left edge. It remained assigned at its original
|
||||
position, reporting enlarged card overlap. A control drag to (625,572) removed
|
||||
assignment; Undo restored the original scene. These are actual native end-state
|
||||
observations; intermediate jitter was diagnosed from source, not frame capture.
|
||||
|
||||
Frozen targets resolve from the pointer, while placement retains its grab
|
||||
offset. The pointer therefore leaves its performer before the full work card
|
||||
does. Former parent/child intersection becomes unrelated overlap after removing
|
||||
allocation. Refused motion previously cleared the preview and redrew the saved
|
||||
scene. Additionally, whole-header viewport containment rejects a useful outgoing
|
||||
position in the fitted reproduction even when its model geometry is valid.
|
||||
|
||||
## Selected policy
|
||||
|
||||
Try exact snapped pointer placement first. Only an outgoing assignment candidate
|
||||
with a placement refusal may propose bounded source clearance: move the entire
|
||||
captured work footprint through a crossed frozen source boundary, clearing the
|
||||
post-removal source enclosure by one 10-world-unit grid cell. Consider at most
|
||||
four directions, ordered by press-to-pointer boundary-crossing fraction and a
|
||||
fixed direction tie-break. Existing placement, collision, semantic, exact-command
|
||||
and source/history admission remain authoritative. No neighbor is moved, no
|
||||
general packing/search occurs, and no semantic refusal is overridden.
|
||||
|
||||
The accepted/candidate semantic indexes are reused during fallback projections.
|
||||
Outgoing headers may be partly clipped but each must retain a 24x24 logical-pixel
|
||||
grab region. Other assignment and Arrange visibility rules remain unchanged.
|
||||
The exact corrected candidate is previewed; release recomputes it. Blocked
|
||||
in-bounds motion retains its last admitted scene and adds an orange pointer
|
||||
outline. This display state confers no permission to commit on refused release.
|
||||
Cancel, outside release and gesture invalidation retire it normally.
|
||||
|
||||
Rejected alternatives: retaining a moving outline alone leaves the boundary
|
||||
dead band; allowing unrelated overlap makes unassigned work look allocated;
|
||||
general auto-layout changes unrelated placement and makes drag intent harder to
|
||||
predict. The previous unconditional pointer-offset rule is narrowed in
|
||||
`docs/language.rst` and its HTML copy. Real neighboring-card collisions and
|
||||
insufficient visible grab area can still refuse a drop.
|
||||
|
||||
## Verification status
|
||||
|
||||
Independent source diagnosis and repair critique found no semantic/stale/cancel
|
||||
bypass. Review exposed the remaining whole-header camera restriction and an
|
||||
obsolete retained-preview assertion; both were revised. Added checks cover
|
||||
OA/SA boundary clearance, corners, source shrinkage, rigid descendants/groups,
|
||||
real App frame-by-frame input, exact source/history, cancellation, blocked release
|
||||
and outgoing grab-area boundaries. At clean source
|
||||
`1a669130fb6d2b65279aab3847e966a1a282c191`, the Windows allocation-drag
|
||||
suite passes 121 tests (none failed or ignored; 1,424 filtered out), strict
|
||||
desktop all-target Clippy passes, and the normal desktop development build
|
||||
passes. [Raw results and reproduction commands](experiments/drag-out-20260925/README.md)
|
||||
preserve the source, platform, failed attempts and exact scope. These checks do
|
||||
not prove native usability. Computer Use was stopped with the physical Escape
|
||||
key before the changed executable could be inspected. Fitted-view dragging,
|
||||
clipped-card identification/regrabbing, native Undo/Redo and Save/reopen remain
|
||||
unverified. The issue remains open; no integration or release acceptance follows
|
||||
from the targeted gates.
|
||||
|
||||
Test-only successor `24b1eab07d306d8cb091bb46f7daf9f027a8f1c0` additionally
|
||||
checks an actual fallback blocked by unrelated work, including preservation of
|
||||
an existing redo branch, and an outgoing move while an allocated sibling keeps
|
||||
the source enclosure expanded. Both run for OA and SA. All 123 allocation-drag
|
||||
tests and strict desktop Clippy pass at that successor. Fresh independent review
|
||||
confirms those tests exercise their claimed invariants, with no material source
|
||||
finding in this scope. The same linked evidence includes the new logs and review;
|
||||
production code and native-acceptance limits remain unchanged.
|
||||
|
||||
The first build attempt failed before tests because the sparse checkout omitted
|
||||
`build/windows_manifest.rs`; restoring the tracked build directory corrected the
|
||||
checkout. The local drive initially had about 22 MB free. Git sparse checkout and
|
||||
Cargo's package-scoped cleanup of inactive desktop artifacts recovered capacity.
|
||||
Automatic review rejected recursive deletion of the extracted preview; it was
|
||||
left intact. No published package or unique evidence was deleted.
|
||||
The second attempt also exposed omitted tracked harness fixtures and a `Self`
|
||||
typo in a standalone test helper; both were corrected before the passing run.
|
||||
That failed compiler process was terminated after its errors were captured.
|
||||
@@ -1 +0,0 @@
|
||||
*.log -text
|
||||
@@ -1,91 +0,0 @@
|
||||
# Small architecture diagram CPU investigation
|
||||
|
||||
Question: does core projection/routing explain [issue 44's low FPS](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/44)
|
||||
with roughly eight architecture cards? This experiment narrows that question;
|
||||
it neither reproduces native frame rate nor establishes a complete cause.
|
||||
|
||||
## Workload and source
|
||||
|
||||
The screenshot uses names from `examples/release1`. Its exact model, projection,
|
||||
camera and authored geometry are unavailable. The probe loads the unchanged
|
||||
`examples/release1/model.json`, measures its five saved views, and constructs a
|
||||
clearly labeled eight-card SA Overview approximation using those semantic
|
||||
elements. Approximate coordinates and stable placement IDs are in the probe;
|
||||
it has 8 projected nodes, 6 ports and 13 projected edges. It is not a recovered
|
||||
copy of the user's diagram. All data changes occur in memory.
|
||||
|
||||
Source: `24b1eab07d306d8cb091bb46f7daf9f027a8f1c0`; core, manifest and lockfile
|
||||
are unchanged from the drag contribution's `1a669130` production source.
|
||||
Windows 10.0.26200, Rust 1.98.1, x86_64-pc-windows-gnullvm, LLVM-MinGW
|
||||
20260908 UCRT, reported CPU Intel Core i7-10870H with 4 exposed cores/threads.
|
||||
The probe was optimized with `-O` and linked to the existing **unoptimized
|
||||
development-profile core library** used by the completed desktop test build.
|
||||
This distinction matters: optimizing the driver does not optimize that library.
|
||||
The desktop test process had completed before measurement; no Cargo compilation
|
||||
was started until after measurement. Other operating-system workloads were not
|
||||
controlled, so outliers are retained rather than interpreted as stable capacity.
|
||||
|
||||
## Method and results
|
||||
|
||||
Each phase gets 3 warmups and 40 timed samples, with returned values passed to
|
||||
`black_box`. Reported p50/p95 select sorted index `ceil((n-1)*p)` as implemented
|
||||
in the source. Returned output destruction is outside each timed phase. Diagram
|
||||
movement uses a deterministic small delta sequence and the existing descendant
|
||||
and authored-route translation APIs. Index creation, projection, routing, and
|
||||
combined movement preparation are measured separately. The probe does not model
|
||||
allocation transaction admission or an Iced frame.
|
||||
|
||||
For the eight-card approximation, `performance-01.log` records:
|
||||
|
||||
| Phase | p50 ms | p95 ms | max ms |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| Reused-index projection | 0.3885 | 0.7550 | 1.2965 |
|
||||
| Fresh-index projection | 1.7135 | 2.7022 | 4.2204 |
|
||||
| Settled routing | 2.4525 | 4.4617 | 4.7735 |
|
||||
| Moved routing | 3.1907 | 4.4781 | 4.5672 |
|
||||
| Movement preparation + projection + routing | 4.2640 | 6.8259 | 8.8052 |
|
||||
|
||||
This workload does not expose severe core latency sufficient by itself to
|
||||
explain very low FPS. It does not rule out different authored routes, allocation
|
||||
admission, hardware/rendering, or the user's exact scene. Repeated fresh-index
|
||||
projection has a measurable cost, but no change is justified solely by this
|
||||
small sample. No FPS or performance-fix claim follows.
|
||||
|
||||
## Source observations and next discriminating measurement
|
||||
|
||||
Independent read-only hot-path review found that `DiagramCanvas::scene` already
|
||||
caches projection and routing by semantic context and transient geometry.
|
||||
Ordinary node movement changes preview geometry and routes the full view;
|
||||
route gestures use `route_edge_preview`. Ordinary hover need not reroute.
|
||||
|
||||
`diagram/port_labels.rs` requests redraw on every mouse event, including when
|
||||
no tooltip is visible. `DiagramCanvas::draw` rebuilds geometry and each dot-grid
|
||||
circle on every draw. At a 1900x660 canvas this yields about 2,240 circles at
|
||||
zoom 1 and 6,528 at minimum spacing. Scene caching does not cache that geometry.
|
||||
`views.rs` also performs an unindexed `project_view` during app view rebuilding;
|
||||
legacy node-motion redraw does not itself require that full UI rebuild.
|
||||
|
||||
Next, measure actual canvas draw/frame costs independently for idle hover, pan,
|
||||
ordinary node drag and allocation drag, with grid generation separated from
|
||||
node/edge/text rendering and frame presentation. Compare the same scene/camera
|
||||
and renderer before changing production code. Native automation was stopped
|
||||
with Escape; no GPU/frame measurement was attempted in this experiment. Live
|
||||
ownership and subsequent results belong to issue 44.
|
||||
|
||||
## Reproduction
|
||||
|
||||
Build `oa-core` at the identified source with the stated Windows toolchain, then
|
||||
compile this standalone probe against that exact library and matching dependency
|
||||
directory. For a fresh standard Cargo development build:
|
||||
|
||||
```powershell
|
||||
cargo build --locked -p oa-core
|
||||
rustc --edition=2024 -O harness/experiments/architecture-perf-20260925/architecture_perf_probe.rs --extern oa_core=target/debug/liboa_core.rlib -L dependency=target/debug/deps -C linker=clang.exe -o architecture_perf_probe.exe
|
||||
./architecture_perf_probe.exe examples/release1/model.json 40
|
||||
```
|
||||
|
||||
The actual run linked `target/debug/deps/liboa_core-2f3c5174cb6398fd.rlib`
|
||||
and used the same dependency directory. Set the linker/runtime PATH as required
|
||||
by the Windows toolchain. Compiler flags, core profile, machine load and fixture
|
||||
all affect timings; preserve them when comparing candidates. This standalone
|
||||
probe is experimental evidence, not a production dependency or a timing test.
|
||||
@@ -1,166 +0,0 @@
|
||||
//! Local-only CPU diagnosis. Does not measure native FPS, canvas redraw, or GPU.
|
||||
//! Usage: architecture_perf_probe.exe PATH_TO_RELEASE1_MODEL_JSON [SAMPLES=40]
|
||||
use oa_core::{persistence, projection, routing, view_options::ViewIndex, *};
|
||||
use std::{collections::BTreeMap, hint::black_box, time::Instant};
|
||||
|
||||
fn measure<T>(label: &str, samples: usize, mut f: impl FnMut(usize) -> T) {
|
||||
for i in 0..3 {
|
||||
black_box(f(i));
|
||||
}
|
||||
let mut ms = Vec::with_capacity(samples);
|
||||
for i in 0..samples {
|
||||
let start = Instant::now();
|
||||
let output = black_box(f(i));
|
||||
ms.push(start.elapsed().as_secs_f64() * 1000.0);
|
||||
drop(output); // Exclude destruction consistently from each timed phase.
|
||||
}
|
||||
ms.sort_by(f64::total_cmp);
|
||||
let percentile = |p: f64| ms[((samples - 1) as f64 * p).ceil() as usize];
|
||||
println!(
|
||||
"{label}: n={samples} p50_ms={:.4} p95_ms={:.4} max_ms={:.4}",
|
||||
percentile(0.5),
|
||||
percentile(0.95),
|
||||
ms[samples - 1]
|
||||
);
|
||||
}
|
||||
|
||||
fn probe(p: &Project, d: &Diagram, samples: usize) {
|
||||
let index = ViewIndex::new(p);
|
||||
let view = projection::project_diagram_with_index(p, d, &index);
|
||||
println!(
|
||||
"\nview={} projection={:?} nodes={} ports={} edges={}",
|
||||
d.name,
|
||||
d.projection,
|
||||
view.nodes.len(),
|
||||
view.ports.len(),
|
||||
view.edges.len()
|
||||
);
|
||||
measure("index_new", samples, |_| ViewIndex::new(black_box(p)));
|
||||
measure("projection_reused_index", samples, |_| {
|
||||
projection::project_diagram_with_index(black_box(p), black_box(d), black_box(&index))
|
||||
});
|
||||
measure("projection_fresh_index", samples, |_| {
|
||||
projection::project_diagram(black_box(p), black_box(d))
|
||||
});
|
||||
measure("routing_settled", samples, |_| {
|
||||
routing::route_diagram(black_box(p), black_box(d), black_box(&view))
|
||||
});
|
||||
// Deterministic slight motion of the first root card. Includes the same
|
||||
// descendant/route translation as legacy single-card canvas drag. This is
|
||||
// presentation-only, not the allocation transaction pipeline.
|
||||
let Some(root) = view.nodes.iter().find(|n| n.visual_parent.is_none()) else {
|
||||
return;
|
||||
};
|
||||
println!("moving_root={} element={}", root.id, p.named(root.element));
|
||||
let mut moved = projection::descendant_nodes(p, d.id, root.id);
|
||||
moved.push(root.id);
|
||||
let make_moved = |i: usize| {
|
||||
let delta = Position {
|
||||
x: (i % 21) as f32 * 3.0,
|
||||
y: (i % 11) as f32 * 2.0,
|
||||
};
|
||||
let mut preview = d.clone();
|
||||
let deltas = moved
|
||||
.iter()
|
||||
.map(|id| (*id, delta))
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
for route in projection::translated_routes(p, d, &deltas) {
|
||||
if let Some(stored) = preview.routes.iter_mut().find(|r| r.edge == route.edge) {
|
||||
*stored = route;
|
||||
} else {
|
||||
preview.routes.push(route);
|
||||
}
|
||||
}
|
||||
for id in &moved {
|
||||
if let Some(n) = preview.nodes.get_mut(id) {
|
||||
n.position.x += delta.x;
|
||||
n.position.y += delta.y;
|
||||
}
|
||||
}
|
||||
preview
|
||||
};
|
||||
let previews = (0..samples.max(3)).map(make_moved).collect::<Vec<_>>();
|
||||
let projected = previews
|
||||
.iter()
|
||||
.map(|d| projection::project_diagram_with_index(p, d, &index))
|
||||
.collect::<Vec<_>>();
|
||||
measure("moved_projection", samples, |i| {
|
||||
projection::project_diagram_with_index(p, black_box(&previews[i]), &index)
|
||||
});
|
||||
measure("moved_routing", samples, |i| {
|
||||
routing::route_diagram(p, black_box(&previews[i]), black_box(&projected[i]))
|
||||
});
|
||||
measure("moved_prepare_projection_routing", samples, |i| {
|
||||
let preview = make_moved(i);
|
||||
let view = projection::project_diagram_with_index(p, &preview, &index);
|
||||
routing::route_diagram(p, &preview, &view)
|
||||
});
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = std::env::args().collect::<Vec<_>>();
|
||||
let path = args
|
||||
.get(1)
|
||||
.ok_or("usage: architecture_perf_probe PATH [SAMPLES]")?;
|
||||
let samples = args
|
||||
.get(2)
|
||||
.map(|s| s.parse::<usize>())
|
||||
.transpose()?
|
||||
.unwrap_or(40)
|
||||
.max(1);
|
||||
let p = persistence::decode(&std::fs::read(path)?)?;
|
||||
println!(
|
||||
"CPU-only probe; samples={samples}; fixture={path}; elements={} relations={}",
|
||||
p.elements.len(),
|
||||
p.relations.len()
|
||||
);
|
||||
for d in p.diagrams.values() {
|
||||
probe(&p, d, samples);
|
||||
}
|
||||
// Approximation of the reported eight-card screenshot, not an exact repro:
|
||||
// fixture semantics, Overview projection, synthetic positions/card sizes.
|
||||
let mut approx = p.clone();
|
||||
let id: Id = "f0440000-0000-4000-8000-000000000001".parse()?;
|
||||
approx.diagrams.insert(
|
||||
id,
|
||||
Diagram {
|
||||
id,
|
||||
alias: "fps44_approx_overview".into(),
|
||||
name: "APPROXIMATION eight-card SA Overview".into(),
|
||||
description: "Synthetic positions, not user geometry".into(),
|
||||
layer: Layer::Sa,
|
||||
projection: ProjectionKind::Overview,
|
||||
view_options: Default::default(),
|
||||
nodes: BTreeMap::new(),
|
||||
routes: vec![],
|
||||
layout: None,
|
||||
},
|
||||
);
|
||||
for (ordinal, (alias, x, y)) in [
|
||||
("sa_assessment_procedure", 30., 240.),
|
||||
("sa_triage", 510., 240.),
|
||||
("sa_control", 990., 240.),
|
||||
("sa_technician", 530., 440.),
|
||||
("sa_assess", 1490., 240.),
|
||||
("sa_repair", 1030., 440.),
|
||||
("sa_confirm", 1530., 440.),
|
||||
("sa_reset", 30., 440.),
|
||||
]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
let element = approx
|
||||
.elements
|
||||
.values()
|
||||
.find(|e| e.alias == alias)
|
||||
.ok_or_else(|| format!("missing alias {alias}"))?
|
||||
.id;
|
||||
let generated = approx.place(id, element, Position { x, y });
|
||||
let diagram = approx.diagrams.get_mut(&id).unwrap();
|
||||
let mut node = diagram.nodes.remove(&generated).unwrap();
|
||||
node.id = format!("f0440000-0000-4000-8000-{:012}", ordinal + 2).parse()?;
|
||||
diagram.nodes.insert(node.id, node);
|
||||
}
|
||||
probe(&approx, &approx.diagrams[&id], samples);
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"source": "24b1eab07d306d8cb091bb46f7daf9f027a8f1c0",
|
||||
"core_profile": "dev unoptimized",
|
||||
"driver_optimization": "rustc -O",
|
||||
"samples_per_phase": 40,
|
||||
"warmups_per_phase": 3,
|
||||
"rlib_sha256": "E10C81BF28A33CD0FB6C4C26884CFFA480EF05328E78BCDB138DD4B635B2531C",
|
||||
"fixture_sha256": "EF0EF4006C3E09D5DB6E1B621256B3F7D6642F3A7B09CC34607CFBCCA830C727",
|
||||
"driver_exe_sha256": "4C66E9CDE4F08D6DFD2A0DC3DBF1A80B97E340F3F22CA001A76301F06F47C2E2",
|
||||
"native_fps_measured": false
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
CPU-only probe; samples=40; fixture=.local/drag-out-01a0d6fd/examples/release1/model.json; elements=94 relations=62
|
||||
|
||||
view=1 · OA responsibility and repair traffic projection=Allocation nodes=6 ports=0 edges=3
|
||||
index_new: n=40 p50_ms=1.0106 p95_ms=2.0583 max_ms=2.0910
|
||||
projection_reused_index: n=40 p50_ms=0.5702 p95_ms=1.2320 max_ms=1.3490
|
||||
projection_fresh_index: n=40 p50_ms=1.5505 p95_ms=3.6681 max_ms=5.1533
|
||||
routing_settled: n=40 p50_ms=0.1944 p95_ms=0.3391 max_ms=0.4246
|
||||
moving_root=3191e05c-1c7f-5f0e-beb0-5f3bded54c48 element=Control room
|
||||
moved_projection: n=40 p50_ms=0.4848 p95_ms=1.2745 max_ms=1.5797
|
||||
moved_routing: n=40 p50_ms=0.1994 p95_ms=0.7971 max_ms=1.1414
|
||||
moved_prepare_projection_routing: n=40 p50_ms=0.9250 p95_ms=2.6847 max_ms=10.4908
|
||||
|
||||
view=5 · SA pressure supervision projection=StateMachine { machine: 132b3f28-3f88-5327-9868-8c8b645ed412 } nodes=5 ports=0 edges=3
|
||||
index_new: n=40 p50_ms=0.9602 p95_ms=2.1394 max_ms=2.4512
|
||||
projection_reused_index: n=40 p50_ms=0.1697 p95_ms=0.7629 max_ms=1.1780
|
||||
projection_fresh_index: n=40 p50_ms=1.1189 p95_ms=2.6324 max_ms=3.3912
|
||||
routing_settled: n=40 p50_ms=0.7063 p95_ms=1.0812 max_ms=1.1149
|
||||
moving_root=a676fbb9-0833-59a8-98cf-a10d8f4b7434 element=Pressure supervision
|
||||
moved_projection: n=40 p50_ms=0.1565 p95_ms=0.3445 max_ms=0.3790
|
||||
moved_routing: n=40 p50_ms=0.6113 p95_ms=1.3199 max_ms=1.3733
|
||||
moved_prepare_projection_routing: n=40 p50_ms=0.8259 p95_ms=1.7640 max_ms=2.1752
|
||||
|
||||
view=2 · SA service boundary and functions projection=Allocation nodes=6 ports=6 edges=3
|
||||
index_new: n=40 p50_ms=0.7820 p95_ms=3.4180 max_ms=6.8439
|
||||
projection_reused_index: n=40 p50_ms=0.7938 p95_ms=1.9946 max_ms=2.1411
|
||||
projection_fresh_index: n=40 p50_ms=2.0597 p95_ms=3.4554 max_ms=3.6616
|
||||
routing_settled: n=40 p50_ms=0.1478 p95_ms=0.7886 max_ms=1.0081
|
||||
moving_root=8345c76a-8d85-5c31-902e-ec1cd33ed4a3 element=Pressure coordination service
|
||||
moved_projection: n=40 p50_ms=0.6914 p95_ms=1.5286 max_ms=1.8658
|
||||
moved_routing: n=40 p50_ms=0.1862 p95_ms=0.5658 max_ms=2.8924
|
||||
moved_prepare_projection_routing: n=40 p50_ms=1.1724 p95_ms=3.1806 max_ms=4.2620
|
||||
|
||||
view=4 · SA mission and included capability projection=Capabilities nodes=4 ports=1 edges=3
|
||||
index_new: n=40 p50_ms=0.6879 p95_ms=1.3582 max_ms=1.5266
|
||||
projection_reused_index: n=40 p50_ms=0.1562 p95_ms=0.6767 max_ms=1.0102
|
||||
projection_fresh_index: n=40 p50_ms=1.2929 p95_ms=2.3543 max_ms=4.0762
|
||||
routing_settled: n=40 p50_ms=0.2553 p95_ms=1.4389 max_ms=1.6677
|
||||
moving_root=069a3fb3-077c-59d8-91da-27b0665143c7 element=Assess an alarm
|
||||
moved_projection: n=40 p50_ms=0.1243 p95_ms=0.1928 max_ms=0.2212
|
||||
moved_routing: n=40 p50_ms=0.2271 p95_ms=0.6733 max_ms=1.2408
|
||||
moved_prepare_projection_routing: n=40 p50_ms=0.5542 p95_ms=1.3344 max_ms=1.8957
|
||||
|
||||
view=3 · SA service conversation only projection=Allocation nodes=6 ports=6 edges=1
|
||||
index_new: n=40 p50_ms=0.9618 p95_ms=1.6890 max_ms=2.0995
|
||||
projection_reused_index: n=40 p50_ms=0.6661 p95_ms=2.3388 max_ms=2.6429
|
||||
projection_fresh_index: n=40 p50_ms=2.3913 p95_ms=4.1941 max_ms=4.8120
|
||||
routing_settled: n=40 p50_ms=0.0660 p95_ms=0.2156 max_ms=0.6289
|
||||
moving_root=40210589-69f7-5209-b329-10bb83cf615c element=Field technician
|
||||
moved_projection: n=40 p50_ms=0.5527 p95_ms=1.1239 max_ms=1.1362
|
||||
moved_routing: n=40 p50_ms=0.0495 p95_ms=0.1771 max_ms=0.2209
|
||||
moved_prepare_projection_routing: n=40 p50_ms=0.7963 p95_ms=4.1835 max_ms=6.7551
|
||||
|
||||
view=APPROXIMATION eight-card SA Overview projection=Overview nodes=8 ports=6 edges=13
|
||||
index_new: n=40 p50_ms=0.7487 p95_ms=1.9597 max_ms=2.2005
|
||||
projection_reused_index: n=40 p50_ms=0.3885 p95_ms=0.7550 max_ms=1.2965
|
||||
projection_fresh_index: n=40 p50_ms=1.7135 p95_ms=2.7022 max_ms=4.2204
|
||||
routing_settled: n=40 p50_ms=2.4525 p95_ms=4.4617 max_ms=4.7735
|
||||
moving_root=f0440000-0000-4000-8000-000000000002 element=Assess an alarm procedure
|
||||
moved_projection: n=40 p50_ms=0.4691 p95_ms=0.8354 max_ms=1.0408
|
||||
moved_routing: n=40 p50_ms=3.1907 p95_ms=4.4781 max_ms=4.5672
|
||||
moved_prepare_projection_routing: n=40 p50_ms=4.2640 p95_ms=6.8259 max_ms=8.8052
|
||||
@@ -1 +0,0 @@
|
||||
*.log -text
|
||||
@@ -1,74 +0,0 @@
|
||||
# Outgoing allocation drag evidence
|
||||
|
||||
Contribution source: `1a669130fb6d2b65279aab3847e966a1a282c191`, based on
|
||||
published preview `715036e132677dd2bc2fb37ed316d93dc9987aec`.
|
||||
This is branch-specific Windows evidence for [issue 40](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/40).
|
||||
It is not acceptance of an integrated release or the complete application.
|
||||
The [decision and native baseline](../../drag-out-20260925.md) explain the repair.
|
||||
|
||||
## Environment and commands
|
||||
|
||||
Windows 10.0.26200, Rust/Cargo 1.98.1, host/target
|
||||
`x86_64-pc-windows-gnullvm`, LLVM 22.1.8, LLVM-MinGW 20260908 UCRT linker
|
||||
`clang.exe`, `CARGO_BUILD_JOBS=1`, `CARGO_INCREMENTAL=0`, default development
|
||||
profile. Run at the identified source with the Windows GNU LLVM toolchain and
|
||||
its linker/runtime available on PATH. A sparse checkout must include `build`
|
||||
and `harness/fixtures` as well as crates. The actual commands were:
|
||||
|
||||
```powershell
|
||||
cargo test --locked --offline -p oa-desktop allocation_drag -- --test-threads=1
|
||||
cargo clippy --locked --offline -p oa-desktop --all-targets -- -D warnings
|
||||
cargo build --locked --offline -p oa-desktop --bin arcadia-studio
|
||||
```
|
||||
|
||||
Offline commands require dependencies already cached. A fresh environment must
|
||||
fetch the locked dependencies first. Raw logs retain original absolute paths;
|
||||
these paths identify this run, not required directories on another machine.
|
||||
|
||||
## Results and boundaries
|
||||
|
||||
- Test-only successor `24b1eab07d306d8cb091bb46f7daf9f027a8f1c0` adds two
|
||||
OA/SA App regressions: a clearance proposal blocked by unrelated work and an
|
||||
outgoing move with a retained sibling enlarging the source enclosure.
|
||||
`tests-04.log` passes all 123 allocation-drag tests (zero failed/ignored,
|
||||
1,424 filtered) in 54.86s; `clippy-02.log` passes the same strict command in
|
||||
1m27s. Production inputs are unchanged from `1a669130`; its normal binary
|
||||
remains the native candidate. [Independent review](independent-review.md)
|
||||
covers the source, new test design and evidence limits.
|
||||
- `tests-03.log`: 121 passed, zero failed/ignored, 1,424 filtered; 35.33 seconds
|
||||
test execution. This is the allocation-drag subset, not the full desktop suite.
|
||||
- `clippy-01.log`: strict desktop all-target Clippy passed in 4m30s.
|
||||
- `build-01.log`: normal GUI build passed in 5m16s. The resulting local executable
|
||||
SHA256 is `9bda1a6a1d24fdc98c7a8822400c12fea9afe1de828a82ba9273f03b99e47c07`.
|
||||
It was staged with the published preview's `libunwind.dll` and started, but
|
||||
Computer Use was stopped before any changed-binary native observation.
|
||||
- `context.json`: recorded source/toolchain, passing test-log and baseline-image
|
||||
hashes, and clean source after the test run.
|
||||
- `tests-01.log`: compilation failed before tests because `build/windows_manifest.rs`
|
||||
was excluded from the initial sparse checkout.
|
||||
- `tests-02.log`: compilation failed before tests because harness fixture files
|
||||
were excluded and a standalone test helper used `Self` instead of `Fixture`.
|
||||
The compiler was terminated after reporting errors; its interrupted exit is
|
||||
preserved. The missing tracked files and typo were repaired before run 03.
|
||||
|
||||
The tests exercise source-clearance proposals, OA/SA App event sequences,
|
||||
preview/release agreement, exact source/history, cancellation, and retained
|
||||
preview without commit authority on refused release. Existing collision and
|
||||
semantic checks still govern all proposals. Independent source review found the
|
||||
whole-header viewport restriction and obsolete preview assertion; both were
|
||||
corrected before the passing run. This is source/test review, not native review.
|
||||
|
||||
`baseline-left-refusal.png` is an unmodified actual native capture from the
|
||||
published preview executable, SHA256
|
||||
`2c03bd6cc3f1110c219e4f57ab94874a121590f83779239a93289b7170664399`.
|
||||
In the copied Allocation companion fixture, OA assign view at 1440x900 content
|
||||
and Fit 72%, dragging X from window (486,546) to (365,546) leaves allocation and
|
||||
placement unchanged and reports overlap. A control drag to (625,572) removes
|
||||
allocation, and Undo restores it. Intermediate jitter was diagnosed from source;
|
||||
this image is end-state evidence only.
|
||||
|
||||
Changed-binary native acceptance is still required: repeat the short fitted-view
|
||||
drag, identify and regrab the partially clipped card, check refused-motion
|
||||
feedback, Cancel and Undo/Redo, save the full bundle, close and reopen in a fresh
|
||||
process, and verify identity/allocation/placement and unchanged sibling data for
|
||||
OA and SA. Linux/WSL remains deferred by the user. No published package changed.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 129 KiB |
@@ -1,5 +0,0 @@
|
||||
Compiling iced_widget v0.14.2 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\vendor\iced_widget)
|
||||
Compiling iced v0.14.0
|
||||
Compiling oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-core)
|
||||
Compiling oa-desktop v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop)
|
||||
Finished `dev` profile [unoptimized] target(s) in 5m 16s
|
||||
@@ -1,6 +0,0 @@
|
||||
Compiling oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-core)
|
||||
Checking iced_widget v0.14.2 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\vendor\iced_widget)
|
||||
Compiling oa-server v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-server)
|
||||
Compiling oa-desktop v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop)
|
||||
Checking iced v0.14.0
|
||||
Finished `dev` profile [unoptimized] target(s) in 4m 30s
|
||||
@@ -1,2 +0,0 @@
|
||||
Checking oa-desktop v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop)
|
||||
Finished `dev` profile [unoptimized] target(s) in 1m 27s
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"source": "1a669130fb6d2b65279aab3847e966a1a282c191",
|
||||
"platform": "Microsoft Windows 10.0.26200",
|
||||
"compiler": [
|
||||
"rustc 1.98.1 (48a229cea 2026-09-01)",
|
||||
"binary: rustc",
|
||||
"commit-hash: 48a229ceaefd4985c50990b14116b6d856af0985",
|
||||
"commit-date: 2026-09-01",
|
||||
"host: x86_64-pc-windows-gnullvm",
|
||||
"release: 1.98.1",
|
||||
"LLVM version: 22.1.8"
|
||||
],
|
||||
"cargo": "cargo 1.98.1 (797e8a9bc 2026-08-05)",
|
||||
"test_log_sha256": "8EB57F522FA0DCCA327DC13C67A9C1B14F5FAB09C5599C108C0BA6D875C78886",
|
||||
"baseline_image_sha256": "AAF162619582018D1197D255B4BA1122747AA22703D8DEDFC7FCEFCB42AEFE38",
|
||||
"target": "x86_64-pc-windows-gnullvm",
|
||||
"incremental": "0",
|
||||
"jobs": "1",
|
||||
"working_tree_clean_after_test": true
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
# Independent source and evidence review
|
||||
|
||||
Fresh read-only GPT-6 Astra review, 2026-09-25. Production source
|
||||
`1a669130fb6d2b65279aab3847e966a1a282c191`; test-only successor
|
||||
`24b1eab07d306d8cb091bb46f7daf9f027a8f1c0`. No GUI actions or test execution
|
||||
were performed by this reviewer.
|
||||
|
||||
No material correctness finding in the bounded scope:
|
||||
|
||||
- The outgoing collision regression in `app/allocation_drag_tests.rs` proves a
|
||||
real source-boundary crossing and unobscured OutsidePerformers target, a
|
||||
nonempty clearance proposal, and intersection with unrelated work. Ordinary
|
||||
placement rejects that proposal. Release preserves project, source bundle,
|
||||
revision, snapshot identity and redo availability.
|
||||
- The retained-sibling regression first requires exact requested placement to
|
||||
fail. The admitted correction clears the enlarged source enclosure while
|
||||
preserving its projection, sibling allocation/placement and all other stored
|
||||
placements. Preview/release and source Undo/Redo comparisons are exact.
|
||||
- In `app/allocation_drag.rs`, clearance remains downstream of semantic
|
||||
admission and retries ordinary placement. Release recomputes placement and
|
||||
passes through `finish` and document execution. No collision, stale-state or
|
||||
retained-preview commit bypass was found.
|
||||
- The committed passing log's bytes and SHA256 match `context.json`; the
|
||||
baseline image hash also matches. Logs support 121 passing tests, strict
|
||||
Clippy and normal development build for the production source. They do not
|
||||
establish execution of the two successor tests; consult the linked raw logs
|
||||
and README for subsequent execution evidence.
|
||||
|
||||
The review supports the source policy and test design, not native usability.
|
||||
The 24x24 visible-header threshold alone does not prove readable identity or
|
||||
practical regrabbing. Changed-binary fitted-view dragging, feedback, recovery
|
||||
and Save/reopen remain unverified. This review is not the broad final
|
||||
requirements/domain/UX/release review required by `PROJECT_GOAL.md`.
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"source": "24b1eab07d306d8cb091bb46f7daf9f027a8f1c0",
|
||||
"production_source": "1a669130fb6d2b65279aab3847e966a1a282c191",
|
||||
"test_log": "tests-04.log",
|
||||
"test_log_sha256": "C98E0F70D60788B484146B3C8785891888BA696130ACC4BFD7D30DA570E6B1E1",
|
||||
"passed": 123,
|
||||
"failed": 0,
|
||||
"ignored": 0,
|
||||
"filtered": 1424,
|
||||
"native_candidate_sha256": "9BDA1A6A1D24FDC98C7A8822400C12FEA9AFE1DE828A82BA9273F03B99E47C07",
|
||||
"native_acceptance": "unverified"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
Compiling oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-core)
|
||||
error: couldn't read `crates\oa-core\../../build/windows_manifest.rs`: The system cannot find the path specified. (os error 3)
|
||||
--> crates\oa-core\build.rs:1:1
|
||||
|
|
||||
1 | include!("../../build/windows_manifest.rs");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: could not compile `oa-core` (build script) due to 1 previous error
|
||||
@@ -1,68 +0,0 @@
|
||||
Compiling oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-core)
|
||||
Compiling oa-server v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-server)
|
||||
Compiling iced_widget v0.14.2 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\vendor\iced_widget)
|
||||
Compiling oa-desktop v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop)
|
||||
Compiling iced v0.14.0
|
||||
error: couldn't read `C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop/../../harness/fixtures/interface-operation-probe/output/boundary-only.json`: The system cannot find the path specified. (os error 3)
|
||||
--> crates\oa-desktop\src\app\reference_authoring\tests\mounted.rs:755:37
|
||||
|
|
||||
755 | let mut p = persistence::decode(include_bytes!(concat!(
|
||||
| _____________________________________^
|
||||
756 | | env!("CARGO_MANIFEST_DIR"),
|
||||
757 | | "/../../harness/fixtures/interface-operation-probe/output/boundary-only.json"
|
||||
758 | | )))
|
||||
| |______^
|
||||
|
||||
error: couldn't read `C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop/../../harness/fixtures/interface-operation-probe/output/boundary-only.json`: The system cannot find the path specified. (os error 3)
|
||||
--> crates\oa-desktop\src\behavior\scenario\usage\tests.rs:235:37
|
||||
|
|
||||
235 | let mut p = persistence::decode(include_bytes!(concat!(
|
||||
| _____________________________________^
|
||||
236 | | env!("CARGO_MANIFEST_DIR"),
|
||||
237 | | "/../../harness/fixtures/interface-operation-probe/output/boundary-only.json"
|
||||
238 | | )))
|
||||
| |______^
|
||||
|
||||
error: couldn't read `C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop/../../harness/fixtures/interface-operation-probe/output/boundary-only.json`: The system cannot find the path specified. (os error 3)
|
||||
--> crates\oa-desktop\src\behavior\scenario_operation_tests.rs:6:25
|
||||
|
|
||||
6 | persistence::decode(include_bytes!(concat!(
|
||||
| _________________________^
|
||||
7 | | env!("CARGO_MANIFEST_DIR"),
|
||||
8 | | "/../../harness/fixtures/interface-operation-probe/output/boundary-only.json"
|
||||
9 | | )))
|
||||
| |______^
|
||||
|
||||
error: couldn't read `C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop/../../harness/fixtures/source7-native/base/expected-baseline.json`: The system cannot find the path specified. (os error 3)
|
||||
--> crates\oa-desktop\src\behavior\topology\contextual_routing.rs:61:29
|
||||
|
|
||||
61 | persistence::decode(include_bytes!(concat!(
|
||||
| _____________________________^
|
||||
62 | | env!("CARGO_MANIFEST_DIR"),
|
||||
63 | | "/../../harness/fixtures/source7-native/base/expected-baseline.json"
|
||||
64 | | )))
|
||||
| |__________^
|
||||
|
||||
error: couldn't read `C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop/../../harness/fixtures/interface-operation-probe/output/boundary-only.json`: The system cannot find the path specified. (os error 3)
|
||||
--> crates\oa-desktop\src\semantic_review\source7_tests.rs:5:25
|
||||
|
|
||||
5 | persistence::decode(include_bytes!(concat!(
|
||||
| _________________________^
|
||||
6 | | env!("CARGO_MANIFEST_DIR"),
|
||||
7 | | "/../../harness/fixtures/interface-operation-probe/output/boundary-only.json"
|
||||
8 | | )))
|
||||
| |______^
|
||||
|
||||
error[E0411]: cannot find struct, variant or union type `Self` in this scope
|
||||
--> crates\oa-desktop\src\app\allocation_drag\clearance.rs:314:9
|
||||
|
|
||||
287 | fn fixture(layer: Layer) -> Fixture {
|
||||
| ------- `Self` not allowed in a function
|
||||
...
|
||||
314 | Self {
|
||||
| ^^^^ `Self` is only available in impls, traits, and type definitions
|
||||
|
||||
error: could not compile `oa-desktop` (bin "arcadia-studio" test) due to 6 previous errors
|
||||
|
||||
Caused by:
|
||||
process didn't exit successfully: `C:\Users\User\Documents\Git\ARCADIA-Studio\.local\toolchain\rustup\toolchains\stable-x86_64-pc-windows-gnullvm\bin\rustc.exe --crate-name arcadia_studio --edition=2024 crates\oa-desktop\src\main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --emit=dep-info,link -C embed-bitcode=no --test --check-cfg cfg(docsrs,test) --check-cfg "cfg(feature, values())" -C metadata=5e2096130f19ead2 -C extra-filename=-c5b42126ba36cd38 --out-dir C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps -C linker=clang.exe -C strip=debuginfo -L dependency=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps --extern axum=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libaxum-ccc7aea466db9258.rlib --extern iced=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libiced-594f7d417d69ed72.rlib --extern iced_runtime=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libiced_runtime-4d31a36fe5cef0b0.rlib --extern oa_core=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\liboa_core-2f3c5174cb6398fd.rlib --extern oa_server=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\liboa_server-bb42169ca297f969.rlib --extern reqwest=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libreqwest-31ac987472fa8038.rlib --extern rfd=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\librfd-17cc7ba2db223d7b.rlib --extern serde=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libserde-60a32311146a42e4.rlib --extern serde_json=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libserde_json-da2c4f333fc47818.rlib --extern tempfile=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libtempfile-86aac28d6be16d2f.rlib --extern tokio=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libtokio-5e0ca96735e3073a.rlib --extern unicode_segmentation=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\libunicode_segmentation-85698043f7780858.rlib -L native=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\build\ring-5f8d2d20440f09b4\out -L native=C:\Users\User\Documents\Git\ARCADIA-Studio\.local\toolchain\cargo\registry\src\index.crates.io-1949cf8c6b5b557f\windows_x86_64_gnullvm-0.52.6\lib -C link-arg=C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\build\oa-desktop-307d320bbc13ccd5\out\normal-user-manifest.o` (exit code: 0xffffffff)
|
||||
@@ -1,130 +0,0 @@
|
||||
Blocking waiting for file lock on build directory
|
||||
Compiling oa-desktop v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop)
|
||||
Finished `test` profile [unoptimized] target(s) in 8m 13s
|
||||
Running unittests src\main.rs (C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\arcadia_studio-c5b42126ba36cd38.exe)
|
||||
|
||||
running 121 tests
|
||||
test allocation_drag::outgoing_header_retains_a_grab_region_without_requiring_full_camera_containment ... ok
|
||||
test allocation_drag::tests::allocation_artifact_and_manual_trace_cascades_are_named_and_refused ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_detects_hidden_moved_child_and_stationary_enclosure_growth ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_distributed_oa_sa_exact_scope_routes_source_history_and_anchor ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_noop_stale_tamper_target_and_all_selected_headers ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_performer_closure_does_not_acquire_incidental_semantic_root ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_preserves_existing_overlap_but_refuses_its_growth ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_preserves_roles_and_does_not_invent_unplaced_descendants ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_preserves_unrelated_folded_interior_diagnostic_boundary ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_simultaneous_roots_may_enter_each_others_vacated_bounds ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_validates_all_original_members_before_normalizing ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_checks_original_identity_and_visibility_before_normalization ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_distributed_parent_refuses_but_its_independent_leaves_can_reassign ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_finish_rejects_stale_project_and_each_tampered_result ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_normalizes_parent_child_and_assigns_unplaced_leaf_once ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_requires_non_anchor_selected_header_inside_viewport ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_unresolved_oa_role_leaf_accepts_explicit_target_but_not_outside ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_accumulates_stable_ids_and_aliases_without_partial_reuse ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_collateral_surviving_constraint_refuses_whole_semantic_candidate ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_deletes_only_own_routes_across_views_and_keeps_internal_flow ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_independent_performers_preserves_already_correct_provenance ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_source_failure_preserves_existing_history_and_retry_ids ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_unfolds_only_changed_destination_and_refuses_newly_exposed_overlap ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_uses_vacated_space_and_one_complete_route_owner_map ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_zero_delta_changes_semantics_once_and_then_is_noop ... ok
|
||||
test allocation_drag::tests::cache_plan_uses_candidate_index_and_same_pixel_different_target_changes_preview ... ok
|
||||
test allocation_drag::tests::collapsed_target_unfold_is_explicit_and_no_other_fold_changes ... ok
|
||||
test allocation_drag::tests::direct_exit_revealing_another_role_performer_has_truthful_refusal ... ok
|
||||
test allocation_drag::tests::explicit_different_performer_retains_advisory_role_warning ... ok
|
||||
test allocation_drag::tests::folded_subtree_cannot_hide_new_collision ... ok
|
||||
test allocation_drag::tests::geometry_refuses_new_overlap_bounds_and_invisible_headers_and_preserves_existing_overlap ... ok
|
||||
test allocation_drag::tests::group_arrange_experiment::mixed_arrange_experiment_detects_moved_folded_child_collision ... ok
|
||||
test allocation_drag::tests::group_arrange_experiment::mixed_arrange_experiment_detects_stationary_enclosure_growth_collision ... ok
|
||||
test allocation_drag::tests::group_arrange_experiment::mixed_arrange_experiment_distributed_root_and_performer_can_translate_rigidly ... ok
|
||||
test allocation_drag::tests::group_arrange_experiment::mixed_arrange_experiment_unrelated_folded_interiors_are_outside_diagnostic_domain ... ok
|
||||
test allocation_drag::tests::malformed_scope_wrong_projection_duplicate_placement_and_stable_id_collision_refuse ... ok
|
||||
test allocation_drag::tests::mixed_p_x_y_refuses_semantic_and_arrange_instead_of_stretching_destination ... ok
|
||||
test allocation_drag::tests::oa_communication_incompleteness_remains_advisory_without_collateral_loss ... ok
|
||||
test allocation_drag::tests::oa_sa_incoming_between_outgoing_preserve_identity_source_history_and_other_views ... ok
|
||||
test allocation_drag::tests::oa_sa_one_leaf_move_refuses_when_ancestor_regrouping_introduces_unrelated_overlap ... ok
|
||||
test allocation_drag::tests::oa_sa_one_leaf_reassignment_and_outward_move_regroup_ancestors_without_moving_sibling ... ok
|
||||
test allocation_drag::tests::oa_sa_populated_collapsed_target_accepts_room_and_refuses_collision_without_relocating_contents ... ok
|
||||
test allocation_drag::tests::oa_sa_state_owned_action_and_availability_reject_reassignment_atomically ... ok
|
||||
test allocation_drag::tests::oa_sa_unfolding_prior_hidden_overlap_refuses_even_when_insertion_does_not_collide ... ok
|
||||
test allocation_drag::tests::own_deleted_allocation_routes_may_disappear_in_every_diagram_only ... ok
|
||||
test allocation_drag::tests::role_only_same_effective_performer_is_semantic_noop_and_outgoing_refuses ... ok
|
||||
test allocation_drag::tests::sa_port_and_deferred_exchange_allocation_cascade_refuses_and_retarget_is_invalid ... ok
|
||||
test allocation_drag::tests::same_performer_readability_preserves_snapped_noop_and_allocation_identity ... ok
|
||||
test allocation_drag::tests::scope_detects_first_child_allocation_and_role_transfer_and_finish_rejects_live_edits ... ok
|
||||
test allocation_drag::tests::selected_header_visibility_allows_viewport_edge_but_refuses_clipping ... ok
|
||||
test allocation_drag::tests::snapped_noop_returns_no_command_and_keeps_source_revision_and_redo ... ok
|
||||
test allocation_drag::tests::source_budget_refusal_keeps_project_bundle_history_and_retry_identity_exact ... ok
|
||||
test allocation_drag::tests::surviving_constraint_mutation_is_refused_even_when_core_candidate_is_valid ... ok
|
||||
test allocation_drag::tests::target_presentation_requires_accepted_identity_and_selected_header_visibility ... ok
|
||||
test allocation_drag::tests::toolbar_identity_allows_exact_incoming_placement_at_old_label_overlap ... ok
|
||||
test allocation_drag::tests::uniform_folded_grandchild_and_unplaced_scope_moves_exactly_q_and_all_l_oa_sa ... ok
|
||||
test allocation_drag::tests::uniform_role_only_and_mixed_direct_role_composites_same_target_do_not_allocate ... ok
|
||||
test allocation_drag::tests::uniformly_unassigned_composite_creates_only_stable_leaf_allocations_including_unplaced ... ok
|
||||
test allocation_drag::tests::unrequested_view_option_cleanup_is_not_whitelisted ... ok
|
||||
test allocation_drag::tests::unresolved_role_leaf_can_arrange_or_accept_explicit_target_without_guessing ... ok
|
||||
test app::allocation_drag::clearance::tests::corner_order_follows_boundary_crossing_and_is_deterministic ... ok
|
||||
test app::allocation_drag::clearance::tests::descendant_footprint_controls_clearance_without_mutating_projects ... ok
|
||||
test app::allocation_drag::clearance::tests::each_outgoing_edge_clears_the_source_and_passes_ordinary_placement ... ok
|
||||
test app::allocation_drag::clearance::tests::independent_selected_roots_keep_one_rigid_group_translation ... ok
|
||||
test app::allocation_drag::clearance::tests::no_crossing_no_overlap_no_source_and_nonfinite_requests_are_empty ... ok
|
||||
test app::allocation_drag::clearance::tests::source_shrink_uses_candidate_enclosure_not_frozen_target ... ok
|
||||
test app::allocation_drag::tests::actual_canvas_origin_change_cancels_held_work_before_any_legacy_release ... ok
|
||||
test app::allocation_drag::tests::arrange_is_one_gesture_and_snapped_noop_preserves_redo_and_source ... ok
|
||||
test app::allocation_drag::tests::candidate_semantics_are_cached_per_destination_with_stable_ids_and_own_index ... ok
|
||||
test app::allocation_drag::tests::destination_identity_does_not_describe_blocked_or_outside_viewport_as_unallocation ... ok
|
||||
test app::allocation_drag::tests::frozen_collapsed_target_uses_only_visible_header_and_port_edge_controls_occlude ... ok
|
||||
test app::allocation_drag::tests::frozen_targets_use_half_open_semantic_priority_and_refuse_incomparable_overlap ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_app_tree_dirty_description_retains_focus_and_middle_caret_for_next_key ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_app_tree_dirty_name_retains_focus_and_middle_caret_for_next_key ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_app_tree_exact_incoming_drag_keeps_destination_visible_and_canvas_stable ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_keyboard_arrange_shortcut_consumes_once_escape_cancels_and_dirty_owner_refuses ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_rendered_canvas_pixels_do_not_change_when_toolbar_feedback_text_changes ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_toolbar_hover_inspects_last_full_name_without_authorizing_an_outside_drop ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_tree_outgoing_boundary_motion_preview_release_and_cancel ... ok
|
||||
test app::allocation_drag::tests::full_tree::control_focus::dirty_selected_pin_outer_ring_keeps_real_name_focus_and_caret ... ok
|
||||
test app::allocation_drag::tests::group::allocation_bare_moves_cannot_bypass_armed_active_or_retired_lifetime ... ok
|
||||
test app::allocation_drag::tests::group::completed_text_apply_rejects_old_allocation_packets_without_retiring_a_new_drag ... ok
|
||||
test app::allocation_drag::tests::group::connection_lifetime::captured_connection_after_cancel_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::connection_lifetime::captured_connection_context_mismatches_preserve_the_current_session ... ok
|
||||
test app::allocation_drag::tests::group::connection_lifetime::captured_connection_current_restart_and_pair_commit_after_tool_boundary ... ok
|
||||
test app::allocation_drag::tests::group::group_arrange_work_and_performer_anchors_preserve_every_responsibility ... ok
|
||||
test app::allocation_drag::tests::group::group_assignment_split_rebuild_preserves_primary_and_commits_one_complete_candidate ... ok
|
||||
test app::allocation_drag::tests::group::group_out_and_back_assigns_at_zero_delta_then_true_noop_preserves_redo ... ok
|
||||
test app::allocation_drag::tests::group::group_selection_aba_and_old_press_cannot_retire_a_new_token ... ok
|
||||
test app::allocation_drag::tests::group::group_source_refusal_retains_primary_source_and_both_history_paths ... ok
|
||||
test app::allocation_drag::tests::group::idle_group_press_rejects_selection_generation_aba_with_unchanged_other_stamps ... ok
|
||||
test app::allocation_drag::tests::group::ordinary_off_grid_performer_out_and_back_is_noop_with_redo ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::captured_route_context_fields_independently_reject_before_retirement ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::current_route_commits_without_session_preserve_exact_route_history ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::same_context_route_attachment_after_selection_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::same_context_route_commit_after_selection_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::stale_route_attachment_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::stale_route_commit_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::unsupported_group_click_collapses_but_threshold_crossing_never_becomes_click ... ok
|
||||
test app::allocation_drag::tests::modal_roundtrip_equal_fit_undo_resize_and_focus_retire_press_before_replay ... ok
|
||||
test app::allocation_drag::tests::mounted_clean_stationary_selects_exact_work_without_revision_or_legacy_apply ... ok
|
||||
test app::allocation_drag::tests::mounted_dirty_port_press_cannot_fall_through_to_applying_port_selection ... ok
|
||||
test app::allocation_drag::tests::mounted_dirty_property_press_does_not_select_apply_or_destroy_draft ... ok
|
||||
test app::allocation_drag::tests::mounted_oa_sa_ordered_incoming_between_outgoing_are_exact_single_history_steps ... ok
|
||||
test app::allocation_drag::tests::mounted_role_only_outgoing_refusal_retains_placement_and_same_performer_creates_no_allocation ... ok
|
||||
test app::allocation_drag::tests::mounted_uniform_parent_moves_hidden_placements_and_assigns_only_leaves ... ok
|
||||
test app::allocation_drag::tests::navigation_union::old_chooser_envelopes_preserve_a_current_canvas_gesture ... ok
|
||||
test app::allocation_drag::tests::navigation_union::stale_gesture_packets_preserve_navigation_and_a_new_live_cancel_still_works ... ok
|
||||
test app::allocation_drag::tests::oa_sa_clipped_selected_header_refuses_preview_release_and_retries_without_partial_source_or_history ... ok
|
||||
test app::allocation_drag::tests::oa_sa_toolbar_identity_accepts_exact_receiver_and_collapsed_header_drag ... ok
|
||||
test app::allocation_drag::tests::outgoing_boundary_drop_clears_source_without_changing_other_placements ... ok
|
||||
test app::allocation_drag::tests::outside_release_is_cancel_and_does_not_remove_an_assignment ... ok
|
||||
test app::allocation_drag::tests::pending_behavior_draft_refuses_actual_work_press_and_equal_document_replacement_retires_packet ... ok
|
||||
test app::allocation_drag::tests::refused_motion_retains_last_scene_but_release_never_commits_it ... ok
|
||||
test app::allocation_drag::tests::release_uses_ordered_native_position_before_later_motion_in_same_batch ... ok
|
||||
test app::allocation_drag::tests::same_snapped_position_on_opposite_shared_border_rebuilds_semantics_even_if_layout_refuses ... ok
|
||||
test app::allocation_drag::tests::source_and_modal_admission_reject_prebuilt_clean_press_without_selecting ... ok
|
||||
test app::allocation_drag::tests::source_refusal_is_atomic_and_a_new_gesture_can_retry_against_live_revision ... ok
|
||||
test app::allocation_drag::tests::stale_packets_do_not_cancel_a_newer_token_and_each_release_is_consumed_once ... ok
|
||||
test app::allocation_drag::tests::toolbar_destination_names_transformed_target_whose_header_is_clipped ... ok
|
||||
test app::allocation_drag::tests::toolbar_status_leaves_transformed_top_edge_work_header_readable ... ok
|
||||
|
||||
test result: ok. 121 passed; 0 failed; 0 ignored; 0 measured; 1424 filtered out; finished in 35.33s
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
Compiling oa-desktop v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\.local\drag-out-01a0d6fd\crates\oa-desktop)
|
||||
Finished `test` profile [unoptimized] target(s) in 6m 05s
|
||||
Running unittests src\main.rs (C:/Users/User/Documents/Git/ARCADIA-Studio/target\debug\deps\arcadia_studio-c5b42126ba36cd38.exe)
|
||||
|
||||
running 123 tests
|
||||
test allocation_drag::outgoing_header_retains_a_grab_region_without_requiring_full_camera_containment ... ok
|
||||
test allocation_drag::tests::allocation_artifact_and_manual_trace_cascades_are_named_and_refused ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_detects_hidden_moved_child_and_stationary_enclosure_growth ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_distributed_oa_sa_exact_scope_routes_source_history_and_anchor ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_noop_stale_tamper_target_and_all_selected_headers ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_performer_closure_does_not_acquire_incidental_semantic_root ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_preserves_existing_overlap_but_refuses_its_growth ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_preserves_roles_and_does_not_invent_unplaced_descendants ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_preserves_unrelated_folded_interior_diagnostic_boundary ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_simultaneous_roots_may_enter_each_others_vacated_bounds ... ok
|
||||
test allocation_drag::tests::arrange_tests::explicit_arrange_validates_all_original_members_before_normalizing ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_checks_original_identity_and_visibility_before_normalization ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_distributed_parent_refuses_but_its_independent_leaves_can_reassign ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_finish_rejects_stale_project_and_each_tampered_result ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_normalizes_parent_child_and_assigns_unplaced_leaf_once ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_requires_non_anchor_selected_header_inside_viewport ... ok
|
||||
test allocation_drag::tests::assignment_boundary_tests::group_assignment_unresolved_oa_role_leaf_accepts_explicit_target_but_not_outside ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_accumulates_stable_ids_and_aliases_without_partial_reuse ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_collateral_surviving_constraint_refuses_whole_semantic_candidate ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_deletes_only_own_routes_across_views_and_keeps_internal_flow ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_independent_performers_preserves_already_correct_provenance ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_source_failure_preserves_existing_history_and_retry_ids ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_unfolds_only_changed_destination_and_refuses_newly_exposed_overlap ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_uses_vacated_space_and_one_complete_route_owner_map ... ok
|
||||
test allocation_drag::tests::assignment_tests::group_assignment_zero_delta_changes_semantics_once_and_then_is_noop ... ok
|
||||
test allocation_drag::tests::cache_plan_uses_candidate_index_and_same_pixel_different_target_changes_preview ... ok
|
||||
test allocation_drag::tests::collapsed_target_unfold_is_explicit_and_no_other_fold_changes ... ok
|
||||
test allocation_drag::tests::direct_exit_revealing_another_role_performer_has_truthful_refusal ... ok
|
||||
test allocation_drag::tests::explicit_different_performer_retains_advisory_role_warning ... ok
|
||||
test allocation_drag::tests::folded_subtree_cannot_hide_new_collision ... ok
|
||||
test allocation_drag::tests::geometry_refuses_new_overlap_bounds_and_invisible_headers_and_preserves_existing_overlap ... ok
|
||||
test allocation_drag::tests::group_arrange_experiment::mixed_arrange_experiment_detects_moved_folded_child_collision ... ok
|
||||
test allocation_drag::tests::group_arrange_experiment::mixed_arrange_experiment_detects_stationary_enclosure_growth_collision ... ok
|
||||
test allocation_drag::tests::group_arrange_experiment::mixed_arrange_experiment_distributed_root_and_performer_can_translate_rigidly ... ok
|
||||
test allocation_drag::tests::group_arrange_experiment::mixed_arrange_experiment_unrelated_folded_interiors_are_outside_diagnostic_domain ... ok
|
||||
test allocation_drag::tests::malformed_scope_wrong_projection_duplicate_placement_and_stable_id_collision_refuse ... ok
|
||||
test allocation_drag::tests::mixed_p_x_y_refuses_semantic_and_arrange_instead_of_stretching_destination ... ok
|
||||
test allocation_drag::tests::oa_communication_incompleteness_remains_advisory_without_collateral_loss ... ok
|
||||
test allocation_drag::tests::oa_sa_incoming_between_outgoing_preserve_identity_source_history_and_other_views ... ok
|
||||
test allocation_drag::tests::oa_sa_one_leaf_move_refuses_when_ancestor_regrouping_introduces_unrelated_overlap ... ok
|
||||
test allocation_drag::tests::oa_sa_one_leaf_reassignment_and_outward_move_regroup_ancestors_without_moving_sibling ... ok
|
||||
test allocation_drag::tests::oa_sa_populated_collapsed_target_accepts_room_and_refuses_collision_without_relocating_contents ... ok
|
||||
test allocation_drag::tests::oa_sa_state_owned_action_and_availability_reject_reassignment_atomically ... ok
|
||||
test allocation_drag::tests::oa_sa_unfolding_prior_hidden_overlap_refuses_even_when_insertion_does_not_collide ... ok
|
||||
test allocation_drag::tests::own_deleted_allocation_routes_may_disappear_in_every_diagram_only ... ok
|
||||
test allocation_drag::tests::role_only_same_effective_performer_is_semantic_noop_and_outgoing_refuses ... ok
|
||||
test allocation_drag::tests::sa_port_and_deferred_exchange_allocation_cascade_refuses_and_retarget_is_invalid ... ok
|
||||
test allocation_drag::tests::same_performer_readability_preserves_snapped_noop_and_allocation_identity ... ok
|
||||
test allocation_drag::tests::scope_detects_first_child_allocation_and_role_transfer_and_finish_rejects_live_edits ... ok
|
||||
test allocation_drag::tests::selected_header_visibility_allows_viewport_edge_but_refuses_clipping ... ok
|
||||
test allocation_drag::tests::snapped_noop_returns_no_command_and_keeps_source_revision_and_redo ... ok
|
||||
test allocation_drag::tests::source_budget_refusal_keeps_project_bundle_history_and_retry_identity_exact ... ok
|
||||
test allocation_drag::tests::surviving_constraint_mutation_is_refused_even_when_core_candidate_is_valid ... ok
|
||||
test allocation_drag::tests::target_presentation_requires_accepted_identity_and_selected_header_visibility ... ok
|
||||
test allocation_drag::tests::toolbar_identity_allows_exact_incoming_placement_at_old_label_overlap ... ok
|
||||
test allocation_drag::tests::uniform_folded_grandchild_and_unplaced_scope_moves_exactly_q_and_all_l_oa_sa ... ok
|
||||
test allocation_drag::tests::uniform_role_only_and_mixed_direct_role_composites_same_target_do_not_allocate ... ok
|
||||
test allocation_drag::tests::uniformly_unassigned_composite_creates_only_stable_leaf_allocations_including_unplaced ... ok
|
||||
test allocation_drag::tests::unrequested_view_option_cleanup_is_not_whitelisted ... ok
|
||||
test allocation_drag::tests::unresolved_role_leaf_can_arrange_or_accept_explicit_target_without_guessing ... ok
|
||||
test app::allocation_drag::clearance::tests::corner_order_follows_boundary_crossing_and_is_deterministic ... ok
|
||||
test app::allocation_drag::clearance::tests::descendant_footprint_controls_clearance_without_mutating_projects ... ok
|
||||
test app::allocation_drag::clearance::tests::each_outgoing_edge_clears_the_source_and_passes_ordinary_placement ... ok
|
||||
test app::allocation_drag::clearance::tests::independent_selected_roots_keep_one_rigid_group_translation ... ok
|
||||
test app::allocation_drag::clearance::tests::no_crossing_no_overlap_no_source_and_nonfinite_requests_are_empty ... ok
|
||||
test app::allocation_drag::clearance::tests::source_shrink_uses_candidate_enclosure_not_frozen_target ... ok
|
||||
test app::allocation_drag::tests::actual_canvas_origin_change_cancels_held_work_before_any_legacy_release ... ok
|
||||
test app::allocation_drag::tests::arrange_is_one_gesture_and_snapped_noop_preserves_redo_and_source ... ok
|
||||
test app::allocation_drag::tests::candidate_semantics_are_cached_per_destination_with_stable_ids_and_own_index ... ok
|
||||
test app::allocation_drag::tests::destination_identity_does_not_describe_blocked_or_outside_viewport_as_unallocation ... ok
|
||||
test app::allocation_drag::tests::frozen_collapsed_target_uses_only_visible_header_and_port_edge_controls_occlude ... ok
|
||||
test app::allocation_drag::tests::frozen_targets_use_half_open_semantic_priority_and_refuse_incomparable_overlap ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_app_tree_dirty_description_retains_focus_and_middle_caret_for_next_key ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_app_tree_dirty_name_retains_focus_and_middle_caret_for_next_key ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_app_tree_exact_incoming_drag_keeps_destination_visible_and_canvas_stable ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_keyboard_arrange_shortcut_consumes_once_escape_cancels_and_dirty_owner_refuses ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_rendered_canvas_pixels_do_not_change_when_toolbar_feedback_text_changes ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_toolbar_hover_inspects_last_full_name_without_authorizing_an_outside_drop ... ok
|
||||
test app::allocation_drag::tests::full_tree::actual_tree_outgoing_boundary_motion_preview_release_and_cancel ... ok
|
||||
test app::allocation_drag::tests::full_tree::control_focus::dirty_selected_pin_outer_ring_keeps_real_name_focus_and_caret ... ok
|
||||
test app::allocation_drag::tests::group::allocation_bare_moves_cannot_bypass_armed_active_or_retired_lifetime ... ok
|
||||
test app::allocation_drag::tests::group::completed_text_apply_rejects_old_allocation_packets_without_retiring_a_new_drag ... ok
|
||||
test app::allocation_drag::tests::group::connection_lifetime::captured_connection_after_cancel_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::connection_lifetime::captured_connection_context_mismatches_preserve_the_current_session ... ok
|
||||
test app::allocation_drag::tests::group::connection_lifetime::captured_connection_current_restart_and_pair_commit_after_tool_boundary ... ok
|
||||
test app::allocation_drag::tests::group::group_arrange_work_and_performer_anchors_preserve_every_responsibility ... ok
|
||||
test app::allocation_drag::tests::group::group_assignment_split_rebuild_preserves_primary_and_commits_one_complete_candidate ... ok
|
||||
test app::allocation_drag::tests::group::group_out_and_back_assigns_at_zero_delta_then_true_noop_preserves_redo ... ok
|
||||
test app::allocation_drag::tests::group::group_selection_aba_and_old_press_cannot_retire_a_new_token ... ok
|
||||
test app::allocation_drag::tests::group::group_source_refusal_retains_primary_source_and_both_history_paths ... ok
|
||||
test app::allocation_drag::tests::group::idle_group_press_rejects_selection_generation_aba_with_unchanged_other_stamps ... ok
|
||||
test app::allocation_drag::tests::group::ordinary_off_grid_performer_out_and_back_is_noop_with_redo ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::captured_route_context_fields_independently_reject_before_retirement ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::current_route_commits_without_session_preserve_exact_route_history ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::same_context_route_attachment_after_selection_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::same_context_route_commit_after_selection_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::stale_route_attachment_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::route_lifetime::stale_route_commit_preserves_arrange_arm_and_live_group ... ok
|
||||
test app::allocation_drag::tests::group::unsupported_group_click_collapses_but_threshold_crossing_never_becomes_click ... ok
|
||||
test app::allocation_drag::tests::modal_roundtrip_equal_fit_undo_resize_and_focus_retire_press_before_replay ... ok
|
||||
test app::allocation_drag::tests::mounted_clean_stationary_selects_exact_work_without_revision_or_legacy_apply ... ok
|
||||
test app::allocation_drag::tests::mounted_dirty_port_press_cannot_fall_through_to_applying_port_selection ... ok
|
||||
test app::allocation_drag::tests::mounted_dirty_property_press_does_not_select_apply_or_destroy_draft ... ok
|
||||
test app::allocation_drag::tests::mounted_oa_sa_ordered_incoming_between_outgoing_are_exact_single_history_steps ... ok
|
||||
test app::allocation_drag::tests::mounted_role_only_outgoing_refusal_retains_placement_and_same_performer_creates_no_allocation ... ok
|
||||
test app::allocation_drag::tests::mounted_uniform_parent_moves_hidden_placements_and_assigns_only_leaves ... ok
|
||||
test app::allocation_drag::tests::navigation_union::old_chooser_envelopes_preserve_a_current_canvas_gesture ... ok
|
||||
test app::allocation_drag::tests::navigation_union::stale_gesture_packets_preserve_navigation_and_a_new_live_cancel_still_works ... ok
|
||||
test app::allocation_drag::tests::oa_sa_clipped_selected_header_refuses_preview_release_and_retries_without_partial_source_or_history ... ok
|
||||
test app::allocation_drag::tests::oa_sa_toolbar_identity_accepts_exact_receiver_and_collapsed_header_drag ... ok
|
||||
test app::allocation_drag::tests::outgoing_boundary_drop_clears_source_without_changing_other_placements ... ok
|
||||
test app::allocation_drag::tests::outgoing_clearance_collision_refuses_release_without_source_or_history_mutation ... ok
|
||||
test app::allocation_drag::tests::outgoing_clearance_preserves_source_enclosure_and_allocated_sibling ... ok
|
||||
test app::allocation_drag::tests::outside_release_is_cancel_and_does_not_remove_an_assignment ... ok
|
||||
test app::allocation_drag::tests::pending_behavior_draft_refuses_actual_work_press_and_equal_document_replacement_retires_packet ... ok
|
||||
test app::allocation_drag::tests::refused_motion_retains_last_scene_but_release_never_commits_it ... ok
|
||||
test app::allocation_drag::tests::release_uses_ordered_native_position_before_later_motion_in_same_batch ... ok
|
||||
test app::allocation_drag::tests::same_snapped_position_on_opposite_shared_border_rebuilds_semantics_even_if_layout_refuses ... ok
|
||||
test app::allocation_drag::tests::source_and_modal_admission_reject_prebuilt_clean_press_without_selecting ... ok
|
||||
test app::allocation_drag::tests::source_refusal_is_atomic_and_a_new_gesture_can_retry_against_live_revision ... ok
|
||||
test app::allocation_drag::tests::stale_packets_do_not_cancel_a_newer_token_and_each_release_is_consumed_once ... ok
|
||||
test app::allocation_drag::tests::toolbar_destination_names_transformed_target_whose_header_is_clipped ... ok
|
||||
test app::allocation_drag::tests::toolbar_status_leaves_transformed_top_edge_work_header_readable ... ok
|
||||
|
||||
test result: ok. 123 passed; 0 failed; 0 ignored; 0 measured; 1424 filtered out; finished in 54.86s
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Independent downloaded Windows package QA
|
||||
|
||||
Codex-9e8r6t /root, 2026-09-24. **PASS for the bounded package, State presentation/picker/reopen, built-in guide and packaged-server checks below.** No material blocker found in this scope. This evidence supports the release owner's admission decision; it does not claim completion of issue 37, the full checklist, or the user application goal.
|
||||
|
||||
## Exact artifact and source
|
||||
|
||||
- Draft release 7: `v0.2.0-preview.integrated.20260924`, source **`715036e132677dd2bc2fb37ed316d93dc9987aec`**.
|
||||
- Studio asset 25: `ArcadiaStudio-0.2.0-preview.integrated.20260924-x86_64-pc-windows-gnullvm.zip`, 34,168,661 bytes, SHA256 **`5554e32533e3cb2c33fb4143a5a0902733d5a8d47577303cb2842d268e7bc76d`**; checksum asset 26 agrees. Companion assets 21–24 also downloaded and verified.
|
||||
- Windows 11 build 26200, exact downloaded executables with bundled libunwind and system-only process PATH. Fresh extraction on a machine separate from the producer, unrelated desktop cwd, existing user profile. No local compilation or Linux checks; user explicitly excludes Linux for this prerelease.
|
||||
- This branch only adds QA documentation/evidence. The tested product stays at 715036e; later documentation commit identities are not rebuilt-product identities. Release/tag/publication ownership remains Codex-956atf.
|
||||
|
||||
## Results
|
||||
|
||||
| Scope | Result and limits |
|
||||
| --- | --- |
|
||||
| Download/package | All 565 archive files equal extraction; 564 checksum entries and 559 package input pins pass. Independent PE imports identify only bundled libunwind outside system components, no delay imports. 18 local doc links, 66 shipped source documents/examples, 489 notice references and 529 recorded local inputs checked. |
|
||||
| Build linkage | Both executable bytes equal the preserved **individual** final04 Cargo-identified builds for 715036e. All four BuildEvidence pins resolve to the published 206f3b9 gate evidence; all 462 archived evidence members verified. Supplemental combined-build hashes are distinct and excluded. No independent compiler rebuild claim. |
|
||||
| Native desktop | Bundled walkthrough loads from unrelated cwd; State add-bend visual Undo/Redo, bend movement with exact whole-source Undo/Redo, independent view navigation, dropdown-only Escape, explicit form Cancel, Save, normal exit and fresh-process reopen pass. Only one authored waypoint is added; semantics, attachments, node positions and all other views remain original bytes. Both runs exit 0 with empty logs. |
|
||||
| Built-in guide | Engineering guide and State topic render in the packaged app. A network-disabled environment was not tested. |
|
||||
| Server | 23 explicit runtime checks and 11 captured HTTP exchanges: version/help, readiness, served OpenAPI, complete authored CRLF/Unicode source, conditional name-only revision 1→2, stale ETag 412, exact model/source/store and acknowledged-write restart persistence. Both owned processes stopped. Forced exit 1 was intentional; no graceful shutdown, in-flight or power-loss claim. |
|
||||
|
||||
Detailed reports: [package/build review](package-provenance-review.md), [native observations](native-observations.md), [independent native/source review](native-source-review.md), [picker-policy review](picker-policy-review.md), [server review](server-review.md).
|
||||
|
||||
At 56% Fit the State fixture's labels remain small/crowded. These results do not establish broad editing usability or accessibility, aggregate deletion, modifier gestures, every new-feature combination, authentication/load/TLS, Linux, or complete product acceptance. The fixture's 12 model checks are intentional incompleteness. The second Escape **kept** the ordinary State edit form; explicit Cancel closed it. Capture 26's optimistic filename is contradicted by its retained screenshot and corrected in the reports. No in-memory history-stack introspection was performed.
|
||||
|
||||
## Portable evidence and reproduction
|
||||
|
||||
[evidence.zip](evidence.zip) contains **190 original/helper/review records**, **3,425,348 bytes**, SHA256 **`cb084be5f316f1b3be45bc5493fe0cbd6076052198c09f9dbac441b8f2588e63`**. [manifest.json](manifest.json) binds every member's size/hash and the ZIP; [checksum](evidence.zip.sha256) is supplied separately. This is evidence only: runnable product remains the release asset, not duplicated in Git.
|
||||
|
||||
Extract the ZIP into a new directory. Run `python -B native-check.py` and `python -B server-readback-check.py` there for offline full-source and captured-HTTP reconciliation. Retained successful results are `native-check.json` and `server-readback-check.json`. Original captures/metadata and launch/exit records live in `native-2/` and `native-3/`; baseline and all five saved source snapshots are included. `server-smoke/` contains the exact helper, requests/responses, source, accepted envelope, isolated store and logs.
|
||||
|
||||
Static package audits require the same release assets extracted at the original relative layout under `.local/package-qa/download-1`, a source checkout at 715036e, and `scripts/package-artifacts.py`. The archived audit helpers retain their original checkout-relative paths. `package-audit/build-link.py` also requires fetched commit `206f3b969482241e01e2dfc6be955caf31747b89`. It resolves `harness/prerelease37-windows-gates-20260924/final04-complete`, whose archive is SHA256 `7cead0b6aa36a6af8fc9f8987186bfe0decd8fa2ebab094fc45387ae9daea632`. The initial static result's producer-local `available_on_this_machine:false` fields are historical; subsequent `build-link-records.json` resolves them using the published raw evidence. Native/server launch helpers describe the performed environment; use a fresh evidence directory for a new runtime trial rather than overwriting these records.
|
||||
|
||||
The reports retain harness-only corrections: environment-key casing before first launch, native dialog automation limitations, and explicit UTF-8 decoding in parent HTTP reconciliation. None changed product bytes or converted a failed product trial into a pass.
|
||||
|
||||
[Final independent archive review](final-evidence-review.md) verified all 190 members against retained originals, bound the baseline to the companion ZIP, and replayed both offline evaluators from a fresh extraction with unchanged files and exact recorded results. That review is outside the already-frozen evidence ZIP.
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
cb084be5f316f1b3be45bc5493fe0cbd6076052198c09f9dbac441b8f2588e63 evidence.zip
|
||||
@@ -0,0 +1,28 @@
|
||||
# Independent final evidence audit
|
||||
|
||||
2026-09-24. Reviewed `harness/prerelease37-independent-9e8r6t-20260924` before publication. **No material finding within this bounded audit.** The package preserves the original evidence, both advertised portable read-only replays pass from a fresh extraction, and the README/report claims remain appropriately scoped.
|
||||
|
||||
## Archive and original fidelity
|
||||
|
||||
Independently rehashed `evidence.zip`: 3,425,348 bytes, SHA256 `cb084be5f316f1b3be45bc5493fe0cbd6076052198c09f9dbac441b8f2588e63`. This exactly matches the manifest, adjacent checksum and README. There are 190 unique members with no case-insensitive duplicate, traversal, absolute or backslash-ambiguous paths. Every member size/hash matches the manifest. Every member also equals its retained original under `.local/package-qa`; the separately named baseline and package metadata were mapped to the original companion extraction and Studio extraction. All five outer detailed reports equal their archived and original copies.
|
||||
|
||||
The native baseline is 9,662 bytes, SHA256 `2dae785d63a940094d8052f3dcddcb988c024b38df9780e026bccd516264dbfe`. It exactly equals the fixture member inside the archived State/Traceability companion ZIP, whose checksum also passes. Thus the portable native evaluator's baseline is independently tied to the downloaded companion, rather than merely accepted as a newly authored expected file. Both native start receipts' download-proof and launcher pins match archived bytes, and their executable/runtime pins equal the actual retained downloaded Studio executable and libunwind bytes.
|
||||
|
||||
The earlier package provenance audit remains applicable: downloaded Studio archive `5554e325...`, source `715036e132677dd2bc2fb37ed316d93dc9987aec`, and both executables' linkage to the preserved individual final04 Cargo-identified outputs. The final README correctly describes the separately verified 206f3b9 evidence and does not substitute the supplemental combined-build bytes. Historical producer-local unavailable-path fields in the first static result are explained by the later build-link records.
|
||||
|
||||
## Independent portable replay
|
||||
|
||||
Created a new isolated extraction at `.local/package-qa/final-review-replay-xkq9rytf`, outside both the immutable published candidate and the original run directories. Ran each extracted script using the bundled Python with `-B`, with the extraction as working directory:
|
||||
|
||||
- `native-check.py`: exit 0, empty stderr, output JSON exactly equal to archived `native-check.json`.
|
||||
- `server-readback-check.py`: exit 0, empty stderr, output JSON exactly equal to archived `server-readback-check.json`.
|
||||
|
||||
Rehashed every extracted file before and after each execution: no file changed or appeared. The scripts perform no product launch, network request or source build. The native replay compares all five full-source snapshots against baseline plus the single exact waypoint addition; movement Undo/Redo, explicit cancellation and fresh-process save retain the stated complete-file invariants. The HTTP replay checks all 11 captured response statuses, exact CRLF/Unicode source bundles, name-only model change, revisions/ETags, stale-write refusal, restart envelope and on-disk store equality. Its 23-check count describes the recorded runtime helper, not 23 newly executed runtime checks.
|
||||
|
||||
## Claims and selected visual review
|
||||
|
||||
Read the README and all five detailed reports, plus the two replay scripts and assembler. The top-level report clearly distinguishes visible add-bend Undo/Redo from saved full-source movement Undo/Redo, existing user profile from a clean OS/profile, rendered guide content from a network-disabled test, normal desktop exit from intentionally forced server termination, and scoped QA from full prerelease/product acceptance.
|
||||
|
||||
Manually inspected the original full-window `native-2/26-second-escape-cancels-form-1.jpg`: the ordinary State Edit transition form is visibly still present. The README and native/source/policy reports correctly override that optimistic filename with observed retention and identify explicit Cancel separately. Inspected `native-3/05-persisted-bend-selected-1.jpg`: the reopened edit-attachments view shows the selected Activate route and two square bend handles, including the downward bend. Its labels are small/crowded at 56%, consistently disclosed as a usability limitation. Exact coordinate and unrelated-source preservation claims come from the byte oracle, not pixel inference.
|
||||
|
||||
The server report preserves the two imposed exit-1 results and limits persistence to already acknowledged writes; it makes no graceful shutdown, in-flight write, power-loss, authentication, TLS, load or Linux claim. Helper-only corrections and the original capture labels remain disclosed. No product runtime/build, Git mutation, source edit or network action occurred in this audit. The only new artifacts are the fresh replay extraction and this review, outside the immutable evidence archive.
|
||||
@@ -0,0 +1,775 @@
|
||||
{
|
||||
"source": "715036e132677dd2bc2fb37ed316d93dc9987aec",
|
||||
"release": 7,
|
||||
"studioAsset": 25,
|
||||
"studioZip": {
|
||||
"bytes": 34168661,
|
||||
"sha256": "5554e32533e3cb2c33fb4143a5a0902733d5a8d47577303cb2842d268e7bc76d"
|
||||
},
|
||||
"members": {
|
||||
"assemble.py": {
|
||||
"bytes": 2742,
|
||||
"sha256": "a44cc7f41cc92ca42e070a4913be989bfd35fa1e27b1665db66bc2d5502fc02b"
|
||||
},
|
||||
"download-1/ArcadiaStudio-0.2.0-preview.integrated.20260924-x86_64-pc-windows-gnullvm.zip.sha256": {
|
||||
"bytes": 144,
|
||||
"sha256": "41c7b1257660b66a44f27555e0e9613e7f6e4c0b119522347e3ccff54d60cea1"
|
||||
},
|
||||
"download-1/ArcadiaStudio-Allocation-Process-checks-20260924.zip": {
|
||||
"bytes": 17190,
|
||||
"sha256": "17327e563af333fd9913f6d8b8a7e6ad0e095cea33393a5cad7a8b3397ffb185"
|
||||
},
|
||||
"download-1/ArcadiaStudio-Allocation-Process-checks-20260924.zip.sha256": {
|
||||
"bytes": 119,
|
||||
"sha256": "9e1052b1d6cc04f081f5657f69c4e7e22be9abae8d64ec1e9eb210e4d1f34bbb"
|
||||
},
|
||||
"download-1/ArcadiaStudio-State-Traceability-checks-20260924.zip": {
|
||||
"bytes": 9691,
|
||||
"sha256": "6fda3606b4fe811906a60fbb8a3ba594f826d285dc2b4fc136ddccb64660d994"
|
||||
},
|
||||
"download-1/ArcadiaStudio-State-Traceability-checks-20260924.zip.sha256": {
|
||||
"bytes": 119,
|
||||
"sha256": "8d6ab2c2a4ffeda42616a737c3fa514c2c94b33032dff6b12666d6313e77e324"
|
||||
},
|
||||
"download-1/assets.json": {
|
||||
"bytes": 2684,
|
||||
"sha256": "3312039a6d86262672e7d0a073faf5bd7dc88807db0a34a0400fef2773a6ba8f"
|
||||
},
|
||||
"download-1/download-result.json": {
|
||||
"bytes": 157695,
|
||||
"sha256": "198685f4d1e338857b9c2a61f7c046a66618ff8b88e2064435d3652ae6f4f73f"
|
||||
},
|
||||
"download-1/release.json": {
|
||||
"bytes": 5182,
|
||||
"sha256": "037816d561ff6d75e6d45dc98a578a47f70f105f30da2e91d1d0dfe317d77c1e"
|
||||
},
|
||||
"download.py": {
|
||||
"bytes": 3838,
|
||||
"sha256": "4353f4bff5d1ecba90e70725384c9d5e6b6d3f8ce970d1f22a0faac5a338f1a2"
|
||||
},
|
||||
"native-2/01-home-0.jpg": {
|
||||
"bytes": 103896,
|
||||
"sha256": "7db5300ebe5a1eb9e7135d33975531f643e205601f669e3bf25fb9745b3994ff"
|
||||
},
|
||||
"native-2/01-home.json": {
|
||||
"bytes": 981,
|
||||
"sha256": "7a40f7186e468099d7e7837c3968a08ad4e13f12d08f58071fd102fbeaaf7a83"
|
||||
},
|
||||
"native-2/02-maximized-home-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/02-maximized-home-1.jpg": {
|
||||
"bytes": 105249,
|
||||
"sha256": "48ced23c34ac07509446511e700892478e3f9876004f7a5b5bd120cd65b75e22"
|
||||
},
|
||||
"native-2/02-maximized-home.json": {
|
||||
"bytes": 1110,
|
||||
"sha256": "d3487f8a4ee43932afed3c6cb6843334bff1f137e7d16463b3e14d9e458da1d1"
|
||||
},
|
||||
"native-2/03-bundled-walkthrough-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/03-bundled-walkthrough-1.jpg": {
|
||||
"bytes": 103761,
|
||||
"sha256": "e334cc9addc67390881d9b4629646643f6eb57b4aed8b488deea25503c00b7bd"
|
||||
},
|
||||
"native-2/03-bundled-walkthrough.json": {
|
||||
"bytes": 1120,
|
||||
"sha256": "161db29fd86461c77a4411ec7ea4e74d822ab54dcbfb86ceeeb6bab8337d00b9"
|
||||
},
|
||||
"native-2/04-walkthrough-loaded-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/04-walkthrough-loaded-1.jpg": {
|
||||
"bytes": 142209,
|
||||
"sha256": "d566beb4d45998de78ea57a01c39a92ac3cb3db5d268016247b9427694f3c8f9"
|
||||
},
|
||||
"native-2/04-walkthrough-loaded.json": {
|
||||
"bytes": 1303,
|
||||
"sha256": "d913fbee41d5e069a1f1eee227d1470ce752880b38c1f283d01bc931bf0c347f"
|
||||
},
|
||||
"native-2/05-state-fixture-open-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/05-state-fixture-open-1.jpg": {
|
||||
"bytes": 110683,
|
||||
"sha256": "b8fadad5f4f8cee676ef288131e336236531a7c7c9dc383c22b479fd19823d7c"
|
||||
},
|
||||
"native-2/05-state-fixture-open.json": {
|
||||
"bytes": 1303,
|
||||
"sha256": "cd991ce13b60ef70234950bb96efdecccb6c719ffb0b10cd377858e873f9b70a"
|
||||
},
|
||||
"native-2/06-system-perspective-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/06-system-perspective-1.jpg": {
|
||||
"bytes": 129420,
|
||||
"sha256": "4841b3d79220bfbc955a619ce0ddd81b4c75acc471c5f9f15860adb8d6f4bcba"
|
||||
},
|
||||
"native-2/06-system-perspective.json": {
|
||||
"bytes": 1243,
|
||||
"sha256": "4b2dd65851b41c33c4cdd26a7e0b98d16171d60aba52fe9851b9582ea1ac572a"
|
||||
},
|
||||
"native-2/07-activate-transition-selected-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/07-activate-transition-selected-1.jpg": {
|
||||
"bytes": 129572,
|
||||
"sha256": "3c176faf194ed25517fab1762ba2419c61777d8df78d27b43c85de252062fc8a"
|
||||
},
|
||||
"native-2/07-activate-transition-selected.json": {
|
||||
"bytes": 1263,
|
||||
"sha256": "3ecc247a8c0bae174df3ba4887213f0b77e4b0c48232a1aab2720ced81e68161"
|
||||
},
|
||||
"native-2/08-transition-actions-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/08-transition-actions-1.jpg": {
|
||||
"bytes": 132017,
|
||||
"sha256": "d33691c256cfe24eb910be9cda23cc851dae3ea42537a3b389dead0a9503a16c"
|
||||
},
|
||||
"native-2/08-transition-actions.json": {
|
||||
"bytes": 1243,
|
||||
"sha256": "9d4f6ebe683701a28ff4c2bb2941da680c3adbbd4526374ab35654d51ee2b23c"
|
||||
},
|
||||
"native-2/09-add-bend-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/09-add-bend-1.jpg": {
|
||||
"bytes": 128200,
|
||||
"sha256": "22a5382b80b22e5e7e8b539d5e1d3c1718a83fbe6d7c304c0efd9c068b7f22e8"
|
||||
},
|
||||
"native-2/09-add-bend.json": {
|
||||
"bytes": 1231,
|
||||
"sha256": "ccaebd7e516f9f02efa686b5ee3fcc3a00a64079e0bf3347a94e8990c7b790ba"
|
||||
},
|
||||
"native-2/10-undo-added-bend-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/10-undo-added-bend-1.jpg": {
|
||||
"bytes": 126682,
|
||||
"sha256": "f51fe83cb7796bb43bacd66119cc77f74f7508b71638c10b8594503517268044"
|
||||
},
|
||||
"native-2/10-undo-added-bend.json": {
|
||||
"bytes": 1239,
|
||||
"sha256": "f2a4233e6fdbeb35b44d79a76f3a0aacbe4775ac3254b792314ea0a2fb52a259"
|
||||
},
|
||||
"native-2/11-redo-added-bend-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/11-redo-added-bend-1.jpg": {
|
||||
"bytes": 126800,
|
||||
"sha256": "561f1e4524b7d6c4d33b00e3047fc3b48a79d3801933431f01df800ba0b92460"
|
||||
},
|
||||
"native-2/11-redo-added-bend.json": {
|
||||
"bytes": 1245,
|
||||
"sha256": "44c5184cd68b2ee319e913c02e67528aec78432317bddde5622b3a3d00508032"
|
||||
},
|
||||
"native-2/12-move-new-bend-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/12-move-new-bend-1.jpg": {
|
||||
"bytes": 128606,
|
||||
"sha256": "d99f2ff1e75f69181cc700f8c6ee71790b300f4e4eae37e48a70548335795aca"
|
||||
},
|
||||
"native-2/12-move-new-bend.json": {
|
||||
"bytes": 1243,
|
||||
"sha256": "544c719817b52d84e432161f90acc23248f753cec53dfc7093a4a460f6cd3604"
|
||||
},
|
||||
"native-2/13-save-bend-edit-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/13-save-bend-edit-1.jpg": {
|
||||
"bytes": 126952,
|
||||
"sha256": "1038eaf6e03d1b1652ad0d7a87fa3e4fde619e86dd2c31a1f81002783e482e9f"
|
||||
},
|
||||
"native-2/13-save-bend-edit.json": {
|
||||
"bytes": 1237,
|
||||
"sha256": "2fffb1f9fc0575db2157bd4b4facff13833a812237e826700269863d4c22dd54"
|
||||
},
|
||||
"native-2/14-undo-bend-move-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/14-undo-bend-move-1.jpg": {
|
||||
"bytes": 126804,
|
||||
"sha256": "15408b738a4508b64ef47151ff3b762ee1316db03837b2fba5ebd6044b290791"
|
||||
},
|
||||
"native-2/14-undo-bend-move.json": {
|
||||
"bytes": 1243,
|
||||
"sha256": "5d98c93c27ea062d4cebc15c26defcd3e6a5b21c793b5f6b1cea35a565f59938"
|
||||
},
|
||||
"native-2/15-save-undone-move-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/15-save-undone-move-1.jpg": {
|
||||
"bytes": 126302,
|
||||
"sha256": "26bd1d6d2dfb01667d756d93ba4e94f3023af65a8574707b8e9d894225bac546"
|
||||
},
|
||||
"native-2/15-save-undone-move.json": {
|
||||
"bytes": 1241,
|
||||
"sha256": "768cae7204c2bd0fb833b68eebdec718311b736803b0418477e26f6e21a4a1b9"
|
||||
},
|
||||
"native-2/16-redo-bend-move-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/16-redo-bend-move-1.jpg": {
|
||||
"bytes": 127338,
|
||||
"sha256": "4188744410f21061b4a3f09dd2e69566256a2a8f0cd82f23eea88f7bbcb12c9f"
|
||||
},
|
||||
"native-2/16-redo-bend-move.json": {
|
||||
"bytes": 1243,
|
||||
"sha256": "7bb46dc2c1318ff8ce0a134692d4567a0fba1cf468c44ca2389c6e62f8b2b5e2"
|
||||
},
|
||||
"native-2/17-save-redone-move-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/17-save-redone-move-1.jpg": {
|
||||
"bytes": 126803,
|
||||
"sha256": "7f29d34336c5fd7bc45677e542be6c7cbb9d5aa1255a5adb8e4f76453ffb8df2"
|
||||
},
|
||||
"native-2/17-save-redone-move.json": {
|
||||
"bytes": 1241,
|
||||
"sha256": "c4a1fb2ee1dd6c26be9bbfe2559813133cf7174d17622d5a8446160e3bd5b224"
|
||||
},
|
||||
"native-2/18-state-view-picker-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/18-state-view-picker-1.jpg": {
|
||||
"bytes": 129077,
|
||||
"sha256": "99f8ffd05b6cbc400712180d4749410aae4276dc288cc69d535021cc4d61b1a4"
|
||||
},
|
||||
"native-2/18-state-view-picker.json": {
|
||||
"bytes": 1241,
|
||||
"sha256": "81d52aca8a4870d10be4ee48459ebc940b5c9399817f74c03f7bb2c545b6370f"
|
||||
},
|
||||
"native-2/19-reference-view-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/19-reference-view-1.jpg": {
|
||||
"bytes": 126293,
|
||||
"sha256": "a3653870e1afcc8808b4627bc435938f97eb9487e00b91b2278fbc7265bf9cda"
|
||||
},
|
||||
"native-2/19-reference-view.json": {
|
||||
"bytes": 1235,
|
||||
"sha256": "625a6587819f203fa8b82ca86a32cbf6b1853de6d7ee8024177adbed8f7eee74"
|
||||
},
|
||||
"native-2/20-reference-picker-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/20-reference-picker-1.jpg": {
|
||||
"bytes": 129268,
|
||||
"sha256": "de07f6abf1df6ccfa2d1461f0e9d03dc5a8c59d1b999e99b47ad548ad0e33f3a"
|
||||
},
|
||||
"native-2/20-reference-picker.json": {
|
||||
"bytes": 1239,
|
||||
"sha256": "37d6b22eda964fc5d270c3699b42de77012ed91ae02b809320517eaa6414043f"
|
||||
},
|
||||
"native-2/21-edited-view-return-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/21-edited-view-return-1.jpg": {
|
||||
"bytes": 126971,
|
||||
"sha256": "c9ae903418fa95118ed00ebc17026e52224cefdb075740f38784f90d97a375be"
|
||||
},
|
||||
"native-2/21-edited-view-return.json": {
|
||||
"bytes": 1243,
|
||||
"sha256": "95bdfe3e5150e353be6bbc54722bf5d10b5ef526da2589d3c65771a10851119b"
|
||||
},
|
||||
"native-2/22-transition-actions-reopen-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/22-transition-actions-reopen-1.jpg": {
|
||||
"bytes": 130710,
|
||||
"sha256": "850d1ffe7e4ec1eafdcd9056c115f1c50d4f310112b2502c23c3e7ee7667c2fc"
|
||||
},
|
||||
"native-2/22-transition-actions-reopen.json": {
|
||||
"bytes": 1257,
|
||||
"sha256": "4c256bdee194721424a98bca0cc4ac5df259d45174ccfd6dc1a9275b4a959644"
|
||||
},
|
||||
"native-2/23-transition-edit-form-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/23-transition-edit-form-1.jpg": {
|
||||
"bytes": 134465,
|
||||
"sha256": "d6b2a6d00544c84eaaa66481621eb70281b22eabe86539d54489cd28b997f54e"
|
||||
},
|
||||
"native-2/23-transition-edit-form.json": {
|
||||
"bytes": 1255,
|
||||
"sha256": "0a8f47170b1e9c6ab183401ac94a6a7af56b98d6f18248e2cc88aa4dbf0ce09f"
|
||||
},
|
||||
"native-2/24-transition-source-picker-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/24-transition-source-picker-1.jpg": {
|
||||
"bytes": 132783,
|
||||
"sha256": "fcb23f584ecb4470122c4a2276dfe92d3e8b20754e0a641c6cf53c50a2cbe883"
|
||||
},
|
||||
"native-2/24-transition-source-picker.json": {
|
||||
"bytes": 1265,
|
||||
"sha256": "a2af6cde560ffe2ce114c1ba5019ebd81af45960249ef1af040b0d63f85fa996"
|
||||
},
|
||||
"native-2/25-first-escape-picker-only-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/25-first-escape-picker-only-1.jpg": {
|
||||
"bytes": 134562,
|
||||
"sha256": "a45837ea333a05b50be5c081378cdce51b9c302ca49ce956389063e83906b63d"
|
||||
},
|
||||
"native-2/25-first-escape-picker-only.json": {
|
||||
"bytes": 1265,
|
||||
"sha256": "2d153f32fcfa82171a4f9721b1148bdcca32560f93ab75d8bb9a46dfdf87d6fb"
|
||||
},
|
||||
"native-2/26-second-escape-cancels-form-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/26-second-escape-cancels-form-1.jpg": {
|
||||
"bytes": 134562,
|
||||
"sha256": "a45837ea333a05b50be5c081378cdce51b9c302ca49ce956389063e83906b63d"
|
||||
},
|
||||
"native-2/26-second-escape-cancels-form.json": {
|
||||
"bytes": 1269,
|
||||
"sha256": "38d9b72fd6a36a524ba281c798f4b3266d13c82761da3c62d32f804b1131a062"
|
||||
},
|
||||
"native-2/27-second-escape-settled-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/27-second-escape-settled-1.jpg": {
|
||||
"bytes": 134562,
|
||||
"sha256": "a45837ea333a05b50be5c081378cdce51b9c302ca49ce956389063e83906b63d"
|
||||
},
|
||||
"native-2/27-second-escape-settled.json": {
|
||||
"bytes": 1259,
|
||||
"sha256": "8c3ac677ba291dd3a3c59345e78d36844fb93e5be69c960f7e25c5fb23a19a9e"
|
||||
},
|
||||
"native-2/28-explicit-cancel-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/28-explicit-cancel-1.jpg": {
|
||||
"bytes": 127338,
|
||||
"sha256": "af811b0432a4dbf16c0312af2c4222ede3abccbed189d1ce238382abef0c4146"
|
||||
},
|
||||
"native-2/28-explicit-cancel.json": {
|
||||
"bytes": 1239,
|
||||
"sha256": "d1b45b5bd046acdff26737d9c3461f03383d2d5ec3f017afd4c1d4dcd01a9721"
|
||||
},
|
||||
"native-2/29-save-after-form-cancel-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-2/29-save-after-form-cancel-1.jpg": {
|
||||
"bytes": 127312,
|
||||
"sha256": "81228aae86327fbc8a937c93c6919424d9fdd9273f65d773964488fe7813a655"
|
||||
},
|
||||
"native-2/29-save-after-form-cancel.json": {
|
||||
"bytes": 1251,
|
||||
"sha256": "e8ac53acde40e4634e101bf199795bdec32448a94d065b55eb251e28bb53ccc2"
|
||||
},
|
||||
"native-2/after-cancel-saved.arcadia": {
|
||||
"bytes": 9705,
|
||||
"sha256": "ea05d0e409687c7943dda0b93bc34036eb524f5f5033b912e71ad2eaf643a158"
|
||||
},
|
||||
"native-2/bend-saved.arcadia": {
|
||||
"bytes": 9705,
|
||||
"sha256": "ea05d0e409687c7943dda0b93bc34036eb524f5f5033b912e71ad2eaf643a158"
|
||||
},
|
||||
"native-2/finished.json": {
|
||||
"bytes": 354,
|
||||
"sha256": "4094c500ce0668ef6f0cba4e8ac43e3630d483be3a1b4f94584ce004e7826f9e"
|
||||
},
|
||||
"native-2/move-redo-saved.arcadia": {
|
||||
"bytes": 9705,
|
||||
"sha256": "ea05d0e409687c7943dda0b93bc34036eb524f5f5033b912e71ad2eaf643a158"
|
||||
},
|
||||
"native-2/move-undo-saved.arcadia": {
|
||||
"bytes": 9705,
|
||||
"sha256": "7f1fc18265a79b7d452e4a3de3f17671684e38c0f727cbdec15833196f46f114"
|
||||
},
|
||||
"native-2/started.json": {
|
||||
"bytes": 891,
|
||||
"sha256": "cd12917f9016f3f6e271ddf0a8eec1bc2cfd4fc2c65389380f9ecb43aaca1643"
|
||||
},
|
||||
"native-2/stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"native-2/stdout.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"native-3/01-fresh-home-0.jpg": {
|
||||
"bytes": 101565,
|
||||
"sha256": "1823169b7164d38e81c38b83f2c3927f9f4b37f6fb59732d3387fa1791dbaff4"
|
||||
},
|
||||
"native-3/01-fresh-home.json": {
|
||||
"bytes": 988,
|
||||
"sha256": "a1562b3b2d66aa3d25b88cd693a505f9db7cac07177088d0d529ba19ea4cc1a9"
|
||||
},
|
||||
"native-3/02-maximized-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-3/02-maximized-1.jpg": {
|
||||
"bytes": 105356,
|
||||
"sha256": "f12eb6b9e8ce8606ffffd89fdd916cd6562492de3e69a7f104163816580f4107"
|
||||
},
|
||||
"native-3/02-maximized.json": {
|
||||
"bytes": 1101,
|
||||
"sha256": "ec1750b82cd0ffb5964e265ec2d5a027225e374e3afd6d9616eff38f5b5ed398"
|
||||
},
|
||||
"native-3/03-open-saved-fixture-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-3/03-open-saved-fixture-1.jpg": {
|
||||
"bytes": 110813,
|
||||
"sha256": "7a187538b69c82907fe301d778acae5fdbed094d87d9646942f0c324ae44df79"
|
||||
},
|
||||
"native-3/03-open-saved-fixture.json": {
|
||||
"bytes": 1119,
|
||||
"sha256": "c22071d278a4c2f4b9fb614bee7f3f0a707a8e82ecf7f0a78765bf16dc6f562b"
|
||||
},
|
||||
"native-3/04-system-state-reopened-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-3/04-system-state-reopened-1.jpg": {
|
||||
"bytes": 129878,
|
||||
"sha256": "2db55e8cc7f603c08b151cc020214ddd7a103d0bdb59e6d04bf5cd6a42fc3119"
|
||||
},
|
||||
"native-3/04-system-state-reopened.json": {
|
||||
"bytes": 1250,
|
||||
"sha256": "356f04db8dfa782a5816d050fd8a7c9a09a9cb5f58f5619ee90eca96b759314c"
|
||||
},
|
||||
"native-3/05-persisted-bend-selected-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-3/05-persisted-bend-selected-1.jpg": {
|
||||
"bytes": 129942,
|
||||
"sha256": "118a7bfb22bff5099a6f7008e234f85102992834d80d66510ee898562a3844b7"
|
||||
},
|
||||
"native-3/05-persisted-bend-selected.json": {
|
||||
"bytes": 1254,
|
||||
"sha256": "0279ec95b15e265c770c5168c34412ead55a18fbd38b2f47169f5b325c51f28a"
|
||||
},
|
||||
"native-3/06-save-after-reopen-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-3/06-save-after-reopen-1.jpg": {
|
||||
"bytes": 128388,
|
||||
"sha256": "e9185c8e612020d05cce72f995d21f22e6e832f05a63c66bf4c56f02639a9905"
|
||||
},
|
||||
"native-3/06-save-after-reopen.json": {
|
||||
"bytes": 1242,
|
||||
"sha256": "d74f726ff589336db1772cc8d7988d8c73f3c6d63973e6871324a3a3232cd632"
|
||||
},
|
||||
"native-3/07-engineering-guide-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-3/07-engineering-guide-1.jpg": {
|
||||
"bytes": 173028,
|
||||
"sha256": "1e9a9cdc315c7e12901ba3a5bd1dec6cfc2f5c3628d40346ade986c19b4e4254"
|
||||
},
|
||||
"native-3/07-engineering-guide.json": {
|
||||
"bytes": 1242,
|
||||
"sha256": "53a5822d73022eaed8c73b1d763d2a89facbc1878bc06ab6eecb18890af2ca9a"
|
||||
},
|
||||
"native-3/08-state-guide-topic-0.jpg": {
|
||||
"bytes": 722,
|
||||
"sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d"
|
||||
},
|
||||
"native-3/08-state-guide-topic-1.jpg": {
|
||||
"bytes": 198585,
|
||||
"sha256": "0bcab4102666a794fd791561a4ef4ff44add5bfbb377cb9e79fb0cae3e57cbc9"
|
||||
},
|
||||
"native-3/08-state-guide-topic.json": {
|
||||
"bytes": 1242,
|
||||
"sha256": "2d7ba83836ec93ad6ee7104a26754cd42edffda055c5fa7305926557827b3807"
|
||||
},
|
||||
"native-3/finished.json": {
|
||||
"bytes": 354,
|
||||
"sha256": "e6853bb83c949db2828bedc8d7763012673ccb378f8172cbee6dfeb7efa3043d"
|
||||
},
|
||||
"native-3/reopened-saved.arcadia": {
|
||||
"bytes": 9705,
|
||||
"sha256": "ea05d0e409687c7943dda0b93bc34036eb524f5f5033b912e71ad2eaf643a158"
|
||||
},
|
||||
"native-3/started.json": {
|
||||
"bytes": 891,
|
||||
"sha256": "776ea6df056bf0204c1db8849e59e46fde961abee98823e8fdb86e95faa197ea"
|
||||
},
|
||||
"native-3/stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"native-3/stdout.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"native-baseline.arcadia": {
|
||||
"bytes": 9662,
|
||||
"sha256": "2dae785d63a940094d8052f3dcddcb988c024b38df9780e026bccd516264dbfe"
|
||||
},
|
||||
"native-check.json": {
|
||||
"bytes": 1247,
|
||||
"sha256": "70f2fce9d03809ca178c2e94f4bd9802168c6c93e920f091f5960d7c165a4e1d"
|
||||
},
|
||||
"native-check.py": {
|
||||
"bytes": 2210,
|
||||
"sha256": "5c1f6aaa22c2c1d5abc0339ab0186f65e0ef3e58555681cb7a0a493024a875a7"
|
||||
},
|
||||
"native-launch.py": {
|
||||
"bytes": 2545,
|
||||
"sha256": "c6338d2234db3453bccaa65c9e2df3b48b3eadc206605762afc11fd2ad11b895"
|
||||
},
|
||||
"native-observations.md": {
|
||||
"bytes": 5929,
|
||||
"sha256": "878369a46ed0ef58d92b00ca008bcb1729fee216a5a7aeb7b637130872ed5b42"
|
||||
},
|
||||
"native-source-review.md": {
|
||||
"bytes": 6540,
|
||||
"sha256": "4216547e3aa8902f7c9b6f66e5d2ef8f10f50d3b815b2abf9398edd8b942ab0c"
|
||||
},
|
||||
"package-audit/audit.py": {
|
||||
"bytes": 7776,
|
||||
"sha256": "bb2a3877d25952814654652f1f5b25f3e5e2ae95063c0c244b80e07c06a22580"
|
||||
},
|
||||
"package-audit/build-link-records.json": {
|
||||
"bytes": 30112,
|
||||
"sha256": "9e52981badd31675982c6d358cb193d1d074cff777a2974eef3109b8a90f78d7"
|
||||
},
|
||||
"package-audit/build-link.py": {
|
||||
"bytes": 3781,
|
||||
"sha256": "e56e98a1502033fb9349e8313e075083c78ff0ca0c65eea0f619ca21d701a2b3"
|
||||
},
|
||||
"package-audit/result.json": {
|
||||
"bytes": 3458,
|
||||
"sha256": "937eefdffdf70159d4aa58b7042c47e10bf823d96bdf082acecb7ff92e2937d0"
|
||||
},
|
||||
"package-metadata/README.md": {
|
||||
"bytes": 1902,
|
||||
"sha256": "597cfb8da873e019d2658420f18ec059f0185fa9106ff9eafe934dfdd6ed266b"
|
||||
},
|
||||
"package-metadata/SHA256SUMS.txt": {
|
||||
"bytes": 67036,
|
||||
"sha256": "5fb408d7279f733daddf84ae59e4187c935d40738e420ad5bb7fa01641cbc693"
|
||||
},
|
||||
"package-metadata/START-HERE.txt": {
|
||||
"bytes": 676,
|
||||
"sha256": "a549295cf57ac73673dc4fa6106463450f982122793cb9c7135ce4fc7087e9ed"
|
||||
},
|
||||
"package-metadata/documentation-check.json": {
|
||||
"bytes": 43,
|
||||
"sha256": "18a35f7022d6c180c42ad4fd7c7010e494bdff0d2ca395efac84ac545fe23627"
|
||||
},
|
||||
"package-metadata/package.json": {
|
||||
"bytes": 76306,
|
||||
"sha256": "daf412ef5bd6facfe471181cc4c57203c25bc2b952e533d0e170a06302d0ea32"
|
||||
},
|
||||
"package-provenance-review.md": {
|
||||
"bytes": 6178,
|
||||
"sha256": "9ce825b952172b8e6e3ab8652ded4e6d5ab8666fbd55ebc9a7d4dc5d3b02ec2d"
|
||||
},
|
||||
"picker-policy-review.md": {
|
||||
"bytes": 5213,
|
||||
"sha256": "58d0bfb810762b46660748436e7ca69235a834cae62bd1a960b6158881b4154f"
|
||||
},
|
||||
"server-readback-check.json": {
|
||||
"bytes": 372,
|
||||
"sha256": "160a5978a49d1765febe6fcca31c0dbf604d6275a4f4c78160c04f83b6243859"
|
||||
},
|
||||
"server-readback-check.py": {
|
||||
"bytes": 2850,
|
||||
"sha256": "4e20463f5b62f83e0908a7deb1204d37b2e89979be6c1dc06b4ea7daa7569820"
|
||||
},
|
||||
"server-review.md": {
|
||||
"bytes": 4800,
|
||||
"sha256": "bd02d4b12a29a6b71ec91f381073dde736e887793c57ea5127e5313088ede167"
|
||||
},
|
||||
"server-smoke/01.request.http": {
|
||||
"bytes": 72,
|
||||
"sha256": "98a7941518fa378830e47e212bcab4500ab3ae951d13b79911acc92e61742b08"
|
||||
},
|
||||
"server-smoke/01.response.http": {
|
||||
"bytes": 219,
|
||||
"sha256": "0cc33f39df17d6b4a5ca28402b8719455696a694e385e1898cc7ce403d2f364f"
|
||||
},
|
||||
"server-smoke/02.request.http": {
|
||||
"bytes": 79,
|
||||
"sha256": "52cab473c448bd13e88e2c866e05071c5ebba40058db73ced7fb37779683e4e7"
|
||||
},
|
||||
"server-smoke/02.response.http": {
|
||||
"bytes": 349010,
|
||||
"sha256": "faa794207009a9a2c7988e2b49f1ab07c0eac68c09de9baa96f2054aed8a8c16"
|
||||
},
|
||||
"server-smoke/03.request.http": {
|
||||
"bytes": 474,
|
||||
"sha256": "a24ed595021750bc44ece5c2d1366b56bfa86cf011c112ab2871107c3da0cc11"
|
||||
},
|
||||
"server-smoke/03.response.http": {
|
||||
"bytes": 535,
|
||||
"sha256": "16c3b7e6acca0d71cb2b20641fa8038c51329201bb4c9db78b35d8e3be26d854"
|
||||
},
|
||||
"server-smoke/04.request.http": {
|
||||
"bytes": 112,
|
||||
"sha256": "41c7650b095643b62e8e6024047dac7a24221859c4697257c0480864b186ed41"
|
||||
},
|
||||
"server-smoke/04.response.http": {
|
||||
"bytes": 1070,
|
||||
"sha256": "f8d46feb5f1fed3d336cfefb2c47b1cbad3108c80154a2f17e251d4ea081d88c"
|
||||
},
|
||||
"server-smoke/05.request.http": {
|
||||
"bytes": 127,
|
||||
"sha256": "0350f3adcfc326d86dbc6c73a9691027093e788ebc73478175ea824fbb347a6c"
|
||||
},
|
||||
"server-smoke/05.response.http": {
|
||||
"bytes": 579,
|
||||
"sha256": "24a3205e9ecfeef972e71dae666634d65d3892c644e63556171bc014e49f2b2c"
|
||||
},
|
||||
"server-smoke/06.request.http": {
|
||||
"bytes": 556,
|
||||
"sha256": "fc44c92bb375c80bd87fc2d8a5e2897481dba4fa05a2f9524a9b9277c1d01b7f"
|
||||
},
|
||||
"server-smoke/06.response.http": {
|
||||
"bytes": 1219,
|
||||
"sha256": "579d76a9f6bd3023aa3e1bb5c3b01baad83a40f2a2d7be6c177368fe4e4d436d"
|
||||
},
|
||||
"server-smoke/07.request.http": {
|
||||
"bytes": 561,
|
||||
"sha256": "33f43063a9a52dbe65f9b0a571a048bb351463098572a76339e9eb893fd2c10c"
|
||||
},
|
||||
"server-smoke/07.response.http": {
|
||||
"bytes": 450,
|
||||
"sha256": "9ec589caf67f59b80488ff308572ea67a7acc60d819b8342cc4506df50be97cf"
|
||||
},
|
||||
"server-smoke/08.request.http": {
|
||||
"bytes": 112,
|
||||
"sha256": "41c7650b095643b62e8e6024047dac7a24221859c4697257c0480864b186ed41"
|
||||
},
|
||||
"server-smoke/08.response.http": {
|
||||
"bytes": 1066,
|
||||
"sha256": "46e90ec83c926b2c702f8901a53da4e4a1a1943d25cc778c8e794b6876044cd9"
|
||||
},
|
||||
"server-smoke/09.request.http": {
|
||||
"bytes": 72,
|
||||
"sha256": "98a7941518fa378830e47e212bcab4500ab3ae951d13b79911acc92e61742b08"
|
||||
},
|
||||
"server-smoke/09.response.http": {
|
||||
"bytes": 219,
|
||||
"sha256": "80c9c431a2fdd254ae292358cbf8fb15ab50a09357c3a8c05bd9f2a155e12136"
|
||||
},
|
||||
"server-smoke/10.request.http": {
|
||||
"bytes": 112,
|
||||
"sha256": "41c7650b095643b62e8e6024047dac7a24221859c4697257c0480864b186ed41"
|
||||
},
|
||||
"server-smoke/10.response.http": {
|
||||
"bytes": 1066,
|
||||
"sha256": "12acd31db3adb0ef07bea483502f1b499e0bfbeda3a980366bcbed21a70ca83d"
|
||||
},
|
||||
"server-smoke/11.request.http": {
|
||||
"bytes": 127,
|
||||
"sha256": "0350f3adcfc326d86dbc6c73a9691027093e788ebc73478175ea824fbb347a6c"
|
||||
},
|
||||
"server-smoke/11.response.http": {
|
||||
"bytes": 577,
|
||||
"sha256": "07bc56fb0a7b1532f720c64e1444f95eb085578894d42c17fdcb56b73fa5f495"
|
||||
},
|
||||
"server-smoke/accepted-envelope.json": {
|
||||
"bytes": 1051,
|
||||
"sha256": "933a78f4cc01424942e37f146c679ff9a59ed470643ebae94553f9b51386dace"
|
||||
},
|
||||
"server-smoke/edited.arcadia": {
|
||||
"bytes": 249,
|
||||
"sha256": "e59acb5ed01e55057096b22a39667b40ddddb97227395d04c281686a73c6a14c"
|
||||
},
|
||||
"server-smoke/first.stderr.log": {
|
||||
"bytes": 120,
|
||||
"sha256": "3bcc24b254215618fd5aea59360a1a7b8f3c7eba3d98063f8ebd8b4234e971f6"
|
||||
},
|
||||
"server-smoke/first.stdout.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"server-smoke/help.stderr.txt": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"server-smoke/help.stdout.txt": {
|
||||
"bytes": 350,
|
||||
"sha256": "99c5cb07d451c6da829b835b66fce92ce5c2529508c8053030123df704d0610e"
|
||||
},
|
||||
"server-smoke/original.arcadia": {
|
||||
"bytes": 251,
|
||||
"sha256": "1f6b88cbcc3ac12995192feca91e07b9f6d536f2d21d0df6f42aa08f5c745ba9"
|
||||
},
|
||||
"server-smoke/package-provenance.json": {
|
||||
"bytes": 76305,
|
||||
"sha256": "bcd528f4bc722a89bdf565d46c1e2ac474ab16b7a17512365c194c8da1319d49"
|
||||
},
|
||||
"server-smoke/restart.stderr.log": {
|
||||
"bytes": 120,
|
||||
"sha256": "3bcc24b254215618fd5aea59360a1a7b8f3c7eba3d98063f8ebd8b4234e971f6"
|
||||
},
|
||||
"server-smoke/restart.stdout.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"server-smoke/result.json": {
|
||||
"bytes": 4731,
|
||||
"sha256": "1e564b40fd65a7de3d9c251f239f67586e8a2060f541b7fa06451f5e7cb375f7"
|
||||
},
|
||||
"server-smoke/run.py": {
|
||||
"bytes": 9122,
|
||||
"sha256": "62f173e6dd284589639ca85029b3d343e73f6f4548193a203db66769ae12e018"
|
||||
},
|
||||
"server-smoke/store/.arcadia.lock": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"server-smoke/store/230d7234-8150-4252-a4bd-85a3b7b2308c.json": {
|
||||
"bytes": 810,
|
||||
"sha256": "c928995daf0c1ff3963850aba9ad533196423fa2112ad99554758825f73fc5af"
|
||||
},
|
||||
"server-smoke/version.stderr.txt": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"server-smoke/version.stdout.txt": {
|
||||
"bytes": 21,
|
||||
"sha256": "af82a1126f98794babaa173139764cadbfb5143a235f9a887ef70d18d00a0d91"
|
||||
}
|
||||
},
|
||||
"archive": {
|
||||
"bytes": 3425348,
|
||||
"sha256": "cb084be5f316f1b3be45bc5493fe0cbd6076052198c09f9dbac441b8f2588e63"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
# Downloaded Windows Studio: direct native observations
|
||||
|
||||
Codex-9e8r6t /root, 2026-09-24. Tested the unmodified fresh extraction of release 7 asset 25 on Windows 11 build 26200. Product source is `715036e132677dd2bc2fb37ed316d93dc9987aec`; no Cargo/build or Linux operation occurred in this exercise. This is independent of the producer's machine and GUI exercise.
|
||||
|
||||
## Launch and workflows
|
||||
|
||||
`native-launch.py` launched the packaged executable directly with PATH `C:\Windows\System32;C:\Windows`, removed development-related environment variables, and used unrelated working directory `C:/arcadia-package-qa-9e8r6t`. It retained the ordinary Windows user profile, including existing recovery entries; this is not a fresh-OS/profile test. Python only orchestrated the launch and logging. The original extracted bundle was not edited. A whole companion kit and example directory were copied to the working directory before opening the copied State model. Both application sessions closed normally with Alt+F4, exit 0, empty stdout/stderr and unchanged executable/runtime hashes.
|
||||
|
||||
Original screenshots and their timestamps/window identity/accessibility trees are in `native-2/` and `native-3/`. Each capture includes a full-window JPEG, plus a tiny icon image in most captures. Native actions used Computer Use, without application-state injection. Visual acceptance below is bounded to the actual observed sequence.
|
||||
|
||||
| Captures | Observed behavior |
|
||||
| --- | --- |
|
||||
| native-2 01–04 | Home launched; bundled water-pressure walkthrough loaded from the unrelated cwd (94 objects, 62 links, 1 model check). |
|
||||
| native-2 05–09 | Opened copied State fixture; selected System perspective, readiness view 03 and Activate transition; Actions → Add bend displayed an additional square handle. |
|
||||
| native-2 10–11 | Undo removed the added handle; Redo restored it. These two observations are visual, not saved full-file snapshots. |
|
||||
| native-2 12–17 | Dragged new square downward; Save, Undo movement/Save, Redo movement/Save. Whole-source checks establish one additional waypoint, original (500,310) retained, added point moving (526,310) → (530,385), and exact movement Undo/Redo. |
|
||||
| native-2 18–21 | Switched to untouched reference view 04, then returned to edited view 03. Reference layout remained distinct; the authored edit returned. Whole-file comparison also leaves every reference-view byte unchanged. |
|
||||
| native-2 22–29 | Opened Edit transition and its source-state dropdown without changing fields. First Escape closed the dropdown and kept the form. Second Escape kept the form too. Explicit Cancel closed it; saving preserved the complete edited source exactly. |
|
||||
| native-3 01–06 | Fresh process; reopened the working model, returned to System/State view 03, selected Activate. Both authored handles and downward bend persisted. Save produced identical complete source bytes. |
|
||||
| native-3 07–08 | Opened built-in Engineering guide and its States, modes & transitions topic; guide content rendered normally. No external network-disconnection test was performed. |
|
||||
|
||||
`native-check.py` is a read-only full-byte evaluator. It starts with the independently downloaded companion baseline and allows only one exact addition in Activate's waypoint list in readiness_view. Consequently semantics, IDs, node positions, endpoint attachments, labels, other routes and all other views retain their original bytes. Its output is `native-check.json`. The five accepted saved snapshots are retained. A separate source reviewer checks the oracle and key original images in `native-source-review.md`.
|
||||
|
||||
## Scope and observations that are not pass claims
|
||||
|
||||
The filename `native-2/26-second-escape-cancels-form` records the intended probe, not its outcome. Captures 26 and 27 show the form still open. Source review in `picker-policy-review.md` confirms that ordinary State edit drafts use explicit Cancel; #35 retains existing surrounding Escape policies. No second-Escape cancellation or direct inspection of the history stack is claimed. After explicit Cancel, exact source preservation was checked; no fields had been edited in that form.
|
||||
|
||||
At 56% Fit, this fixture's transition labels are small and crowded. That limits readability and remains within the existing label/layout follow-up; this run does not establish broad diagram ergonomics, accessibility, label clarity or aggregate editing acceptance. The fixture intentionally reports 12 model checks (14 objects/9 links); the modeling issues were not fixed as part of a presentation-only check. This exercise does not cover all release-checklist cases; producer and other reviewers retain their separate scopes.
|
||||
|
||||
The first launcher invocation (`native-1`) failed before product startup because the copied environment dictionary used the wrong case for SystemRoot. The helper was corrected to read the case-insensitive original environment; the empty native-1 directory contains no run evidence and is excluded. File-dialog automation needed direct visible Filename entry after UIA set_value was unsupported. On reopening, an undeclared JavaScript local caused one tool call to fail before its action; declaration then succeeded. These are harness/tool errors, not product crashes. Raw successful native-2/native-3 captures and receipts are preserved without renaming or overwriting.
|
||||
|
||||
No release/tag changes or publication are performed by this QA branch. Codex-956atf owns release admission and publication.
|
||||
|
||||
Parent read-only server evidence reconciliation initially used Python's Windows default text decoding for accepted-envelope.json and failed equality on the Unicode comment. Explicit UTF-8 decoding made the saved HTTP/envelope/store comparison pass. No runtime request, product file, or captured source was changed; `server-readback-check.py` and its result preserve the corrected evaluator. The original packaged-server runtime smoke itself passed on its first run.
|
||||
@@ -0,0 +1,53 @@
|
||||
# Independent native source and screenshot review
|
||||
|
||||
2026-09-24. Reviewed captured package-QA evidence in `C:/ar-prerelease-qa-9e8r6t/.local/package-qa`, for the run receipts identifying source `715036e132677dd2bc2fb37ed316d93dc9987aec`. No GUI control, application launch, build, Git operation or captured-evidence modification. This file is the only written artifact. This is bounded review of the State bend/picker/reopen trial, not general release acceptance.
|
||||
|
||||
## Complete-file oracle: PASS
|
||||
|
||||
Baseline: `download-1/companions-21/prerelease-human-checks-20260924/state/native-fixture.arcadia`, 9662 bytes, SHA256 `2dae785d63a940094d8052f3dcddcb988c024b38df9780e026bccd516264dbfe`.
|
||||
|
||||
Using the bundled Python standard library in read-only mode, I compared every byte of each captured file against the original baseline with exactly one expected replacement. The unique replacement target is:
|
||||
|
||||
```text
|
||||
edge @activate; waypoints [{ x 500; y 310; }]
|
||||
```
|
||||
|
||||
The expected replacement retains that original waypoint and appends exactly this new serialized object (LF line breaks):
|
||||
|
||||
```text
|
||||
edge @activate; waypoints [{ x 500; y 310; }, {
|
||||
x X.0;
|
||||
y Y.0;
|
||||
}]
|
||||
```
|
||||
|
||||
The target occurs once, inside `diagram readiness_view`, ID `ea202922-0033-4000-8000-000000000200`. All five full-file comparisons passed, without normalizing whitespace, line endings, strings or numbers. My initial compact single-line serialization expectation differed only in the inserted object's formatting; after explicitly accounting for the actual multiline decimal serialization above, every byte of the complete expected files matched.
|
||||
|
||||
| Captured file | New point | Bytes | SHA256 |
|
||||
| --- | --- | --- | --- |
|
||||
| `native-2/bend-saved.arcadia` | (530,385) | 9705 | `ea05d0e409687c7943dda0b93bc34036eb524f5f5033b912e71ad2eaf643a158` |
|
||||
| `native-2/move-undo-saved.arcadia` | (526,310) | 9705 | `7f1fc18265a79b7d452e4a3de3f17671684e38c0f727cbdec15833196f46f114` |
|
||||
| `native-2/move-redo-saved.arcadia` | (530,385) | 9705 | `ea05d0e409687c7943dda0b93bc34036eb524f5f5033b912e71ad2eaf643a158` |
|
||||
| `native-2/after-cancel-saved.arcadia` | (530,385) | 9705 | `ea05d0e409687c7943dda0b93bc34036eb524f5f5033b912e71ad2eaf643a158` |
|
||||
| `native-3/reopened-saved.arcadia` | (530,385) | 9705 | `ea05d0e409687c7943dda0b93bc34036eb524f5f5033b912e71ad2eaf643a158` |
|
||||
|
||||
Consequently, all semantic declarations, IDs, references, names, comments, transition endpoints/kind/guard/effects, original waypoint, route label/attachments, other routes, nodes and all other views remain byte-for-byte original. The moved, redone, explicit-cancel-saved and fresh-reopen-saved files are mutually byte-identical. This is stronger than checking selected parsed fields; it does not rely on the application's own serializer as the oracle for unrelated content. No semantic parser or hidden model/history introspection was run.
|
||||
|
||||
## Original screenshots inspected
|
||||
|
||||
I opened these full 1605x872 original `-1.jpg` captures using view_image, rather than the 16x16 companion thumbnails:
|
||||
|
||||
- `native-2/09-add-bend-1.jpg`, `10-undo-added-bend-1.jpg`, `11-redo-added-bend-1.jpg`: selected Activate route visibly has two square bend handles, then one, then two; status text correspondingly shows the State update, model change undone, and model change redone. This supports visible add/undo/redo behavior, without proving internal history depth or exact command count.
|
||||
- `native-2/14-undo-bend-move-1.jpg`, `16-redo-bend-move-1.jpg`: the added handle returns beside the original handle on the upper row, then moves below it again; status text shows undone/redone. The exact coordinates and preservation claims come from the full-file oracle, not pixel measurement.
|
||||
- `native-2/19-reference-view-1.jpg`: the picker identifies “04 Readiness — untouched reference”; the selected Activate route has no authored square bends. Other-view preservation is independently established by the source oracle.
|
||||
- `native-2/24-transition-source-picker-1.jpg`: the Edit transition form is present and the source-state dropdown is open. `25-first-escape-picker-only-1.jpg`: dropdown closed, form retained with Ready, Active, External and crew_assigned visible. `26-second-escape-cancels-form-1.jpg`: form is still present, despite that capture's optimistic filename. The retained evidence must not be cited as second-Escape cancellation. Its actual content matches the existing explicit-Cancel policy explained in `picker-policy-review.md`.
|
||||
- `native-2/28-explicit-cancel-1.jpg`: form is closed and the moved route remains. `after-cancel-saved.arcadia` confirms no accepted source change after cancel. This does not directly prove a no-op on internal undo/redo stacks.
|
||||
- `native-3/05-persisted-bend-selected-1.jpg`: the reopened “03 Readiness — edit attachments” view shows both square handles and the lower moved bend, with the Activate transition selected. `native-3/08-state-guide-topic-1.jpg`: Engineering guide is open on “States, modes & transitions” with readable workflow content.
|
||||
|
||||
The route labels remain small and crowded at the captured 56% scale, especially in the reference view. These captures do not establish general diagram readability or accessibility. The evidence remains useful for the bounded interaction/source checks above.
|
||||
|
||||
## Run records and limits
|
||||
|
||||
Read `started.json` and `finished.json` for both runs. They record the same packaged binary/source identity, distinct process IDs (8188 then 6904), separate start times, exitCode 0 and unchanged binary/runtime hashes. The run-3 start follows run-2 finish. I independently read all four stdout/stderr files: each is zero bytes with SHA256 `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`. I did not rehash the executable/runtime or independently observe the Alt-F4 key; normal termination and identity assertions are the retained launcher receipts.
|
||||
|
||||
No material contradiction was found between the saved source, the inspected screen states and the bounded trial description. The one evidence-label correction is capture 26: its filename says cancellation, but the form demonstrably remains. The explicit Cancel and subsequent saved/reopened equality are established separately. This review supports exact saved presentation change, reversible visible outcomes, untouched semantics/other views, picker-only first Escape, explicit form cancellation, and fresh-process persistence. It does not prove internal history depth, every intermediate in-memory state, complete State editing, or broader prerelease/native acceptance.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Downloaded prerelease package provenance review
|
||||
|
||||
2026-09-24. Bounded independent static audit of draft release 7, Studio asset 25 and checksum asset 26, downloaded into `download-1`. No material package-integrity, build-linkage, or static portability defect found. Both packaged executables match the preserved individual Cargo-identified build receipts for exact source 715036e; this review does not establish native acceptance.
|
||||
|
||||
## Reproduction and exact package
|
||||
|
||||
Run `python -B .local/package-qa/package-audit/audit.py` from this worktree. The stdlib audit reuses only the read-only document checker from `scripts/package-artifacts.py`; it does not launch shipped executables, invoke Cargo, or contact a network. Machine-readable results are in `package-audit/result.json`. Initial read-only Git checks reported clean tracked work and HEAD `715036e132677dd2bc2fb37ed316d93dc9987aec`.
|
||||
|
||||
The Studio ZIP is 34,168,661 bytes, SHA256 `5554e32533e3cb2c33fb4143a5a0902733d5a8d47577303cb2842d268e7bc76d`, matching the downloaded checksum and download receipt. All 565 archived files equal their extracted bytes and recorded pins. Names have no traversal, absolute paths, backslash ambiguity, or case-insensitive duplicates; extraction has no extra files. All 564 `SHA256SUMS.txt` entries pass, covering every file except that checksum inventory itself. All 559 `package.json` input hashes pass.
|
||||
|
||||
The supplied BuildEvidence and release snapshot identify source `715036e132677dd2bc2fb37ed316d93dc9987aec`, development profile, Rust 1.98.1, and `x86_64-pc-windows-gnullvm`. Both executable hashes match the actual archive bytes:
|
||||
|
||||
- Studio: `2c03bd6cc3f1110c219e4f57ab94874a121590f83779239a93289b7170664399`.
|
||||
- Server: `6cebacc117e46fdab023c6402a5cebd6929fb55993ae8ff6b89cd1c6c1170237`.
|
||||
|
||||
The four BuildEvidence references (mandatory gate, source manifest, environment, artifact relocation) retain producer-local path labels. Their bytes are independently available in versioned gate evidence linked by the downloaded release snapshot: `206f3b969482241e01e2dfc6be955caf31747b89:harness/prerelease37-windows-gates-20260924/final04-complete`. After the parent fetched those objects, this reviewer read them without checkout or mutation. `package-audit/build-link.py` verifies the complete 6,588,421-byte evidence ZIP (SHA256 `7cead0b6aa36a6af8fc9f8987186bfe0decd8fa2ebab094fc45387ae9daea632`), all 462 member hashes, and exact agreement with all four BuildEvidence pins. Results and pertinent original receipt records are retained in `package-audit/build-link-records.json`.
|
||||
|
||||
Both individual builds have exit 0 and unchanged input captures identical to the final04 source manifest. Their source, target, and profile agree with the package; the preserved output size/hash equals each actual downloaded executable. The relocation records' Cargo compiler-artifact objects exactly occur in the corresponding pinned raw Cargo JSON logs, identify the appropriate non-test binary target and output path, and both streams record successful build completion. The aggregate summary records a passed gate at the same source. This bridges the package to the owner's already admitted source/build evidence; it does not rerun the broader 3,709-input source audit. Supplemental combined-build output hashes differ and are correctly excluded from the package identity claim. Keep the versioned evidence link in the final release so recipients can resolve the historical local labels.
|
||||
|
||||
## Runtime and offline content
|
||||
|
||||
An independent PE32+ parser confirmed x86-64 architecture and reproduced every recorded import for Studio, Server, and `libunwind.dll`. The only ordinary non-system dependency is the shipped `libunwind.dll`, whose own imports resolve to Windows components/API sets. All three delay-import directories are empty. The runtime hash matches package inputs and notice inventory: `aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a`. Dynamic graphics loading, driver compatibility, and execution without development PATH remain runtime checks owned by the parent; static imports cannot establish them.
|
||||
|
||||
All 18 checked local Markdown/reST/HTML file links resolve. The two HTML specifications load no external script/style/image resources and contain inline styling. All 66 shipped documentation/example/deployment/license source files checked match this exact clean source checkout (README maps to `scripts/package-readme.md`). This includes the complete tracked `examples/release1` content. Built-in Help behavior and actual example opening require the parent's separate native exercise.
|
||||
|
||||
The notice inventory contains 268 dependency packages. All 489 referenced notice paths/hashes match shipped bytes; Cargo.lock and 529 recorded local source/build-input hashes match the exact checkout with no mismatch. Rust and libunwind notices are present and pinned. This verifies the recorded notice closure, not an independent universal license audit, registry recompilation, or proof of embedded asset completeness.
|
||||
|
||||
## Launch guidance and scope
|
||||
|
||||
Read START-HERE, package README, Windows packaging guide, server launch/configuration guidance, and preview human checks. They consistently require keeping the bundle together and the runtime DLL beside both executables; local modeling needs no Rust installation or server. They distinguish packaged executable launch from Cargo/Docker recipes requiring a separate source checkout, and recommend keeping server data outside the application folder. The Windows guide explicitly requires fresh extraction, unrelated working directory, restricted process PATH, actual workflows, logs/exit checks, and acknowledges a second machine as stronger portability evidence.
|
||||
|
||||
The human checklist presents expected exercises rather than claiming those exercises passed. It preserves aggregate deletion and broader acceptance limitations. The downloaded release snapshot remains draft/prerelease with packaged runtime acceptance pending; this audit does not upgrade that state. No GUI/server execution, Cargo, Linux checks, product/source changes, Git mutation, or network activity occurred. Only the requested local review/audit artifacts were written.
|
||||
@@ -0,0 +1,27 @@
|
||||
# State transition picker Escape policy review
|
||||
|
||||
2026-09-24. Read-only source/policy analysis in the package-QA checkout identified by the parent as `715036e`. Read AGENTS.md, PROJECT_GOAL.md (relevant keyboard/cancellation search), `docs/preview-human-checks.md`, `harness/picker-escape-20260923.md`, the combined integration review, and actual State form/App/Escape-wrapper source and relevant tests. No Cargo, Git, GUI or network operations. The native observation (first Escape closes dropdown, second retains State transition form, capture 26) is parent-reported; I did not inspect that capture.
|
||||
|
||||
## Conclusion
|
||||
|
||||
The reported behavior is consistent with the implemented ordinary State Edit transition policy. It is **not evidence of a regression in issue 35**. The current ordinary State draft has an explicit Cancel action; a generic second Escape is not wired to discard it. The checklist does not establish a new universal second-Escape cancellation requirement. This conclusion distinguishes the actual implementation and selected #35 contract from a broader usability preference; it does not claim that every modal's Escape behavior is consistent or ideal.
|
||||
|
||||
## Actual call paths
|
||||
|
||||
- `crates/oa-desktop/src/behavior/states.rs:247-282`: `Event::Edit(id)` constructs the editable transition draft in `states.draft`. The form's From state / To state pickers are at `:454-455`. The word source here denotes the transition endpoint; this is not a nested behavior source-authoring form.
|
||||
- `states.rs:283` explicitly handles `Event::Cancel` by clearing the draft through acknowledge_commit. The visible Cancel button emits that event at `:576`. `behavior.rs:938-946` recognizes cancellation of the currently pending State draft and acknowledges it without returning a model command. The independent behavior-form test also checks that explicit Cancel discards the pending form (`behavior.rs:3560`).
|
||||
- `behavior.rs:908-914` defines `source_active` from creation, Scenario and Process source forms; it does not include an ordinary State transition edit. `creation.has_pending()` is a separate editor from `states.draft`.
|
||||
- `app.rs:2742-2760` handles generic Message::Escape: source_back first, then source_active cancellation, then behavior.creation cancellation, then State AdjustAttachment tool cancellation. It has no ordinary State draft cancellation branch. If an uncaptured second Escape reaches this handler, it can retire transient canvas state, but it does not clear the transition draft or commit model/source/history changes.
|
||||
- The #35 root wrapper (`app/escape.rs:18-32`) forwards captured focused-input Escape only for the existing listed workflows: behavior.creation, diagram usages, behavior source forms and specified Text workflows, plus the separate architecture callback. It does not add ordinary State transition forms to that policy. Its popup preflight lets an open dropdown consume Escape before those surrounding actions (`:101-140`). The global subscription separately ignores captured Escape (`app.rs:1316-1320`). Thus both captured and uncaptured paths are compatible with the reported second-Escape retention.
|
||||
|
||||
## Contract and test limits
|
||||
|
||||
`harness/picker-escape-20260923.md:10-15` explicitly requires popup dismissal without changing the surrounding draft/model/source/history/selection/camera, followed by the existing surrounding workflow's policy on a later Escape. Its design preserves existing activation predicates and message priorities. The combined review repeats “next Escape follows existing modal priority” (`harness/reviews/prerelease37-integration-20260924.md:38`).
|
||||
|
||||
`docs/preview-human-checks.md:45-47` says a subsequent Escape follows the form's ordinary cancellation behavior. It does not say every form closes on that key. Read against the actual selected #35 contract, it should not be used to invent a second-Escape cancellation oracle for this State editor. If polishing the checklist later, “follows the surrounding workflow's existing Escape policy; use explicit Cancel where that form requires it” would remove the ambiguity without changing behavior.
|
||||
|
||||
`app/state_picker_escape_tests.rs` exercises the actual State missing-element picker, including close/reopen/place and exact unchanged document/selection/camera/history on dismissal; it is not a test that second Escape closes the transition editor. The composed pending-form cases in `app/escape/tests.rs` use behavior.creation/source workflows, whose existing Escape policy does cancel or go back. Those test results should not be generalized to ordinary State editing.
|
||||
|
||||
## Recommended package-QA disposition
|
||||
|
||||
Record first-Escape popup dismissal with unchanged transition form as the observed #35 success for this native control. Record second-Escape form retention as compatible with its current explicit-Cancel path, rather than a product regression inferred from the generic checklist. Use the visible Cancel button, verify the form closes and accepted model/source/history remain unchanged, and continue package QA. A future request to make ordinary State forms Escape-cancelable would be a separate product-policy change requiring consistent draft-loss/focus semantics and its own verification.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Independent packaged server review — draft release 7
|
||||
|
||||
**PASS for the bounded Windows packaged-server HTTP/restart smoke.** 23 explicit checks passed on Windows 11 build 26200. The helper exited 0. This is runtime evidence for the downloaded packaged server, not a source build, native desktop acceptance, or release publication.
|
||||
|
||||
## Identity and execution isolation
|
||||
|
||||
- Reviewed source identity supplied by package build evidence: `715036e132677dd2bc2fb37ed316d93dc9987aec`. Package identifies `dev` profile, `x86_64-pc-windows-gnullvm`, rustc `1.98.1 (48a229cea 2026-09-01)`. These source/compiler/profile statements remain distributor assertions, not independently rebuilt provenance.
|
||||
- Downloaded Studio ZIP: `ArcadiaStudio-0.2.0-preview.integrated.20260924-x86_64-pc-windows-gnullvm.zip`, 34,168,661 bytes, independently rehashed SHA-256 `5554e32533e3cb2c33fb4143a5a0902733d5a8d47577303cb2842d268e7bc76d`.
|
||||
- Executed only its extracted `arcadia-server.exe`, SHA-256 `6cebacc117e46fdab023c6402a5cebd6929fb55993ae8ff6b89cd1c6c1170237`. `--version` returned `arcadia-server 0.2.0`; version/help exited 0. Bundled `libunwind.dll` hash `aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a` is recorded.
|
||||
- Child environment is an explicit Windows runtime whitelist, with PATH exactly `C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem`. No inherited Rust/development PATH or server bearer token. Python orchestrates HTTP and process lifetime only; it supplies no server runtime library.
|
||||
- Working directory and fresh isolated store are under `.local/package-qa/server-smoke`; original extracted package files were not modified. Listener used newly available loopback port `127.0.0.1:61860`, never a non-loopback interface. No existing store or service was touched.
|
||||
|
||||
Literal helper launch:
|
||||
|
||||
```powershell
|
||||
& C:/Users/User/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/python.exe .local/package-qa/server-smoke/run.py
|
||||
```
|
||||
|
||||
Exact child argv arrays, environment, executable/runtime hashes, process IDs and exit results are in [server-smoke/result.json](server-smoke/result.json). The helper refuses a preexisting store, so reruns must use a fresh evidence directory rather than overwriting this run.
|
||||
|
||||
## Exercised behavior
|
||||
|
||||
1. Startup readiness returned 200. Served OpenAPI returned 200 and exactly equalled the packaged OpenAPI JSON contract.
|
||||
2. Imported the complete authored source bundle with stable model/activity IDs, an explicit Unicode comment and CRLF text. POST returned 201; GET preserved the entry filename and exact file text, UUIDs and comment. Server resource ID was independently allocated and distinct from the model ID.
|
||||
3. GET returned the same initial strong ETag; conditional source-project PUT changed only project name `Package QA original` to `Package QA edited`, returned changed=true, incremented revision exactly from 1 to 2 and returned a new ETag plus exact edited bundle.
|
||||
4. A second PUT with the stale revision-1 ETag and a distinctive rejected name returned `412 revision_conflict`. Subsequent GET equalled the accepted edited model/source pair exactly; the expected model was independently constructed by changing only its name in the original model.
|
||||
5. The acknowledged HTTP envelope exactly equalled the stored JSON envelope. The server was terminated, restarted from the same store and again passed readiness. Whole-envelope GET and source-project GET retained exact revision-2 ETag, all IDs, name, comment and CRLF text. Restart/readback did not change committed envelope bytes.
|
||||
|
||||
Resource: `230d7234-8150-4252-a4bd-85a3b7b2308c`; final revision 2; store SHA-256 `c928995daf0c1ff3963850aba9ad533196423fa2112ad99554758825f73fc5af`.
|
||||
|
||||
## Evidence and limits
|
||||
|
||||
[server-smoke/run.py](server-smoke/run.py) is the executable evaluator. Numbered `*.request.http` and `*.response.http` files contain literal requests/responses, including source bodies and ETags, without secrets. `original.arcadia`, `edited.arcadia`, `accepted-envelope.json`, isolated `store/`, copied `package-provenance.json`, help/version output and both process stdout/stderr logs are retained. Logs contain normal startup messages; no crash/error diagnostics were observed.
|
||||
|
||||
Both server processes were deliberately stopped with Windows TerminateProcess after completed, acknowledged requests (exit code 1 is the imposed termination result). This verifies restart recovery of acknowledged writes; **it does not establish graceful Ctrl+C shutdown, in-flight-write recovery or power-loss safety**. Both processes have been stopped. Authentication, remote networking/TLS, Linux/container operation, broad API semantics, concurrency/load and GUI behavior are outside this bounded run. No Cargo/build, source edits, Git mutations, Gitea messages or GUI operations occurred.
|
||||
Reference in New Issue
Block a user