Complete source 6 engineering workflows and preserve release validation evidence

This commit is contained in:
Codex
2026-09-06 21:49:04 -07:00
parent 2b2d2bc18b
commit 4b6b5fc197
290 changed files with 48271 additions and 1791 deletions
+43
View File
@@ -97,6 +97,7 @@ pub struct Document {
current_bytes: usize,
saved: Arc<SourceBundle>,
revision: u64,
view_index: std::cell::OnceCell<oa_core::view_options::ViewIndex>,
limits: ProjectLimits,
recovered_unsaved: bool,
}
@@ -126,6 +127,7 @@ impl Document {
future: Vec::new(),
saved: Arc::new(bundle),
revision: 0,
view_index: Default::default(),
limits,
recovered_unsaved: false,
})
@@ -135,6 +137,12 @@ impl Document {
&self.current.decoded.project
}
/// Semantic reachability is shared by every diagram at this accepted revision.
pub fn view_index(&self) -> &oa_core::view_options::ViewIndex {
self.view_index
.get_or_init(|| oa_core::view_options::ViewIndex::new(self.project()))
}
pub fn bundle(&self) -> &SourceBundle {
&self.current.bundle
}
@@ -220,6 +228,7 @@ impl Document {
// Source-position readers must reject their old revision even though
// changing the save location does not create an Undo transaction.
self.revision = self.revision.saturating_add(1);
self.view_index.take();
}
Ok(())
}
@@ -349,6 +358,7 @@ impl Document {
bytes: std::mem::replace(&mut self.current_bytes, previous.bytes),
});
self.revision = self.revision.saturating_add(1);
self.view_index.take();
true
}
@@ -361,6 +371,7 @@ impl Document {
bytes: std::mem::replace(&mut self.current_bytes, next.bytes),
});
self.revision = self.revision.saturating_add(1);
self.view_index.take();
true
}
@@ -382,6 +393,7 @@ impl Document {
retained = retained.saturating_sub(self.past.remove(0).bytes);
}
self.revision = self.revision.saturating_add(1);
self.view_index.take();
true
}
}
@@ -399,6 +411,37 @@ mod tests {
Document::from_project(Project::empty(), ProjectLimits::default()).unwrap()
}
#[test]
fn cached_view_index_tracks_accepted_creation_undo_and_redo() {
use oa_core::{Relation, RelationBody, RelationKind, view_options::ViewOptions};
let mut p = Project::empty();
let source = p
.add_element(Kind::Entity, Layer::Oa, "Team", None)
.unwrap();
let target = p
.add_element(Kind::Actor, Layer::Oa, "Dispatcher", None)
.unwrap();
let mut document = Document::from_project(p, ProjectLimits::default()).unwrap();
let id = Id::new_v4();
let options = ViewOptions::default();
let visible = |d: &Document| d.view_index().prepare(Layer::Oa, &options).includes(id);
assert!(!visible(&document));
document
.execute(Command::CreateRelation(Relation {
id,
alias: "radio".into(),
name: "Radio".into(),
description: String::new(),
body: RelationBody::new(RelationKind::CommunicationMean, source, target),
}))
.unwrap();
assert!(visible(&document));
assert!(document.undo());
assert!(!visible(&document));
assert!(document.redo());
assert!(visible(&document));
}
fn comment(bundle: &SourceBundle, text: &str) -> SourceBundle {
let mut changed = bundle.clone();
changed