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
@@ -0,0 +1,615 @@
//! Typed artifact lifecycle drafts; all authored values belong to an exact pair/facet.
use super::*;
use serde::{Deserialize, Serialize};
pub(super) const METADATA: [ArtifactFacet; 7] = [
ArtifactFacet::Name,
ArtifactFacet::Description,
ArtifactFacet::Owner,
ArtifactFacet::Relation,
ArtifactFacet::Uri,
ArtifactFacet::Revision,
ArtifactFacet::Fragment,
];
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub enum Raw {
Text(String),
Owner(String),
Relation(ArtifactRelation),
Optional { present: bool, text: String },
}
#[derive(Debug, Clone)]
pub enum Event {
Pick(Layer, Option<Choice>),
Search(String),
Stage,
Reserve,
Input(FacetSelector, Raw),
Description(FacetSelector, text_editor::Action),
}
#[derive(Default)]
pub struct Editor {
pub oa: Option<Choice>,
pub sa: Option<Choice>,
pub search: String,
pub seeds: BTreeMap<Id, ArtifactLink>,
pub drafts: BTreeMap<FacetSelector, Raw>,
pub descriptions: BTreeMap<FacetSelector, text_editor::Content>,
}
#[derive(Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Saved {
oa: Option<Id>,
sa: Option<Id>,
seeds: Vec<ArtifactLink>,
drafts: Vec<(FacetSelector, Raw)>,
}
impl Saved {
pub fn is_empty(&self) -> bool {
self.oa.is_none() && self.sa.is_none() && self.seeds.is_empty() && self.drafts.is_empty()
}
}
pub struct Proposal {
// The final selector addresses the actual mutation slot; the last selector
// retains the reviewed facet solely for conflict diagnostics.
pub slots: Vec<((Id, FacetSelector), Value, FacetSelector)>,
pub creations: Vec<ArtifactLink>,
pub candidates: BTreeSet<Id>,
}
pub(super) fn parts(facet: &FacetSelector) -> Option<(&KeyPair<Id>, ArtifactFacet)> {
if let FacetSelector::Artifact { keys, facet } = facet {
Some((keys, *facet))
} else {
None
}
}
pub(super) fn supported(facet: &FacetSelector) -> bool {
parts(facet).is_some()
}
pub(super) fn selector(keys: &KeyPair<Id>, facet: ArtifactFacet) -> FacetSelector {
FacetSelector::Artifact {
keys: keys.clone(),
facet,
}
}
pub(super) fn key(keys: &KeyPair<Id>, layer: Layer) -> Option<Id> {
if layer == Layer::Oa { keys.oa } else { keys.sa }
}
pub(super) fn field(facet: ArtifactFacet) -> Option<&'static str> {
Some(match facet {
ArtifactFacet::Presence => return None,
ArtifactFacet::Name => "name",
ArtifactFacet::Description => "description",
ArtifactFacet::Owner => "owner",
ArtifactFacet::Relation => "relation",
ArtifactFacet::Uri => "uri",
ArtifactFacet::Revision => "revision",
ArtifactFacet::Fragment => "fragment",
})
}
pub(super) fn slot(id: Id, facet: ArtifactFacet) -> (Id, FacetSelector) {
(
id,
selector(
&KeyPair {
oa: None,
sa: Some(id),
},
if facet == ArtifactFacet::Presence {
ArtifactFacet::Owner
} else {
facet
},
),
)
}
pub(super) fn observation(record: Option<&ArtifactLink>, facet: ArtifactFacet) -> Value {
match record {
None => Value::String("NotApplicable".into()),
Some(record) => {
serde_json::json!({"Value":serde_json::to_value(record).expect("Artifact")[field(facet).unwrap_or("owner")]})
}
}
}
pub(super) fn raw(record: &ArtifactLink, facet: ArtifactFacet) -> Option<Raw> {
Some(match facet {
ArtifactFacet::Presence => return None,
ArtifactFacet::Name => Raw::Text(record.name.clone()),
ArtifactFacet::Description => Raw::Text(record.description.clone()),
ArtifactFacet::Uri => Raw::Text(record.uri.clone()),
ArtifactFacet::Owner => Raw::Owner(record.owner.to_string()),
ArtifactFacet::Relation => Raw::Relation(record.relation),
ArtifactFacet::Revision => Raw::Optional {
present: record.revision.is_some(),
text: record.revision.clone().unwrap_or_default(),
},
ArtifactFacet::Fragment => Raw::Optional {
present: record.fragment.is_some(),
text: record.fragment.clone().unwrap_or_default(),
},
})
}
fn compatible(facet: ArtifactFacet, raw: &Raw) -> bool {
matches!(
(facet, raw),
(
ArtifactFacet::Name | ArtifactFacet::Description | ArtifactFacet::Uri,
Raw::Text(_)
) | (ArtifactFacet::Owner, Raw::Owner(_))
| (ArtifactFacet::Relation, Raw::Relation(_))
| (
ArtifactFacet::Revision | ArtifactFacet::Fragment,
Raw::Optional { .. }
)
)
}
fn write(record: &mut ArtifactLink, facet: ArtifactFacet, raw: &Raw) -> Result<(), String> {
match (facet, raw) {
(ArtifactFacet::Name, Raw::Text(v)) => record.name = v.clone(),
(ArtifactFacet::Description, Raw::Text(v)) => record.description = v.clone(),
(ArtifactFacet::Uri, Raw::Text(v)) => record.uri = v.clone(),
(ArtifactFacet::Owner, Raw::Owner(v)) => {
record.owner = v
.parse()
.map_err(|_| "Choose a valid explicit artifact owner identity.")?
}
(ArtifactFacet::Relation, Raw::Relation(v)) => record.relation = *v,
(ArtifactFacet::Revision, Raw::Optional { present, text }) => {
record.revision = present.then(|| text.clone())
}
(ArtifactFacet::Fragment, Raw::Optional { present, text }) => {
record.fragment = present.then(|| text.clone())
}
_ => return Err("Artifact draft type disagrees with its selected metadata facet.".into()),
};
Ok(())
}
impl Editor {
pub fn pair(&self) -> KeyPair<Id> {
KeyPair {
oa: self.oa.as_ref().map(|c| c.id),
sa: self.sa.as_ref().map(|c| c.id),
}
}
pub fn select_pair(&mut self, p: &Project, facet: &FacetSelector) -> Result<(), String> {
let (keys, _) = parts(facet).ok_or("Choose an artifact address.")?;
self.oa = keys.oa.map(|id| self.choice(p, id));
self.sa = keys.sa.map(|id| self.choice(p, id));
Ok(())
}
pub fn choice(&self, p: &Project, id: Id) -> Choice {
if p.contains(id) {
return view::choice(p, id);
}
self.seeds.get(&id).map_or_else(
|| view::choice(p, id),
|a| Choice {
id,
label: format!("{} · reserved @{}", a.name, a.alias),
},
)
}
pub fn choices(&self, p: &Project, trace: &Trace, layer: Layer) -> Vec<Choice> {
let owner = if layer == Layer::Oa {
trace.oa
} else {
trace.sa
};
let selected = key(&self.pair(), layer);
let mut ids: BTreeSet<_> = p
.artifact_links
.values()
.filter(|a| p.layer_of(a.owner).is_none_or(|actual| actual == layer))
.map(|a| a.id)
.chain(
self.seeds
.values()
.filter(|a| a.owner == owner)
.map(|a| a.id),
)
.collect();
if let Some(id) = selected {
ids.insert(id);
}
if let Some(base) = trace.baseline.as_ref().and_then(|b| b.semantic.as_ref()) {
for fact in &base.facets {
if let Some((keys, _)) = parts(&fact.selector())
&& let Some(id) = key(keys, layer)
{
ids.insert(id);
}
}
}
let search = self.search.to_lowercase();
let mut choices: Vec<_> = ids
.into_iter()
.map(|id| {
let mut choice = self.choice(p, id);
if let Some(artifact) = p.artifact_links.get(&id) {
choice.label.push_str(&format!(
" · owner: {}{}",
p.named(artifact.owner),
if artifact.owner == owner {
""
} else {
" · not attached to reviewed owner"
}
));
}
choice
})
.filter(|c| Some(c.id) == selected || c.label.to_lowercase().contains(&search))
.collect();
choices.sort_by_cached_key(|c| c.label.to_lowercase());
choices
}
pub fn ensure(
&mut self,
p: &Project,
facet: &FacetSelector,
layer: Layer,
) -> Result<(), String> {
let (keys, which) = parts(facet).ok_or("Choose artifact metadata.")?;
let id = key(keys, layer).ok_or("Choose a destination artifact identity.")?;
let record = p
.artifact_links
.get(&id)
.or_else(|| self.seeds.get(&id))
.ok_or("Reserve a destination counterpart before reviewing its metadata.")?;
let value = raw(record, which).ok_or(
"Presence uses explicit Keep or Take; there is no deletion tombstone candidate.",
)?;
self.drafts.entry(facet.clone()).or_insert(value);
if which == ArtifactFacet::Description
&& let Some(Raw::Text(text)) = self.drafts.get(facet)
{
self.descriptions
.entry(facet.clone())
.or_insert_with(|| text_editor::Content::with_text(text));
}
Ok(())
}
pub fn update(
&mut self,
p: &Project,
trace: &Trace,
direction: TransitionDirection,
event: Event,
) -> Result<Option<Vec<FacetSelector>>, String> {
match event {
Event::Pick(layer, choice) => {
if layer == Layer::Oa {
self.oa = choice
} else {
self.sa = choice
}
}
Event::Search(search) => self.search = search,
Event::Stage => {
let keys = self.pair();
if keys.oa.is_none() && keys.sa.is_none() {
return Err("Choose at least one exact artifact identity.".into());
}
for layer in [Layer::Oa, Layer::Sa] {
if key(&keys, layer)
.and_then(|id| p.layer_of(id))
.is_some_and(|actual| actual != layer)
{
return Err(
"Artifact pair identity belongs to the other perspective.".into()
);
}
}
capture_facet(
p,
trace.oa,
trace.sa,
&selector(&keys, ArtifactFacet::Presence),
)?;
return Ok(Some(
std::iter::once(ArtifactFacet::Presence)
.chain(METADATA)
.map(|facet| selector(&keys, facet))
.filter(|facet| capture_facet(p, trace.oa, trace.sa, facet).is_ok())
.collect(),
));
}
Event::Reserve => {
let source = key(&self.pair(), direction.source_layer())
.and_then(|id| p.artifact_links.get(&id))
.ok_or(
"Choose an existing source artifact before reserving its counterpart.",
)?;
let source_owner = if direction.source_layer() == Layer::Oa {
trace.oa
} else {
trace.sa
};
if source.owner != source_owner {
return Err(
"The source artifact is not attached to this reviewed owner.".into(),
);
}
let mut seed = source.clone();
seed.id = Id::new_v4();
seed.alias = format!("artifact_{}", seed.id.simple());
seed.owner = if direction.target_layer() == Layer::Oa {
trace.oa
} else {
trace.sa
};
let choice = Choice {
id: seed.id,
label: format!("{} · reserved @{}", seed.name, seed.alias),
};
self.seeds.insert(seed.id, seed);
if direction.target_layer() == Layer::Oa {
self.oa = Some(choice)
} else {
self.sa = Some(choice)
};
}
Event::Input(facet, value) => {
let (_, which) = parts(&facet).ok_or("Choose artifact metadata.")?;
if !compatible(which, &value) || !self.drafts.contains_key(&facet) {
return Err(
"Choose Set final value for this exact artifact metadata first.".into(),
);
}
if which == ArtifactFacet::Description
&& let Raw::Text(text) = &value
{
self.descriptions
.insert(facet.clone(), text_editor::Content::with_text(text));
}
self.drafts.insert(facet, value);
}
Event::Description(facet, action) => {
let editor = self
.descriptions
.get_mut(&facet)
.ok_or("Choose the artifact description draft first.")?;
editor.perform(action);
self.drafts.insert(facet, Raw::Text(editor.text()));
}
}
Ok(None)
}
pub fn editable(
&self,
p: &Project,
trace: &Trace,
facet: &FacetSelector,
layer: Layer,
) -> bool {
let Some((keys, which)) = parts(facet) else {
return false;
};
key(keys, layer).is_some()
&& capture_facet(p, trace.oa, trace.sa, facet).is_ok()
&& (which == ArtifactFacet::Presence
|| key(keys, layer).is_some_and(|id| {
p.artifact_links.contains_key(&id) || self.seeds.contains_key(&id)
}))
}
pub fn propose(
&self,
p: &Project,
trace: &Trace,
direction: TransitionDirection,
references: &BTreeMap<Id, Id>,
decisions: &BTreeMap<FacetSelector, SemanticDecision>,
) -> Result<Proposal, String> {
let mut result = Proposal {
slots: vec![],
creations: vec![],
candidates: BTreeSet::new(),
};
let mut pairs: BTreeMap<Id, Vec<(&FacetSelector, SemanticDecision)>> = BTreeMap::new();
for (facet, decision) in decisions {
if let Some((keys, _)) = parts(facet) {
let id = key(keys, direction.target_layer())
.ok_or("Choose a destination artifact identity.")?;
pairs.entry(id).or_default().push((facet, *decision));
}
}
for (id, selected) in pairs {
let original = p.artifact_links.get(&id);
let mut record = original.cloned();
let mut deletion_origin = None;
let owner = if direction.target_layer() == Layer::Oa {
trace.oa
} else {
trace.sa
};
for (facet, decision) in &selected {
let (keys, which) = parts(facet).expect("Artifact");
if which != ArtifactFacet::Presence {
continue;
}
if *decision == SemanticDecision::Candidate {
return Err("Artifact presence uses Keep or Take; deletion requires explicit source-owner absence.".into());
}
if *decision == SemanticDecision::TakeSource
&& key(keys, direction.source_layer()).is_some()
{
let fact = capture_facet(p, trace.oa, trace.sa, facet)?;
let present = scalar::value(&fact, direction.source_layer())
.and_then(|value| value.as_bool())
.ok_or("Source artifact attachment unavailable.")?;
if !present {
record = None;
deletion_origin = Some((*facet).clone());
} else if record.is_none() {
record=Some(self.seeds.get(&id).cloned().ok_or("Reserve a complete destination artifact counterpart before taking its presence.")?);
} else if record.as_ref().is_some_and(|a| a.owner != owner) {
return Err("Take presence cannot move an artifact from another owner; review its Owner from the initially attached trace.".into());
}
}
}
for (facet, decision) in &selected {
let (keys, which) = parts(facet).expect("Artifact");
if which == ArtifactFacet::Presence {
continue;
}
for (layer, side_owner) in [(Layer::Oa, trace.oa), (Layer::Sa, trace.sa)] {
if key(keys, layer)
.and_then(|id| p.artifact_links.get(&id))
.is_some_and(|a| a.owner != side_owner)
{
return Err("Artifact metadata must be reviewed from its initially attached owner trace.".into());
}
}
if *decision == SemanticDecision::KeepTarget {
continue;
}
let value = if *decision == SemanticDecision::Candidate {
self.drafts
.get(*facet)
.cloned()
.ok_or("Choose an explicit final metadata value.")?
} else {
if key(keys, direction.source_layer()).is_none() {
continue;
}
let source=key(keys,direction.source_layer()).and_then(|id|p.artifact_links.get(&id)).ok_or("Source artifact metadata is absent; keep or set the target metadata explicitly.")?;
let mut value = raw(source, which).expect("Metadata");
if let Raw::Owner(ref mut owner) = value {
let from = source.owner;
let target = if direction == TransitionDirection::OaToSa {
references.get(&from).copied()
} else {
let ids: Vec<_> = references
.iter()
.filter(|(_, sa)| **sa == from)
.map(|(oa, _)| *oa)
.collect();
(ids.len() == 1).then(|| ids[0])
}
.ok_or("Map the source artifact owner explicitly.")?;
*owner = target.to_string();
}
value
};
write(
record
.as_mut()
.ok_or("This metadata decision conflicts with absent artifact presence.")?,
which,
&value,
)?;
if *decision == SemanticDecision::Candidate {
result.candidates.insert(id);
}
}
for (facet, decision) in &selected {
let (_, which) = parts(facet).expect("Artifact");
result.slots.push((
slot(id, which),
observation(
if *decision == SemanticDecision::KeepTarget {
original
} else {
record.as_ref()
},
which,
),
(*facet).clone(),
));
}
if original.is_some() && record.is_none() {
for which in METADATA {
result.slots.push((
slot(id, which),
observation(None, which),
deletion_origin
.clone()
.expect("Absent record has an explicit Presence decision"),
));
}
}
if original.is_none()
&& let Some(record) = record
{
result.candidates.insert(id);
result.creations.push(record);
}
}
Ok(result)
}
pub fn recovery_snapshot(&self) -> Saved {
Saved {
oa: self.oa.as_ref().map(|c| c.id),
sa: self.sa.as_ref().map(|c| c.id),
seeds: self.seeds.values().cloned().collect(),
drafts: self
.drafts
.iter()
.map(|(facet, value)| (facet.clone(), value.clone()))
.collect(),
}
}
pub fn from_recovery(
p: &Project,
trace: &Trace,
direction: TransitionDirection,
saved: Saved,
) -> Result<Self, String> {
if saved.seeds.len().saturating_add(saved.drafts.len())
> crate::source_workspace::LIMITS.model.max_records
{
return Err("Artifact recovery exceeds supported limits.".into());
}
let mut editor = Self::default();
let owner = if direction.target_layer() == Layer::Oa {
trace.oa
} else {
trace.sa
};
let mut aliases = BTreeSet::new();
for seed in saved.seeds {
if p.contains(seed.id)
|| seed.owner != owner
|| seed.alias != format!("artifact_{}", seed.id.simple())
|| !aliases.insert(seed.alias.clone())
|| editor.seeds.insert(seed.id, seed).is_some()
{
return Err("Recovered reserved artifact identity, owner or alias is invalid or duplicated.".into());
}
}
for (facet, value) in saved.drafts {
let (keys, which) =
parts(&facet).ok_or("Recovered artifact draft has a different facet family.")?;
if !compatible(which, &value) {
return Err("Recovered artifact draft type disagrees with its facet.".into());
}
for layer in [Layer::Oa, Layer::Sa] {
if key(keys, layer)
.and_then(|id| p.layer_of(id))
.is_some_and(|actual| actual != layer)
{
return Err("Recovered artifact pair has a wrong-layer identity.".into());
}
}
let id = key(keys, direction.target_layer())
.ok_or("Recovered artifact draft has no destination identity.")?;
if !p.artifact_links.contains_key(&id) && !editor.seeds.contains_key(&id) {
return Err(
"Recovered artifact draft has no existing or reserved destination record."
.into(),
);
}
if let (ArtifactFacet::Description, Raw::Text(text)) = (which, &value) {
editor
.descriptions
.insert(facet.clone(), text_editor::Content::with_text(text));
}
if editor.drafts.insert(facet, value).is_some() {
return Err("Recovered artifact draft address is duplicated.".into());
}
}
editor.oa = saved.oa.map(|id| editor.choice(p, id));
editor.sa = saved.sa.map(|id| editor.choice(p, id));
Ok(editor)
}
}