Add bounded definition and reference navigation for current source drafts

Preserve loaded draft bytes and model history, reject stale workspace and input events, and keep captured Escape under modal priority. Verified 181 focused Windows tests and strict desktop Clippy on exact inputs4; earlier full737 scope and component/native preparation evidence are archived separately. Native navigation acceptance remains pending.
This commit is contained in:
2026-09-11 11:23:20 -07:00
parent fb24def2f5
commit 36db9356cc
208 changed files with 44983 additions and 62 deletions
+160 -27
View File
@@ -142,12 +142,87 @@ pub struct Analysis {
pub declarations: Vec<DeclarationSpan>, pub declarations: Vec<DeclarationSpan>,
} }
/// Check the decoded spelling required by declaration-header UUID clauses.
/// This is the shared 36-byte/hyphen shape rule, not a hexadecimal parser:
/// callers must additionally parse the UUID. Uppercase hex and JSON escapes
/// that decode to this spelling remain accepted. URN/braced/compact forms do not.
pub fn has_uuid_header_shape(decoded: &str) -> bool {
decoded.len() == 36
&& [8, 13, 18, 23]
.into_iter()
.all(|index| decoded.as_bytes()[index] == b'-')
}
/// Budgets for one original source buffer. Policy is caller-owned; these
/// limits do not change the grammar or perform model admission.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OutlineLimits {
pub max_source_bytes: usize,
pub max_tokens: usize,
pub max_declarations: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OutlineResource {
SourceBytes,
Tokens,
Declarations,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OutlineLimit {
pub resource: OutlineResource,
pub limit: usize,
pub observed_at_least: usize,
/// Original byte offset where admission stopped; never a rewritten offset.
pub offset: usize,
}
/// Roles discovered by the existing tolerant declaration walk. Keeping the
/// wrapper preserves DeclarationSpan and Analysis as existing public APIs.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OutlineDeclaration {
pub declaration: DeclarationSpan,
pub kind_span: Span,
pub alias_span: Span,
/// Whole quoted header ID token, even if it is not a valid UUID. In that
/// case declaration.id is None. Missing/non-string ID values have no span.
pub id_literal_span: Option<Span>,
}
/// A full-file tolerant scan, not a successful parse or validated model. Invalid
/// text remains available. Lexical errors and unmatched braces are facts only:
/// their absence does not establish syntactic or semantic validity.
///
/// A budget failure returns Err and no partial Outline. Include reachability,
/// project completeness and editor revision are intentionally not inferred here.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Outline<'a> {
pub source: &'a str,
pub tokens: Vec<TokenSpan>,
pub declarations: Vec<OutlineDeclaration>,
pub has_lexical_errors: bool,
pub has_unmatched_braces: bool,
}
/// Tolerant highlighting tokens cover the whole input, including incomplete /// Tolerant highlighting tokens cover the whole input, including incomplete
/// strings and unexpected characters. No model is created or modified. /// strings and unexpected characters. No model is created or modified.
pub fn tokenize(source: &str) -> Vec<TokenSpan> { pub fn tokenize(source: &str) -> Vec<TokenSpan> {
tokenize_with_limit(source, usize::MAX).expect("unlimited token scan")
}
fn tokenize_with_limit(source: &str, max_tokens: usize) -> Result<Vec<TokenSpan>, OutlineLimit> {
let mut tokens = Vec::new(); let mut tokens = Vec::new();
let mut cursor = 0; let mut cursor = 0;
while cursor < source.len() { while cursor < source.len() {
if tokens.len() == max_tokens {
return Err(OutlineLimit {
resource: OutlineResource::Tokens,
limit: max_tokens,
observed_at_least: tokens.len().saturating_add(1),
offset: cursor,
});
}
let start = cursor; let start = cursor;
let ch = source[cursor..].chars().next().expect("in bounds"); let ch = source[cursor..].chars().next().expect("in bounds");
let class = if matches!(ch, ' ' | '\t' | '\r' | '\n') { let class = if matches!(ch, ' ' | '\t' | '\r' | '\n') {
@@ -224,7 +299,7 @@ pub fn tokenize(source: &str) -> Vec<TokenSpan> {
span: Span { start, end: cursor }, span: Span { start, end: cursor },
}); });
} }
tokens Ok(tokens)
} }
pub fn lint(source: &str) -> Vec<Diagnostic> { pub fn lint(source: &str) -> Vec<Diagnostic> {
@@ -1230,11 +1305,7 @@ impl Parser<'_> {
self.cursor += 1; self.cursor += 1;
let offset = self.current().span.start; let offset = self.current().span.start;
let value = self.quoted()?; let value = self.quoted()?;
if value.len() != 36 if !has_uuid_header_shape(&value) {
|| ![8, 13, 18, 23]
.into_iter()
.all(|i| value.as_bytes()[i] == b'-')
{
return Err(Error { return Err(Error {
code: "invalid_source", code: "invalid_source",
offset, offset,
@@ -1962,8 +2033,49 @@ fn take_required_id(fields: &mut Map<String, Value>, key: &str) -> Result<Id, St
/// Analyze an incomplete source buffer without adopting a candidate. Declaration /// Analyze an incomplete source buffer without adopting a candidate. Declaration
/// spans remain available even when a later declaration contains errors. /// spans remain available even when a later declaration contains errors.
/// Invalid compact/braced/URN header IDs retain no authored identity, matching
/// the declaration parser rather than the UUID crate's broader accepted forms.
pub fn analyze(source: &str) -> Analysis { pub fn analyze(source: &str) -> Analysis {
let tokens = tokenize(source); let tokens = tokenize(source);
let (declarations, _) =
declaration_outline(source, &tokens, usize::MAX).expect("unlimited declaration walk");
Analysis {
tokens,
diagnostics: lint(source),
declarations: declarations.into_iter().map(|d| d.declaration).collect(),
}
}
/// Read exact current text without lint, parsing a model, stabilization or I/O.
/// Source bytes are admitted before token allocation; token/declaration limits
/// are checked before lexing the next token or materializing the next record.
pub fn outline(source: &str, limits: OutlineLimits) -> Result<Outline<'_>, OutlineLimit> {
if source.len() > limits.max_source_bytes {
return Err(OutlineLimit {
resource: OutlineResource::SourceBytes,
limit: limits.max_source_bytes,
observed_at_least: source.len(),
offset: 0,
});
}
let tokens = tokenize_with_limit(source, limits.max_tokens)?;
let has_lexical_errors = tokens.iter().any(|token| token.class == TokenClass::Error);
let (declarations, has_unmatched_braces) =
declaration_outline(source, &tokens, limits.max_declarations)?;
Ok(Outline {
source,
tokens,
declarations,
has_lexical_errors,
has_unmatched_braces,
})
}
fn declaration_outline(
source: &str,
tokens: &[TokenSpan],
max_declarations: usize,
) -> Result<(Vec<OutlineDeclaration>, bool), OutlineLimit> {
let significant = tokens let significant = tokens
.iter() .iter()
.filter(|t| !matches!(t.class, TokenClass::Whitespace | TokenClass::Comment)) .filter(|t| !matches!(t.class, TokenClass::Whitespace | TokenClass::Comment))
@@ -1972,17 +2084,21 @@ pub fn analyze(source: &str) -> Analysis {
// again would make tolerant navigation quadratic on deeply nested drafts. // again would make tolerant navigation quadratic on deeply nested drafts.
let mut body_ends = vec![None; significant.len()]; let mut body_ends = vec![None; significant.len()];
let mut bodies = Vec::new(); let mut bodies = Vec::new();
let mut unmatched_close = false;
for (index, token) in significant.iter().enumerate() { for (index, token) in significant.iter().enumerate() {
match &source[token.span.start..token.span.end] { match &source[token.span.start..token.span.end] {
"{" => bodies.push(index), "{" => bodies.push(index),
"}" => { "}" => {
if let Some(open) = bodies.pop() { if let Some(open) = bodies.pop() {
body_ends[open] = Some(token.span.end); body_ends[open] = Some(token.span.end);
} else {
unmatched_close = true;
} }
} }
_ => {} _ => {}
} }
} }
let has_unmatched_braces = unmatched_close || !bodies.is_empty();
let mut declarations = Vec::new(); let mut declarations = Vec::new();
for (i, t) in significant.iter().enumerate() { for (i, t) in significant.iter().enumerate() {
let word = &source[t.span.start..t.span.end]; let word = &source[t.span.start..t.span.end];
@@ -2007,7 +2123,16 @@ pub fn analyze(source: &str) -> Analysis {
} }
j += 1; j += 1;
} }
if declarations.len() == max_declarations {
return Err(OutlineLimit {
resource: OutlineResource::Declarations,
limit: max_declarations,
observed_at_least: declarations.len().saturating_add(1),
offset: t.span.start,
});
}
let mut id = None; let mut id = None;
let mut id_literal_span = None;
if significant if significant
.get(j) .get(j)
.is_some_and(|t| &source[t.span.start..t.span.end] == "id") .is_some_and(|t| &source[t.span.start..t.span.end] == "id")
@@ -2015,39 +2140,51 @@ pub fn analyze(source: &str) -> Analysis {
if let Some(value) = significant.get(j + 1) if let Some(value) = significant.get(j + 1)
&& value.class == TokenClass::String && value.class == TokenClass::String
{ {
id_literal_span = Some(value.span);
let text = let text =
serde_json::from_str::<String>(&source[value.span.start..value.span.end]) serde_json::from_str::<String>(&source[value.span.start..value.span.end])
.unwrap(); .unwrap();
id = Id::parse_str(&text).ok(); if has_uuid_header_shape(&text) {
id = Id::parse_str(&text).ok();
}
} }
j += 2; j += 2;
} }
let mut end = significant // A recognized header ID at EOF must remain inside the whole span.
.get(j) // Keep the old next-token/body behavior; only the EOF fallback changes.
.map_or(alias_token.span.end, |t| t.span.end); let header_end = significant
.get(j.saturating_sub(1))
.or_else(|| significant.last())
.map_or(alias_token.span.end, |token| token.span.end);
let mut end = significant.get(j).map_or(header_end, |t| t.span.end);
if significant if significant
.get(j) .get(j)
.is_some_and(|t| &source[t.span.start..t.span.end] == "{") .is_some_and(|t| &source[t.span.start..t.span.end] == "{")
{ {
end = body_ends[j].unwrap_or(source.len()); end = body_ends[j].unwrap_or(source.len());
} }
declarations.push(DeclarationSpan { declarations.push(OutlineDeclaration {
alias: alias.into(), declaration: DeclarationSpan {
id, alias: alias.into(),
kind: word.into(), id,
span: Span { kind: word.into(),
start: t.span.start, span: Span {
end, start: t.span.start,
end,
},
}, },
kind_span: t.span,
alias_span: alias_token.span,
id_literal_span,
}); });
} }
Analysis { Ok((declarations, has_unmatched_braces))
tokens,
diagnostics: lint(source),
declarations,
}
} }
#[cfg(test)]
#[path = "language_outline_tests.rs"]
mod outline_tests;
#[cfg(test)] #[cfg(test)]
#[path = "language_nesting_tests.rs"] #[path = "language_nesting_tests.rs"]
mod nesting_tests; mod nesting_tests;
@@ -2442,11 +2579,7 @@ pub(crate) mod legacy {
let value = self.quoted()?; let value = self.quoted()?;
// Require the portable 8-4-4-4-12 spelling, not the UUID crate's URN, // Require the portable 8-4-4-4-12 spelling, not the UUID crate's URN,
// braces, or compact alternatives. Uppercase hexadecimal is accepted. // braces, or compact alternatives. Uppercase hexadecimal is accepted.
if value.len() != 36 if !super::has_uuid_header_shape(&value) {
|| ![8, 13, 18, 23]
.into_iter()
.all(|index| value.as_bytes()[index] == b'-')
{
return Err(Error { return Err(Error {
code: "invalid_source", code: "invalid_source",
offset, offset,
@@ -0,0 +1,386 @@
//! Prepared outline tests. Explicit compatibility tests additionally exercise
//! the existing parsers/analyze; the outline entry itself never calls them.
use super::*;
fn limits() -> OutlineLimits {
OutlineLimits {
max_source_bytes: 1024 * 1024,
max_tokens: 100_000,
max_declarations: 1_000,
}
}
fn declaration<'a>(result: &'a Outline<'_>, alias: &str) -> &'a OutlineDeclaration {
result
.declarations
.iter()
.find(|d| d.declaration.alias == alias)
.unwrap()
}
fn text(source: &str, span: Span) -> &str {
&source[span.start..span.end]
}
#[test]
fn outline_roles_preserve_unicode_crlf_and_exact_escaped_uuid_literal() {
let source = "// 検査 🚒\r\noa_actor responder \"救助\" id \"\\u00300000000-0000-0000-0000-000000000001\" {}\r\nsource @ // 使用\r\n responder;";
let before = source.as_bytes().to_vec();
let result = outline(source, limits()).unwrap();
assert_eq!(result.source.as_bytes(), before);
assert_eq!(result.source.as_ptr(), source.as_ptr());
let d = declaration(&result, "responder");
assert_eq!(text(source, d.kind_span), "oa_actor");
assert_eq!(text(source, d.alias_span), "responder");
assert_eq!(
text(source, d.id_literal_span.unwrap()),
"\"\\u00300000000-0000-0000-0000-000000000001\""
);
assert_eq!(d.declaration.id, Some(Id::from_u128(1)));
assert_eq!(d.declaration.span.start, source.find("oa_actor").unwrap());
assert_eq!(d.declaration.span.end, source.find("{}\r\n").unwrap() + 2);
let mut end = 0;
for token in &result.tokens {
assert_eq!(token.span.start, end);
assert!(token.span.start < token.span.end);
assert!(source.is_char_boundary(token.span.start));
assert!(source.is_char_boundary(token.span.end));
end = token.span.end;
}
assert_eq!(end, source.len());
assert!(!result.has_lexical_errors);
assert!(!result.has_unmatched_braces);
}
#[test]
fn closed_id_at_eof_is_inside_the_declaration_extent() {
for source in [
"oa_actor a \"Actor\" id \"00000000-0000-0000-0000-000000000001\"",
"node placed id \"00000000-0000-0000-0000-000000000001\"",
] {
let result = outline(source, limits()).unwrap();
let d = &result.declarations[0];
let literal = d.id_literal_span.unwrap();
assert_eq!(d.declaration.id, Some(Id::from_u128(1)));
assert_eq!(d.declaration.span.end, source.len());
assert!(d.declaration.span.start <= literal.start);
assert!(literal.end <= d.declaration.span.end);
}
for source in ["oa_actor a \"Actor\"", "oa_actor a \"Actor\" id"] {
let result = outline(source, limits()).unwrap();
let d = &result.declarations[0];
assert_eq!(d.declaration.span.end, source.len());
assert_eq!(d.declaration.id, None);
assert_eq!(d.id_literal_span, None);
}
}
#[test]
fn missing_bad_and_historical_ids_never_allocate_authored_identity() {
let source = "oa_actor missing \"No ID\" {}\noa_actor bad \"Bad ID\" id \"not-a-uuid\" {}\noa_actor historical \"00000000-0000-0000-0000-000000000001\" { history uuid \"00000000-0000-0000-0000-000000000001\"; }";
let first = outline(source, limits()).unwrap();
let second = outline(source, limits()).unwrap();
assert_eq!(first, second);
assert!(
first
.declarations
.iter()
.all(|d| d.declaration.id.is_none())
);
assert_eq!(declaration(&first, "missing").id_literal_span, None);
assert_eq!(declaration(&first, "historical").id_literal_span, None);
assert_eq!(
text(source, declaration(&first, "bad").id_literal_span.unwrap()),
"\"not-a-uuid\""
);
// Balanced tokens are not a successful syntax/semantic validation claim.
assert!(!first.has_lexical_errors);
assert!(!first.has_unmatched_braces);
}
#[test]
fn invalid_full_scan_keeps_closed_children_and_reports_lexical_body_facts() {
let source = "oa_entity outer \"Outer\" {\n oa_actor ready \"Ready\" { description \"} stays text\"; }\n oa_actor pending \"Pending\" { description \"unfinished 🌊";
let result = outline(source, limits()).unwrap();
assert_eq!(result.source, source);
assert_eq!(result.tokens.last().unwrap().span.end, source.len());
assert!(result.has_lexical_errors);
assert!(result.has_unmatched_braces);
let ready = declaration(&result, "ready");
assert_eq!(
text(source, ready.declaration.span),
"oa_actor ready \"Ready\" { description \"} stays text\"; }"
);
assert_eq!(
declaration(&result, "outer").declaration.span.end,
source.len()
);
assert_eq!(
declaration(&result, "pending").declaration.span.end,
source.len()
);
let unmatched_close = outline("}\n// brace in comment {\n", limits()).unwrap();
assert!(unmatched_close.has_unmatched_braces);
assert!(!unmatched_close.has_lexical_errors);
}
#[test]
fn missing_body_syntax_is_unchecked_even_when_known_error_flags_are_clear() {
let source = "oa_actor a \"A\" id \"00000000-0000-0000-0000-000000000001\"";
let result = outline(source, limits()).unwrap();
assert_eq!(result.declarations.len(), 1);
assert!(!result.has_lexical_errors);
assert!(!result.has_unmatched_braces);
// There is deliberately no `valid` flag: the known-complete fact is scanning
// these bytes, not the missing body becoming legal or the draft being applied.
assert_eq!(result.source, source);
}
#[test]
fn keyword_alias_and_collisions_keep_every_source_ordered_header() {
let source = "project root_model \"Model\" {\n oa_actor oa_activity \"First\" id \"00000000-0000-0000-0000-000000000001\" {}\n oa_actor oa_activity \"Second\" id \"00000000-0000-0000-0000-000000000001\" {}\n diagram view_one \"View\" {}\n node placement { diagram @view_one; }\n}";
let result = outline(source, limits()).unwrap();
assert_eq!(result.declarations.len(), 5);
let duplicates: Vec<_> = result
.declarations
.iter()
.filter(|d| d.declaration.alias == "oa_activity")
.collect();
assert_eq!(duplicates.len(), 2);
assert!(duplicates[0].alias_span.start < duplicates[1].alias_span.start);
assert_eq!(duplicates[0].declaration.id, duplicates[1].declaration.id);
assert!(
result
.tokens
.iter()
.any(|t| t.span == duplicates[0].alias_span && t.class == TokenClass::Keyword)
);
assert_eq!(
text(source, declaration(&result, "placement").kind_span),
"node"
);
assert_eq!(declaration(&result, "placement").declaration.id, None);
}
#[test]
fn bounds_refuse_before_returning_a_partial_outline() {
let source = "oa_actor a \"A\" {}\noa_actor b \"B\" {}";
let admitted = outline(source, limits()).unwrap();
let exact = OutlineLimits {
max_source_bytes: source.len(),
max_tokens: admitted.tokens.len(),
max_declarations: 2,
};
assert_eq!(outline(source, exact).unwrap(), admitted);
for resource in [
OutlineResource::SourceBytes,
OutlineResource::Tokens,
OutlineResource::Declarations,
] {
let mut lower = exact;
match resource {
OutlineResource::SourceBytes => lower.max_source_bytes -= 1,
OutlineResource::Tokens => lower.max_tokens -= 1,
OutlineResource::Declarations => lower.max_declarations -= 1,
}
let error = outline(source, lower).unwrap_err();
assert_eq!(error.resource, resource);
assert!(error.observed_at_least > error.limit);
assert!(source.is_char_boundary(error.offset));
if resource == OutlineResource::Declarations {
assert_eq!(error.offset, source.find("oa_actor b").unwrap());
}
}
let empty = outline(
"",
OutlineLimits {
max_source_bytes: 0,
max_tokens: 0,
max_declarations: 0,
},
)
.unwrap();
assert!(empty.tokens.is_empty() && empty.declarations.is_empty());
let unicode = "// 🌊\r\noa_actor a \"A\" {}";
let error = outline(
unicode,
OutlineLimits {
max_source_bytes: 4,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::SourceBytes);
assert_eq!(error.offset, 0);
let error = outline(
unicode,
OutlineLimits {
max_tokens: 1,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::Tokens);
assert_eq!(error.offset, unicode.find('\n').unwrap());
}
#[test]
fn outline_ranges_follow_current_bytes_without_identity_stabilization() {
let old = "oa_actor a \"A\" {}\nsource @a;";
let current = format!("// 航海 🚒\r\n{old}");
let old_outline = outline(old, limits()).unwrap();
let current_outline = outline(&current, limits()).unwrap();
let shift = current.len() - old.len();
let old_role = &old_outline.declarations[0];
let current_role = &current_outline.declarations[0];
assert_eq!(
current_role.alias_span.start,
old_role.alias_span.start + shift
);
assert_eq!(
current_role.kind_span.start,
old_role.kind_span.start + shift
);
assert_eq!(
current_role.declaration.span.end,
old_role.declaration.span.end + shift
);
assert_eq!(current_outline.source, current);
assert_eq!(old_outline.source, old);
assert_eq!(current_role.declaration.id, None);
assert!(!current_outline.source.contains(" id "));
// Workspace revision/stale-handle rejection belongs to the query/adapter,
// not a claim that an old owned span can be applied to any other string.
}
#[test]
fn deeply_nested_bounds_use_the_same_iterative_walk_and_declaration_budget() {
let mut source = String::new();
for index in 0..600 {
source.push_str(&format!("oa_activity work_{index} \"Work\" {{\n"));
}
source.push_str(&"}\n".repeat(600));
let result = outline(&source, limits()).unwrap();
assert_eq!(result.declarations.len(), 600);
assert!(!result.has_unmatched_braces);
assert_eq!(
result.declarations[0].declaration.span.end,
source.len() - 1
);
let error = outline(
&source,
OutlineLimits {
max_declarations: 599,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::Declarations);
assert_eq!(error.observed_at_least, 600);
assert_eq!(error.offset, source.find("oa_activity work_599").unwrap());
}
#[test]
fn noncanonical_uuid_spellings_have_no_outline_or_analysis_identity() {
for raw in [
"00000000000000000000000000000001",
"{00000000-0000-0000-0000-000000000001}",
"urn:uuid:00000000-0000-0000-0000-000000000001",
] {
assert!(
Id::parse_str(raw).is_ok(),
"The UUID crate alone is too permissive"
);
assert!(!has_uuid_header_shape(raw));
let literal = format!("\"{raw}\"");
let modern = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let before = modern.clone();
let result = outline(&modern, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, None);
assert_eq!(text(&modern, d.id_literal_span.unwrap()), literal);
assert_eq!(modern, before);
let errors = parse(&modern).unwrap_err();
assert!(
errors
.iter()
.any(|error| error.message.contains("8-4-4-4-12")
&& error.span.start == modern.find(&literal).unwrap())
);
// Intentional compatibility correction: old analyze yielded Some(Id(1))
// here despite lint rejecting the header. It now shares outline's None.
let analysis = analyze(&modern);
assert_eq!(
analysis
.declarations
.iter()
.find(|d| d.alias == "model")
.unwrap()
.id,
None
);
assert!(
analysis
.diagnostics
.iter()
.any(|error| error.message.contains("8-4-4-4-12"))
);
let legacy_source = format!("arcadia 1; project \"Legacy\" id {literal} {{}}");
let legacy_errors = legacy::parse(&legacy_source).unwrap_err();
assert!(
legacy_errors
.iter()
.any(|error| error.message.contains("8-4-4-4-12"))
);
}
}
#[test]
fn uppercase_and_json_escaped_header_ids_survive_both_parsers_and_outline() {
let expected = Id::from_u128(0xabcdef);
let canonical = expected.to_string();
let uppercase = canonical.to_uppercase();
assert_ne!(uppercase, canonical);
for raw in [uppercase.clone(), format!("\\u0030{}", &uppercase[1..])] {
let literal = format!("\"{raw}\"");
let decoded: String = serde_json::from_str(&literal).unwrap();
assert!(has_uuid_header_shape(&decoded));
let modern = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let result = outline(&modern, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, Some(expected));
assert_eq!(text(&modern, d.id_literal_span.unwrap()), literal);
assert_eq!(result.source.as_bytes(), modern.as_bytes());
assert_eq!(parse(&modern).unwrap().id, expected);
let analysis = analyze(&modern);
assert_eq!(analysis.declarations[0].id, Some(expected));
assert!(
!analysis
.diagnostics
.iter()
.any(|error| error.severity == crate::validation::Severity::Error)
);
let legacy_source = format!("arcadia 1; project \"Legacy\" id {literal} {{}}");
assert_eq!(legacy::parse(&legacy_source).unwrap().id, expected);
}
}
#[test]
fn header_shape_still_requires_valid_hexadecimal_uuid_data() {
let raw = "00000000-0000-0000-0000-00000000000Z";
assert!(has_uuid_header_shape(raw));
assert!(Id::parse_str(raw).is_err());
let literal = format!("\"{raw}\"");
let source = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let result = outline(&source, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, None);
assert_eq!(text(&source, d.id_literal_span.unwrap()), literal);
assert!(
parse(&source)
.unwrap_err()
.iter()
.any(|error| error.message == "Invalid UUID identity.")
);
assert_eq!(analyze(&source).declarations[0].id, None);
}
+78 -22
View File
@@ -7,6 +7,7 @@ mod diagram_selection_tests;
mod hosted; mod hosted;
#[cfg(test)] #[cfg(test)]
mod review_navigation_tests; mod review_navigation_tests;
mod source_symbols;
#[cfg(test)] #[cfg(test)]
mod transition_context_tests; mod transition_context_tests;
#[cfg(test)] #[cfg(test)]
@@ -415,7 +416,12 @@ pub enum Message {
Linted(u64, Result<Vec<SourceDiagnostic>, String>), Linted(u64, Result<Vec<SourceDiagnostic>, String>),
SourceDiagnostic(usize), SourceDiagnostic(usize),
SourceRelated(SourceLocation), SourceRelated(SourceLocation),
SourceViewport, SourceViewport(Option<Id>),
SourceSymbols(
crate::source_navigation::SymbolContext,
crate::source_navigation::SymbolEvent,
),
SourceSymbolsReady(crate::source_navigation::Completion),
SourceForSelection, SourceForSelection,
SourceNavigation(crate::source_navigation::Event), SourceNavigation(crate::source_navigation::Event),
Save(bool), Save(bool),
@@ -491,6 +497,7 @@ pub struct App {
pub source_jump: Option<text_editor::Cursor>, pub source_jump: Option<text_editor::Cursor>,
source_select_line: bool, source_select_line: bool,
pub source_navigation: crate::source_navigation::State, pub source_navigation: crate::source_navigation::State,
pub source_symbols: crate::source_navigation::SymbolState,
pub model_issues: Vec<validation::Issue>, pub model_issues: Vec<validation::Issue>,
pub migration: Option<persistence::MigrationReport>, pub migration: Option<persistence::MigrationReport>,
source_version: u64, source_version: u64,
@@ -596,6 +603,7 @@ impl App {
source_jump: None, source_jump: None,
source_select_line: false, source_select_line: false,
source_navigation: crate::source_navigation::State::default(), source_navigation: crate::source_navigation::State::default(),
source_symbols: crate::source_navigation::SymbolState::default(),
model_issues, model_issues,
migration: None, migration: None,
source_version: 0, source_version: 0,
@@ -649,6 +657,7 @@ impl App {
self.lint_requested = None; self.lint_requested = None;
} }
fn show_source_file(&mut self, restore_cursor: bool) { fn show_source_file(&mut self, restore_cursor: bool) {
self.source_symbols.reveal = None;
self.source_tree.reveal(&self.source_workspace.active); self.source_tree.reveal(&self.source_workspace.active);
self.source_select_line = false; self.source_select_line = false;
let source = self.source_workspace.text().to_owned(); let source = self.source_workspace.text().to_owned();
@@ -663,6 +672,9 @@ impl App {
.map(|b| b.cursor) .map(|b| b.cursor)
}) })
.flatten(); .flatten();
if let Some(cursor) = self.source_jump {
self.queue_source_reveal(cursor, false);
}
} }
fn selected_architecture_placement(&self) -> Option<Id> { fn selected_architecture_placement(&self) -> Option<Id> {
self.active_diagram self.active_diagram
@@ -916,6 +928,7 @@ impl App {
let canvas_size = self.canvas_size; let canvas_size = self.canvas_size;
let source_version = self.source_version + 1; let source_version = self.source_version + 1;
let lint_running = self.lint_running; let lint_running = self.lint_running;
let navigation_in_flight = self.source_symbols.in_flight;
let guide = std::mem::take(&mut self.guide); let guide = std::mem::take(&mut self.guide);
let mut hosted = std::mem::take(&mut self.hosted); let mut hosted = std::mem::take(&mut self.hosted);
hosted.leave_document(); hosted.leave_document();
@@ -927,6 +940,7 @@ impl App {
self.canvas_size = canvas_size; self.canvas_size = canvas_size;
self.source_version = source_version; self.source_version = source_version;
self.lint_running = lint_running; self.lint_running = lint_running;
self.source_symbols.in_flight = navigation_in_flight;
self.guide = guide; self.guide = guide;
self.path = path; self.path = path;
self.status = "Project ready".into(); self.status = "Project ready".into();
@@ -1027,7 +1041,10 @@ impl App {
crate::model_menu::popup(self), crate::model_menu::popup(self),
) )
.into(); .into();
crate::hosted::view::overlay(self, base) crate::source_navigation::interaction::observe(
crate::hosted::view::overlay(self, base),
self.source_symbols.raw_interaction.clone(),
)
} }
pub fn subscription(&self) -> Subscription<Message> { pub fn subscription(&self) -> Subscription<Message> {
Subscription::batch([ Subscription::batch([
@@ -1035,8 +1052,14 @@ impl App {
window::close_requests().map(|id| Message::Request(Pending::Close(id))), window::close_requests().map(|id| Message::Request(Pending::Close(id))),
window::resize_events().map(|(_, size)| Message::WindowResized(size)), window::resize_events().map(|(_, size)| Message::WindowResized(size)),
architecture_authoring::subscription(self), architecture_authoring::subscription(self),
// Use one captured-Escape bridge: a focused Find input consumes
// Escape, while modal priority remains in the ordinary handler.
behavior::creation::subscription( behavior::creation::subscription(
self.behavior.creation.has_pending() || self.behavior.source_active(), self.behavior.creation.has_pending()
|| self.behavior.source_active()
|| (self.page == Page::Text
&& self.source_symbols.open
&& self.architecture.is_none()),
) )
.map(|()| Message::Escape), .map(|()| Message::Escape),
iced::event::listen_with(|event, status, _| { iced::event::listen_with(|event, status, _| {
@@ -1083,6 +1106,30 @@ impl App {
]) ])
} }
pub fn update(&mut self, message: Message) -> Task<Message> { pub fn update(&mut self, message: Message) -> Task<Message> {
if let Message::SourceSymbols(context, _) = &message
&& (context.session != self.source_workspace.session()
|| context.path != self.source_workspace.active)
{
return Task::none();
}
// Internal results and geometry do not constitute a new user intent.
// Process query completion even behind a modal to release its worker slot;
// its handler independently refuses navigation outside the live editor.
if let Message::SourceSymbolsReady(completion) = message {
return self.source_symbols_ready(completion);
}
if !matches!(
&message,
Message::CheckpointTick
| Message::CheckpointWritten(..)
| Message::Lint(_)
| Message::Linted(..)
| Message::SourceViewport(_)
| Message::WindowResized(_)
| Message::CanvasResized(_)
) {
self.source_interaction();
}
if matches!(&message, Message::Connection(_)) if matches!(&message, Message::Connection(_))
&& self && self
.architecture .architecture
@@ -1147,7 +1194,7 @@ impl App {
| Message::CanvasResized(_) | Message::CanvasResized(_)
| Message::Lint(_) | Message::Lint(_)
| Message::Linted(_, _) | Message::Linted(_, _)
| Message::SourceViewport | Message::SourceViewport(_)
| Message::Request(Pending::Close(_)) | Message::Request(Pending::Close(_))
) )
{ {
@@ -1193,7 +1240,7 @@ impl App {
| Message::Exported(_) | Message::Exported(_)
| Message::WindowResized(_) | Message::WindowResized(_)
| Message::CanvasResized(_) | Message::CanvasResized(_)
| Message::SourceViewport | Message::SourceViewport(_)
) )
{ {
return Task::none(); return Task::none();
@@ -1231,7 +1278,7 @@ impl App {
| Message::CheckpointLoaded(..) | Message::CheckpointLoaded(..)
| Message::WindowResized(_) | Message::WindowResized(_)
| Message::CanvasResized(_) | Message::CanvasResized(_)
| Message::SourceViewport | Message::SourceViewport(_)
| Message::Lint(_) | Message::Lint(_)
| Message::Linted(_, _) | Message::Linted(_, _)
| Message::Saved(_) | Message::Saved(_)
@@ -1807,6 +1854,9 @@ impl App {
self.status = "Drawing cancelled · Select / move is active".into(); self.status = "Drawing cancelled · Select / move is active".into();
} }
self.source_navigation.open = false; self.source_navigation.open = false;
self.source_symbols.open = false;
self.source_symbols.results = None;
self.source_symbols.notice = None;
self.canvas_epoch = self.canvas_epoch.wrapping_add(1); self.canvas_epoch = self.canvas_epoch.wrapping_add(1);
self.selected_bend = None; self.selected_bend = None;
} }
@@ -2855,6 +2905,9 @@ impl App {
if self.path.is_none() if self.path.is_none()
|| self.path.as_ref() == Some(&receipt.target) || self.path.as_ref() == Some(&receipt.target)
{ {
if self.path.as_ref() != Some(&receipt.target) {
self.source_workspace.reset_navigation_session();
}
self.path = Some(receipt.target); self.path = Some(receipt.target);
self.disk_project = Some(disk); self.disk_project = Some(disk);
} }
@@ -2917,14 +2970,10 @@ impl App {
} }
} }
Message::SourceRelated(location) => self.jump_to_source(location), Message::SourceRelated(location) => self.jump_to_source(location),
Message::SourceViewport => { Message::SourceViewport(ticket) => return self.source_viewport(ticket),
if let Some(cursor) = self.source_jump.take() { Message::SourceSymbols(_, event) => return self.source_symbol_event(event),
self.source_editor.move_to(cursor); Message::SourceSymbolsReady(completion) => {
if self.source_select_line && cursor.selection.is_none() { return self.source_symbols_ready(completion);
self.source_editor.perform(text_editor::Action::SelectLine);
}
return iced::widget::operation::focus("source-editor");
}
} }
Message::ApplySource => { Message::ApplySource => {
self.apply_source(); self.apply_source();
@@ -2985,6 +3034,9 @@ impl App {
} }
Event::Next(backwards) if self.page == Page::Text => { Event::Next(backwards) if self.page == Page::Text => {
self.source_jump = self.source_navigation.next(backwards); self.source_jump = self.source_navigation.next(backwards);
if let Some(cursor) = self.source_jump {
self.queue_source_reveal(cursor, false);
}
if self.source_jump.is_none() { if self.source_jump.is_none() {
self.status = "No matching source text.".into(); self.status = "No matching source text.".into();
} }
@@ -2995,8 +3047,7 @@ impl App {
.destination(self.source_editor.line_count()) .destination(self.source_editor.line_count())
{ {
Ok(cursor) => { Ok(cursor) => {
self.source_jump = Some(cursor); self.queue_source_reveal(cursor, true);
self.source_select_line = true;
} }
Err(error) => self.status = error, Err(error) => self.status = error,
}, },
@@ -3079,6 +3130,9 @@ impl App {
} }
self.sync_source(); self.sync_source();
} }
if self.path.as_ref() != Some(&receipt.path) {
self.source_workspace.reset_navigation_session();
}
self.disk_project = Some(disk); self.disk_project = Some(disk);
self.path = Some(receipt.path); self.path = Some(receipt.path);
self.hosted.session = None; self.hosted.session = None;
@@ -3638,7 +3692,7 @@ impl App {
self.canvas_epoch = self.canvas_epoch.wrapping_add(1); self.canvas_epoch = self.canvas_epoch.wrapping_add(1);
self.path = Some(path); self.path = Some(path);
self.source_workspace = Workspace::new(&disk.bundle, false); self.source_workspace = Workspace::new(&disk.bundle, false);
self.source_workspace.reachable = disk.reachable.clone(); self.source_workspace.set_reachable(disk.reachable.clone());
self.show_source_file(false); self.show_source_file(false);
self.source_diagnostics = error.diagnostics().to_vec(); self.source_diagnostics = error.diagnostics().to_vec();
self.source_version += 1; self.source_version += 1;
@@ -3690,11 +3744,13 @@ impl App {
let column = prefix let column = prefix
.rfind('\n') .rfind('\n')
.map_or(offset, |start| offset - start - 1); .map_or(offset, |start| offset - start - 1);
self.source_jump = Some(text_editor::Cursor { self.queue_source_reveal(
position: text_editor::Position { line, column }, text_editor::Cursor {
selection: None, position: text_editor::Position { line, column },
}); selection: None,
self.source_select_line = true; },
true,
);
} }
fn create_source_file(&mut self) -> Result<(), String> { fn create_source_file(&mut self) -> Result<(), String> {
+16
View File
@@ -213,6 +213,14 @@ impl App {
self.pending = None; self.pending = None;
return Task::none(); return Task::none();
} }
if self.path.is_some()
|| self.hosted.session.as_ref().is_none_or(|session| {
session.resource_id != remote.resource_id
|| session.connection.base() != request.connection.base()
})
{
self.source_workspace.reset_navigation_session();
}
self.hosted.session = Some(Session { self.hosted.session = Some(Session {
connection: request.connection.clone(), connection: request.connection.clone(),
resource_id: remote.resource_id, resource_id: remote.resource_id,
@@ -345,6 +353,14 @@ impl App {
match self.document.apply_compiled((*remote.compiled).clone()) { match self.document.apply_compiled((*remote.compiled).clone()) {
Ok(_) => { Ok(_) => {
self.document.mark_saved(remote.compiled.clone()); self.document.mark_saved(remote.compiled.clone());
if self.path.is_some()
|| self.hosted.session.as_ref().is_none_or(|session| {
session.resource_id != remote.resource_id
|| session.connection.base() != connection.base()
})
{
self.source_workspace.reset_navigation_session();
}
self.hosted.session = Some(Session { self.hosted.session = Some(Session {
connection, connection,
resource_id: remote.resource_id, resource_id: remote.resource_id,
+448
View File
@@ -0,0 +1,448 @@
//! Current draft navigation, isolated from model application and disk discovery.
use super::*;
use crate::source_navigation::{self as nav, query};
use std::sync::atomic::Ordering;
fn admission_notice(error: query::AdmissionError) -> String {
use nav::symbols::{BuildError, InputProblem, Resource};
let (limit, resource) = match error {
query::AdmissionError::Index(BuildError::Limit { limit, resource, .. }) => (limit, resource),
query::AdmissionError::Outline { error, .. } => (error.limit, match error.resource {
language::OutlineResource::SourceBytes => Resource::SourceBytes,
language::OutlineResource::Tokens => Resource::Tokens,
language::OutlineResource::Declarations => Resource::Records,
}),
query::AdmissionError::Index(BuildError::Input { problem, .. }) => return match problem {
InputProblem::NonCanonicalPath | InputProblem::DuplicateOrCaseCollidingPath =>
"Navigation needs distinct relative source paths. Check file names and include paths.".into(),
_ => "Navigation could not verify the current source locations. Correct source errors and try again.".into(),
},
};
let unit = match resource {
Resource::Files => "loaded files",
Resource::SourceBytes => "source bytes",
Resource::PathBytes => "bytes in file paths",
Resource::Tokens => "source tokens",
Resource::Records => "declarations and references",
};
format!(
"Navigation reached its limit of {limit} {unit}. Reduce the loaded source size and try again."
)
}
impl App {
pub fn source_symbol_context(&self) -> nav::SymbolContext {
nav::SymbolContext {
session: self.source_workspace.session(),
path: self.source_workspace.active.clone(),
}
}
pub fn source_symbol_message(&self, event: nav::SymbolEvent) -> Message {
Message::SourceSymbols(self.source_symbol_context(), event)
}
pub fn source_key(&self) -> query::SnapshotKey {
query::SnapshotKey {
workspace: self.source_workspace.session(),
revision: self.source_workspace.revision(),
}
}
fn with_source_input<T>(&self, use_input: impl FnOnce(query::Input<'_>) -> T) -> T {
let files: Vec<_> = self
.source_workspace
.files
.iter()
.map(|(path, buffer)| query::DraftFile {
path,
text: &buffer.text,
})
.collect();
let accepted = self.document.bundle();
let validated: Vec<_> = accepted
.files
.iter()
.map(|(path, text)| query::DraftFile { path, text })
.collect();
use_input(query::Input {
key: self.source_key(),
entry: &self.source_workspace.entry,
files: &files,
applied: self.source_workspace.applied,
validation: self
.source_workspace
.applied
.then_some(query::ValidatedSources {
entry: &accepted.entry,
files: &validated,
}),
})
}
fn source_snapshot_matches(&self, snapshot: &query::Snapshot) -> bool {
snapshot.key() == self.source_key()
&& self.with_source_input(|input| snapshot.matches(input))
}
pub fn source_navigation_available(&self) -> bool {
self.page == Page::Text
&& !self.busy
&& self.pending.is_none()
&& self.file_prompt.is_none()
&& !self.delete_pending
&& self.workflow.is_none()
&& !self.hosted.visible
&& self.model_menu.is_none()
&& self.architecture.is_none()
&& !self.behavior.has_pending()
}
/// Mounted widget IDs change when another interaction supersedes a reveal.
/// A queued focus operation therefore cannot find a subsequently reused editor.
pub fn source_editor_id(&self) -> iced::widget::Id {
iced::widget::Id::from(format!(
"source-editor-{}-{}-{}",
self.source_workspace.session(),
self.source_workspace.active,
self.source_symbols.interaction
))
}
pub fn source_reveal_ticket(&self) -> Option<Id> {
self.source_symbols
.reveal
.as_ref()
.map(|reveal| reveal.ticket)
}
pub(super) fn source_interaction(&mut self) {
self.source_symbols.interaction = Id::new_v4();
self.source_symbols.request = None;
self.source_symbols.reveal = None;
self.source_jump = None;
}
pub(super) fn queue_source_reveal(&mut self, cursor: text_editor::Cursor, select_line: bool) {
self.source_jump = Some(cursor);
self.source_select_line = select_line;
self.source_symbols.reveal = Some(nav::Reveal {
ticket: Id::new_v4(),
interaction: self.source_symbols.interaction,
raw_interaction: self.source_symbols.raw_interaction.load(Ordering::SeqCst),
snapshot: self.source_key(),
path: self.source_workspace.active.clone(),
});
}
pub(super) fn source_viewport(&mut self, ticket: Option<Id>) -> Task<Message> {
let Some(reveal) = &self.source_symbols.reveal else {
return Task::none();
};
if Some(reveal.ticket) != ticket
|| reveal.interaction != self.source_symbols.interaction
|| !nav::interaction::is_current(
&self.source_symbols.raw_interaction,
reveal.raw_interaction,
)
|| reveal.snapshot != self.source_key()
|| reveal.path != self.source_workspace.active
|| !self.source_navigation_available()
{
return Task::none();
}
let raw_interaction = reveal.raw_interaction;
self.source_symbols.reveal = None;
if let Some(cursor) = self.source_jump.take() {
if !nav::exact_cursor(self.source_workspace.text(), cursor) {
return Task::none();
}
self.source_editor.move_to(cursor);
if self.source_select_line && cursor.selection.is_none() {
self.source_editor.perform(text_editor::Action::SelectLine);
}
return nav::interaction::guarded_focus(
self.source_editor_id(),
self.source_symbols.raw_interaction.clone(),
raw_interaction,
);
}
Task::none()
}
pub(super) fn source_symbol_event(&mut self, event: nav::SymbolEvent) -> Task<Message> {
if !self.source_navigation_available() {
return Task::none();
}
match event {
nav::SymbolEvent::Close => {
self.source_symbols.open = false;
self.source_symbols.results = None;
self.source_symbols.notice = None;
}
nav::SymbolEvent::Back => {
self.source_symbols.open = true;
self.source_symbol_back();
}
nav::SymbolEvent::Choose {
stamp,
reference,
index,
} => {
let Some(results) = self.source_symbols.results.clone() else {
return Task::none();
};
if results.stamp != stamp
|| stamp.snapshot != self.source_key()
|| self
.source_symbols
.cache
.as_ref()
.is_none_or(|cache| !self.source_snapshot_matches(cache))
{
self.source_symbols.notice =
Some("Source changed. Run navigation again for current locations.".into());
return Task::none();
}
let destination = if reference {
results
.references
.get(index)
.map(|row| (&row.path, row.position, row.end_position))
} else {
results
.definitions
.get(index)
.map(|row| (&row.path, row.position, row.end_position))
};
if let Some((path, start, end)) = destination {
self.source_symbol_jump(path, start, end);
}
}
nav::SymbolEvent::Query(action) => return self.start_source_query(action),
}
Task::none()
}
fn start_source_query(&mut self, action: query::Action) -> Task<Message> {
self.source_symbols.open = true;
if !nav::interaction::is_current(
&self.source_symbols.raw_interaction,
self.source_symbols.raw_interaction.load(Ordering::SeqCst),
) {
self.source_symbols.notice = Some("Reopen this workspace to reset navigation.".into());
return Task::none();
}
if self.source_symbols.in_flight.is_some() {
self.source_symbols.notice = Some("Navigation is finishing. Try again shortly.".into());
return Task::none();
}
let cursor = self.source_editor.cursor();
let Some(offset) = nav::cursor_offset(self.source_workspace.text(), cursor) else {
self.source_symbols.notice =
Some("Place the cursor on an alias or its @ reference.".into());
return Task::none();
};
self.source_symbols.serial = match self.source_symbols.serial.checked_add(1) {
Some(serial) => serial,
None => {
self.source_workspace.reset_navigation_session();
self.source_symbols.back.clear();
self.source_symbols.cache = None;
0
}
};
let request = nav::Request {
job: Id::new_v4(),
interaction: self.source_symbols.interaction,
raw_interaction: self.source_symbols.raw_interaction.load(Ordering::SeqCst),
stamp: query::QueryStamp {
snapshot: self.source_key(),
serial: self.source_symbols.serial,
},
path: self.source_workspace.active.clone(),
offset,
cursor,
action,
};
let cache = self
.source_symbols
.cache
.as_ref()
.filter(|cache| self.source_snapshot_matches(cache))
.cloned();
let input = if cache.is_none() {
match self
.with_source_input(|input| query::admit_owned(input, query::Limits::default()))
{
Ok(input) => Some(input),
Err(error) => {
self.source_symbols.notice = Some(admission_notice(error));
return Task::none();
}
}
} else {
None
};
self.source_symbols.in_flight = Some(request.job);
self.source_symbols.request = Some(request.clone());
self.source_symbols.results = None;
self.source_symbols.notice = None;
Task::perform(
async move {
let worker_request = request.clone();
let result = tokio::task::spawn_blocking(move || {
let snapshot = match cache {
Some(cache) => cache,
None => Arc::new(
input
.expect("admitted input for uncached request")
.capture()
.map_err(admission_notice)?,
),
};
let results = snapshot
.query(query::Query {
stamp: worker_request.stamp,
path: &worker_request.path,
byte_offset: worker_request.offset,
action: worker_request.action,
})
.map_err(|error| match error {
query::QueryError::ResultEnvelopeLimit => "These result details exceed the display limit. Try literal Find for this alias.".to_owned(),
_ => "Navigation could not verify this location. Place the cursor on an alias and try again.".to_owned(),
})?;
Ok((snapshot, Arc::new(results)))
})
.await
.unwrap_or_else(|error| Err(format!("Navigation task failed: {error}")));
nav::Completion { request, result }
},
Message::SourceSymbolsReady,
)
}
pub(super) fn source_symbols_ready(&mut self, completion: nav::Completion) -> Task<Message> {
let request = completion.request;
if self.source_symbols.in_flight != Some(request.job) {
return Task::none();
}
self.source_symbols.in_flight = None;
let wanted = self
.source_symbols
.request
.take()
.is_some_and(|current| current.job == request.job)
&& request.interaction == self.source_symbols.interaction
&& request.stamp.snapshot == self.source_key()
&& nav::interaction::is_current(
&self.source_symbols.raw_interaction,
request.raw_interaction,
)
&& request.path == self.source_workspace.active
&& request.cursor == self.source_editor.cursor()
&& self.source_navigation_available();
if !wanted {
return Task::none();
}
match completion.result {
Ok((snapshot, results)) if self.source_snapshot_matches(&snapshot) => {
self.source_symbols.cache = Some(snapshot);
self.source_symbols.results = Some(results.clone());
if results.disposition == query::Disposition::Direct
&& let Some(row) = results.definitions.first()
{
self.source_symbol_jump(&row.path, row.position, row.end_position);
}
}
Ok(_) => {
self.source_symbols.notice = Some("Source changed. Run navigation again.".into())
}
Err(error) => self.source_symbols.notice = Some(error),
}
Task::none()
}
fn source_symbol_jump(&mut self, path: &str, start: query::Position, end: query::Position) {
let cursor = text_editor::Cursor {
position: text_editor::Position {
line: start.line,
column: start.byte_column,
},
selection: Some(text_editor::Position {
line: end.line,
column: end.byte_column,
}),
};
if self
.source_workspace
.files
.get(path)
.is_none_or(|buffer| !nav::exact_cursor(&buffer.text, cursor))
{
self.source_symbols.notice =
Some("That source location is no longer available. Run navigation again.".into());
return;
}
if let Some(buffer) = self
.source_workspace
.files
.get(&self.source_workspace.active)
{
let origin = nav::HistoryEntry {
session: self.source_workspace.session(),
path: self.source_workspace.active.clone(),
generation: buffer.generation(),
cursor: self.source_editor.cursor(),
};
self.source_symbols
.back
.retain(|entry| entry.session == origin.session);
if self.source_symbols.back.len() == 64 {
self.source_symbols.back.remove(0);
}
self.source_symbols.back.push(origin);
}
self.source_workspace
.switch(path, self.source_editor.cursor());
self.show_source_file(false);
self.queue_source_reveal(cursor, false);
}
fn source_symbol_back(&mut self) {
while let Some(origin) = self.source_symbols.back.pop() {
if origin.session != self.source_workspace.session() {
continue;
}
let Some(buffer) = self.source_workspace.files.get(&origin.path) else {
self.source_symbols.notice = Some("The previous file is no longer loaded.".into());
return;
};
let unchanged = origin.generation == buffer.generation();
let cursor = if unchanged {
origin.cursor
} else if origin.path == self.source_workspace.active {
self.source_editor.cursor()
} else {
buffer.cursor
};
if !nav::exact_cursor(&buffer.text, cursor) {
self.source_symbols.notice = Some(
"The previous location changed. Open the file to choose a current position."
.into(),
);
return;
}
self.source_workspace
.switch(&origin.path, self.source_editor.cursor());
self.show_source_file(false);
self.queue_source_reveal(cursor, false);
self.source_symbols.notice =
(!unchanged).then(|| "This draft changed; its current cursor was restored.".into());
return;
}
self.source_symbols.notice = Some("No previous source location in this workspace.".into());
}
}
#[cfg(test)]
mod tests;
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -785,7 +785,7 @@ fn article(topic: Topic) -> Article {
const { const {
Article { Article {
summary: "The text editor and graphical forms edit the same model. Source projects preserve file organization and comments for human review, automation and version control.", summary: "The text editor and graphical forms edit the same model. Source projects preserve file organization and comments for human review, automation and version control.",
keywords: "text textual source language syntax highlighting lint parser git aliases uuid identity rename diff merge restructuredtext spec canonical parity", keywords: "text textual source language syntax highlighting lint parser git aliases uuid identity rename diff merge restructuredtext spec canonical parity definition references lexical navigation F12 back",
sections: &[ sections: &[
walkthrough( walkthrough(
"Edit and review source", "Edit and review source",
@@ -798,6 +798,14 @@ fn article(topic: Topic) -> Article {
"Save all writes the entry and its included UTF-8 files. Review the Git diff before committing, including relationships, traces and diagram changes that belong to the same engineering edit.", "Save all writes the entry and its included UTF-8 files. Review the Git diff before committing, including relationships, traces and diagram changes that belong to the same engineering edit.",
], ],
), ),
explain(
"Follow definitions and lexical references",
"Place the caret on a declaration alias or an @reference. Choose Definition (F12) to locate its declaration, or References (Shift+F12) to list lexical uses. Choose a row when a definition is ambiguous, draft or detached. Lexical uses exclude comments and strings; they do not establish typed relationships or resolve an ambiguous alias to one declaration. Back (Alt+Left) returns to the previous source location; if that draft changed, it restores the current cursor instead of an obsolete selection. These shortcuts work while the source editor has focus; the Text toolbar also offers the actions.",
),
explain(
"Read the navigation scope",
"Queries inspect bounded snapshots of currently loaded drafts, without applying them or loading missing included files. The panel identifies partial scope, draft evidence, detached or unverified files, and alias or ID collisions. Counts show total, displayed and omitted rows. A missing result in partial scope does not establish that the whole project has no match. If sources change, stale rows are disabled; run Definition or References again. Row locations use one-based lines and UTF-8 byte columns. Navigation preserves your source drafts and the accepted model.",
),
explain( explain(
"Names, aliases and IDs serve different purposes", "Names, aliases and IDs serve different purposes",
"The displayed name is engineering prose. A stable @alias is the readable source reference and need not change when the name changes. UUID identity distinguishes the persistent record. Preserve IDs when revising the same engineering object; changing identity is a deliberate operation that affects references.", "The displayed name is engineering prose. A stable @alias is the readable source reference and need not change when the name changes. UUID identity distinguishes the persistent record. Preserve IDs when revising the same engineering object; changing identity is a deliberate operation that affects references.",
@@ -1,4 +1,9 @@
//! Literal source search and line navigation, independent of accepted model state. //! Literal source search and line navigation, independent of accepted model state.
mod controller;
pub mod interaction;
pub mod query;
pub mod symbols;
pub use controller::*;
use iced::widget::text_editor::{Cursor, Position}; use iced::widget::text_editor::{Cursor, Position};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -0,0 +1,125 @@
//! Ephemeral editor navigation; no model commands or filesystem operations.
use super::query;
use iced::widget::text_editor::{Cursor, Position};
use oa_core::Id;
use std::sync::Arc;
use std::sync::atomic::AtomicU64;
#[derive(Debug, Clone)]
pub enum SymbolEvent {
Query(query::Action),
Back,
Close,
Choose {
stamp: query::QueryStamp,
reference: bool,
index: usize,
},
}
/// Identity of the mounted source view that emitted an action. Message queues
/// may outlive that view; request-time stamping alone cannot detect replay.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SymbolContext {
pub session: Id,
pub path: String,
}
#[derive(Debug, Clone)]
pub struct HistoryEntry {
pub session: Id,
pub path: String,
pub generation: u64,
pub cursor: Cursor,
}
#[derive(Debug, Clone)]
pub struct Request {
pub job: Id,
pub interaction: Id,
pub raw_interaction: u64,
pub stamp: query::QueryStamp,
pub path: String,
pub offset: usize,
pub cursor: Cursor,
pub action: query::Action,
}
#[derive(Debug, Clone)]
pub struct Completion {
pub request: Request,
pub result: Result<(Arc<query::Snapshot>, Arc<query::Results>), String>,
}
pub struct Reveal {
pub ticket: Id,
pub interaction: Id,
pub raw_interaction: u64,
pub snapshot: query::SnapshotKey,
pub path: String,
}
pub struct SymbolState {
pub open: bool,
pub interaction: Id,
pub raw_interaction: Arc<AtomicU64>,
pub serial: u64,
pub in_flight: Option<Id>,
pub request: Option<Request>,
pub cache: Option<Arc<query::Snapshot>>,
pub results: Option<Arc<query::Results>>,
pub notice: Option<String>,
pub back: Vec<HistoryEntry>,
pub reveal: Option<Reveal>,
}
impl Default for SymbolState {
fn default() -> Self {
Self {
open: false,
interaction: Id::new_v4(),
raw_interaction: Arc::new(AtomicU64::new(0)),
serial: 0,
in_flight: None,
request: None,
cache: None,
results: None,
notice: None,
back: Vec::new(),
reveal: None,
}
}
}
/// Iced uses zero-based UTF-8 byte columns. Reject stale or split-codepoint
/// coordinates; do not normalize CRLF or silently clamp query destinations.
pub fn byte_offset(text: &str, position: Position) -> Option<usize> {
let start = if position.line == 0 {
0
} else {
text.match_indices('\n').nth(position.line - 1)?.0 + 1
};
let end = text[start..]
.find('\n')
.map_or(text.len(), |end| start + end);
let offset = start.checked_add(position.column)?;
(offset <= end && text.is_char_boundary(offset)).then_some(offset)
}
pub fn cursor_offset(text: &str, cursor: Cursor) -> Option<usize> {
let position = cursor.selection.map_or(cursor.position, |selection| {
if (selection.line, selection.column) < (cursor.position.line, cursor.position.column) {
selection
} else {
cursor.position
}
});
byte_offset(text, position)
}
pub fn exact_cursor(text: &str, cursor: Cursor) -> bool {
byte_offset(text, cursor.position).is_some()
&& cursor
.selection
.is_none_or(|position| byte_offset(text, position).is_some())
}
@@ -0,0 +1,284 @@
//! Raw input invalidation and focus checks at widget-operation execution time.
use iced::advanced::{Clipboard, Layout, Shell, Widget, layout, overlay, renderer, widget};
use iced::{Element, Event, Length, Rectangle, Size, Task, Vector, keyboard, mouse, touch};
use std::sync::{
Arc,
atomic::{AtomicU64, Ordering},
};
/// Exhaustion fails closed: a saturated clock can never authorize navigation.
/// Replace the clock with a new workspace/controller, rather than wrapping it.
pub fn is_current(clock: &AtomicU64, expected: u64) -> bool {
expected != u64::MAX && clock.load(Ordering::Acquire) == expected
}
fn invalidate(clock: &AtomicU64, event: &Event) {
if matches!(
event,
Event::Keyboard(keyboard::Event::KeyPressed { .. })
| Event::Mouse(mouse::Event::ButtonPressed(_) | mouse::Event::WheelScrolled { .. })
| Event::Touch(touch::Event::FingerPressed { .. })
| Event::Window(iced::window::Event::Unfocused)
) {
let _ = clock.fetch_update(Ordering::AcqRel, Ordering::Acquire, |value| {
Some(value.saturating_add(1))
});
}
}
/// Transparent, including overlays: invalidate before the child can capture input.
pub fn observe<'a, Message: 'a, Theme: 'a, Renderer: renderer::Renderer + 'a>(
content: Element<'a, Message, Theme, Renderer>,
clock: Arc<AtomicU64>,
) -> Element<'a, Message, Theme, Renderer> {
Element::new(Observed { content, clock })
}
struct Observed<'a, Message, Theme, Renderer> {
content: Element<'a, Message, Theme, Renderer>,
clock: Arc<AtomicU64>,
}
impl<Message, Theme, Renderer: renderer::Renderer> Widget<Message, Theme, Renderer>
for Observed<'_, Message, Theme, Renderer>
{
fn size(&self) -> Size<Length> {
self.content.as_widget().size()
}
fn size_hint(&self) -> Size<Length> {
self.content.as_widget().size_hint()
}
fn tag(&self) -> widget::tree::Tag {
self.content.as_widget().tag()
}
fn state(&self) -> widget::tree::State {
self.content.as_widget().state()
}
fn children(&self) -> Vec<widget::Tree> {
self.content.as_widget().children()
}
fn diff(&self, tree: &mut widget::Tree) {
self.content.as_widget().diff(tree);
}
fn layout(
&mut self,
tree: &mut widget::Tree,
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
self.content.as_widget_mut().layout(tree, renderer, limits)
}
fn draw(
&self,
tree: &widget::Tree,
renderer: &mut Renderer,
theme: &Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
viewport: &Rectangle,
) {
self.content
.as_widget()
.draw(tree, renderer, theme, style, layout, cursor, viewport);
}
fn operate(
&mut self,
tree: &mut widget::Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation,
) {
self.content
.as_widget_mut()
.operate(tree, layout, renderer, operation);
}
fn update(
&mut self,
tree: &mut widget::Tree,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) {
invalidate(&self.clock, event);
self.content.as_widget_mut().update(
tree, event, layout, cursor, renderer, clipboard, shell, viewport,
);
}
fn mouse_interaction(
&self,
tree: &widget::Tree,
layout: Layout<'_>,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.content
.as_widget()
.mouse_interaction(tree, layout, cursor, viewport, renderer)
}
fn overlay<'a>(
&'a mut self,
tree: &'a mut widget::Tree,
layout: Layout<'a>,
renderer: &Renderer,
viewport: &Rectangle,
translation: Vector,
) -> Option<overlay::Element<'a, Message, Theme, Renderer>> {
let clock = self.clock.clone();
self.content
.as_widget_mut()
.overlay(tree, layout, renderer, viewport, translation)
.map(|content| overlay::Element::new(Box::new(ObservedOverlay { content, clock })))
}
}
struct ObservedOverlay<'a, Message, Theme, Renderer> {
content: overlay::Element<'a, Message, Theme, Renderer>,
clock: Arc<AtomicU64>,
}
impl<Message, Theme, Renderer: renderer::Renderer> overlay::Overlay<Message, Theme, Renderer>
for ObservedOverlay<'_, Message, Theme, Renderer>
{
fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
self.content.as_overlay_mut().layout(renderer, bounds)
}
fn draw(
&self,
renderer: &mut Renderer,
theme: &Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
) {
self.content
.as_overlay()
.draw(renderer, theme, style, layout, cursor);
}
fn operate(
&mut self,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation,
) {
self.content
.as_overlay_mut()
.operate(layout, renderer, operation);
}
fn update(
&mut self,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
) {
invalidate(&self.clock, event);
self.content
.as_overlay_mut()
.update(event, layout, cursor, renderer, clipboard, shell);
}
fn mouse_interaction(
&self,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &Renderer,
) -> mouse::Interaction {
self.content
.as_overlay()
.mouse_interaction(layout, cursor, renderer)
}
fn overlay<'a>(
&'a mut self,
layout: Layout<'a>,
renderer: &Renderer,
) -> Option<overlay::Element<'a, Message, Theme, Renderer>> {
let clock = self.clock.clone();
self.content
.as_overlay_mut()
.overlay(layout, renderer)
.map(|content| overlay::Element::new(Box::new(ObservedOverlay { content, clock })))
}
fn index(&self) -> f32 {
self.content.as_overlay().index()
}
}
/// Inspect all focus owners, then focus only the mounted target. Iced executes
/// Operation::Chain synchronously, without an intervening input event. Both
/// traversals recheck the raw clock; no result message authorizes later focus.
pub fn guarded_focus<Message: Send + 'static>(
target: widget::Id,
clock: Arc<AtomicU64>,
expected: u64,
) -> Task<Message> {
widget::operate(GuardedFocus::new(target, clock, expected))
}
struct GuardedFocus {
target: widget::Id,
clock: Arc<AtomicU64>,
expected: u64,
target_count: usize,
foreign_focus: bool,
apply: bool,
}
impl GuardedFocus {
fn new(target: widget::Id, clock: Arc<AtomicU64>, expected: u64) -> Self {
Self {
target,
clock,
expected,
target_count: 0,
foreign_focus: false,
apply: false,
}
}
}
impl<Message: 'static> widget::Operation<Message> for GuardedFocus {
fn traverse(&mut self, visit: &mut dyn FnMut(&mut dyn widget::Operation<Message>)) {
if is_current(&self.clock, self.expected) {
visit(self);
}
}
fn focusable(
&mut self,
id: Option<&widget::Id>,
_: Rectangle,
state: &mut dyn widget::operation::Focusable,
) {
if !is_current(&self.clock, self.expected) {
return;
}
if id == Some(&self.target) {
self.target_count += 1;
if self.apply {
state.focus();
}
} else if state.is_focused() {
self.foreign_focus = true;
}
}
fn finish(&self) -> widget::operation::Outcome<Message> {
if !self.apply
&& self.target_count == 1
&& !self.foreign_focus
&& is_current(&self.clock, self.expected)
{
widget::operation::Outcome::Chain(Box::new(Self {
apply: true,
..Self::new(self.target.clone(), self.clock.clone(), self.expected)
}))
} else {
widget::operation::Outcome::None
}
}
}
#[cfg(all(test, debug_assertions))]
mod tests;
@@ -0,0 +1,190 @@
use super::*;
use iced::advanced::widget::operation::{Focusable, Outcome};
use iced::widget::{column, text_input};
use iced::{Point, Theme};
#[derive(Default)]
struct FocusMap(Vec<(Option<widget::Id>, Rectangle, bool)>);
impl widget::Operation for FocusMap {
fn traverse(&mut self, visit: &mut dyn FnMut(&mut dyn widget::Operation)) {
visit(self);
}
fn focusable(&mut self, id: Option<&widget::Id>, bounds: Rectangle, state: &mut dyn Focusable) {
self.0.push((id.cloned(), bounds, state.is_focused()));
}
}
struct Mounted {
element: Element<'static, (), Theme, ()>,
tree: widget::Tree,
node: layout::Node,
}
impl Mounted {
fn new(clock: Arc<AtomicU64>) -> Self {
let content = column![
text_input("Editor", "source")
.id("editor")
.on_input(|_| ())
.padding(12),
text_input("Find", "")
.id("find")
.on_input(|_| ())
.padding(12),
]
.spacing(10)
.into();
let mut element = observe(content, clock);
let mut tree = widget::Tree::new(element.as_widget());
let node = element.as_widget_mut().layout(
&mut tree,
&(),
&layout::Limits::new(Size::ZERO, Size::new(400., 200.)),
);
Self {
element,
tree,
node,
}
}
fn pass(&mut self, operation: &mut dyn widget::Operation) {
self.element.as_widget_mut().operate(
&mut self.tree,
Layout::new(&self.node),
&(),
operation,
);
}
fn run(&mut self, operation: impl widget::Operation + 'static) {
let mut next: Box<dyn widget::Operation> = Box::new(operation);
loop {
self.pass(next.as_mut());
match next.finish() {
Outcome::Chain(chained) => next = chained,
Outcome::None => break,
Outcome::Some(()) => panic!("focus must not publish an application message"),
}
}
}
fn focus(&mut self) -> FocusMap {
let mut focus = FocusMap::default();
self.pass(&mut focus);
focus
}
fn click(&mut self, id: &str) {
let bounds = self
.focus()
.0
.into_iter()
.find(|(found, _, _)| found.as_ref() == Some(&widget::Id::from(id.to_owned())))
.unwrap()
.1;
let mut messages = Vec::new();
let mut shell = Shell::new(&mut messages);
self.element.as_widget_mut().update(
&mut self.tree,
&Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)),
Layout::new(&self.node),
mouse::Cursor::Available(bounds.center()),
&(),
&mut iced::advanced::clipboard::Null,
&mut shell,
&Rectangle::with_size(Size::new(400., 200.)),
);
assert!(shell.is_event_captured());
assert!(
messages.is_empty(),
"focus-only click must not rely on App messages"
);
}
fn focused(&mut self, id: &str) -> bool {
self.focus()
.0
.into_iter()
.find(|(found, _, _)| found.as_ref() == Some(&widget::Id::from(id.to_owned())))
.unwrap()
.2
}
}
#[test]
fn captured_find_click_invalidates_without_app_message_and_preserves_focus() {
let clock = Arc::new(AtomicU64::new(0));
let mut ui = Mounted::new(clock.clone());
ui.run(GuardedFocus::new("editor".into(), clock.clone(), 0));
assert!(ui.focused("editor"));
ui.click("find");
assert!(!is_current(&clock, 0));
assert!(ui.focused("find"));
ui.run(GuardedFocus::new("editor".into(), clock.clone(), 0));
assert!(ui.focused("find"));
// Even a matching clock cannot authorize stealing another widget's focus.
ui.run(GuardedFocus::new(
"editor".into(),
clock.clone(),
clock.load(Ordering::Acquire),
));
assert!(ui.focused("find"));
assert!(!ui.focused("editor"));
}
#[test]
fn focus_rechecks_clock_between_inspection_and_application_and_missing_target_is_inert() {
let clock = Arc::new(AtomicU64::new(0));
let mut ui = Mounted::new(clock.clone());
let mut operation = GuardedFocus::new("editor".into(), clock.clone(), 0);
ui.pass(&mut operation);
let Outcome::Chain(mut apply) = <GuardedFocus as widget::Operation<()>>::finish(&operation)
else {
panic!("mounted, unopposed target must be eligible");
};
clock.store(1, Ordering::Release);
ui.pass(apply.as_mut());
assert!(!ui.focused("editor"));
ui.run(GuardedFocus::new("editor".into(), clock.clone(), 1));
assert!(ui.focused("editor"));
ui.run(GuardedFocus::new("removed-editor".into(), clock, 1));
assert!(ui.focused("editor"));
}
#[test]
fn raw_navigation_inputs_advance_but_passive_geometry_does_not_and_exhaustion_refuses() {
let clock = AtomicU64::new(0);
let events = [
Event::Keyboard(keyboard::Event::KeyPressed {
key: keyboard::Key::Named(keyboard::key::Named::ArrowLeft),
modified_key: keyboard::Key::Named(keyboard::key::Named::ArrowLeft),
physical_key: keyboard::key::Physical::Code(keyboard::key::Code::ArrowLeft),
location: keyboard::Location::Standard,
modifiers: keyboard::Modifiers::empty(),
text: None,
repeat: false,
}),
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)),
Event::Mouse(mouse::Event::WheelScrolled {
delta: mouse::ScrollDelta::Lines { x: 0., y: 1. },
}),
Event::Touch(touch::Event::FingerPressed {
id: touch::Finger(1),
position: Point::ORIGIN,
}),
Event::Window(iced::window::Event::Unfocused),
];
for (index, event) in events.iter().enumerate() {
invalidate(&clock, event);
assert_eq!(clock.load(Ordering::Acquire), index as u64 + 1);
}
invalidate(
&clock,
&Event::Mouse(mouse::Event::CursorMoved {
position: Point::ORIGIN,
}),
);
invalidate(&clock, &Event::Window(iced::window::Event::Focused));
assert!(is_current(&clock, 5));
clock.store(u64::MAX - 1, Ordering::Release);
invalidate(&clock, &events[0]);
assert!(!is_current(&clock, u64::MAX));
invalidate(&clock, &events[0]);
assert_eq!(clock.load(Ordering::Acquire), u64::MAX);
assert!(!is_current(&clock, 0));
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,989 @@
use super::*;
const PROJECT: &str = "00000000-0000-0000-0000-000000000001";
const PUMP: &str = "00000000-0000-0000-0000-000000000002";
const LINK: &str = "00000000-0000-0000-0000-000000000003";
#[derive(Clone)]
struct Fixture {
entry: String,
files: Vec<(String, String)>,
}
impl Fixture {
fn standard() -> Self {
Self {
entry: "project.arcadia".into(),
files: vec![
(
"project.arcadia".into(),
format!(
"arcadia 7;\r\nproject model \"Harbour\" id \"{PROJECT}\" {{\r\n include \"模块/活動.arcadia\";\r\n include \"links.arcadia\";\r\n}}\r\n"
),
),
(
"模块/活動.arcadia".into(),
format!(
"// 原文 remains exact\r\noa_activity pump \"泵 🚀\" id \"{PUMP}\" {{}}\r\n"
),
),
(
"links.arcadia".into(),
format!(
"// 航海\r\ninteraction connection \"流れ\" id \"{LINK}\" {{\r\n source @ // separator @pump\r\n pump;\r\n description \"船 @pump\"; target @pump;\r\n}}\r\n"
),
),
],
}
}
fn borrowed(&self) -> Vec<DraftFile<'_>> {
self.files
.iter()
.map(|(path, text)| DraftFile { path, text })
.collect()
}
fn text(&self, path: &str) -> &str {
&self
.files
.iter()
.find(|(candidate, _)| candidate == path)
.unwrap()
.1
}
fn text_mut(&mut self, path: &str) -> &mut String {
&mut self
.files
.iter_mut()
.find(|(candidate, _)| candidate == path)
.unwrap()
.1
}
fn snapshot(&self, validated: Option<&Self>, applied: bool, limits: Limits) -> Snapshot {
let current = self.borrowed();
let old = validated.map(Self::borrowed);
capture(
Input {
key: key(1),
entry: &self.entry,
files: &current,
applied,
validation: old.as_ref().map(|files| ValidatedSources {
entry: &validated.unwrap().entry,
files,
}),
},
limits,
)
.unwrap()
}
}
fn key(revision: u64) -> SnapshotKey {
SnapshotKey {
workspace: Id::from_u128(100),
revision,
}
}
fn query(snapshot: &Snapshot, path: &str, byte_offset: usize, action: Action) -> Results {
snapshot
.query(Query {
stamp: QueryStamp {
snapshot: snapshot.key(),
serial: 37,
},
path,
byte_offset,
action,
})
.unwrap()
}
fn reference_offset(fixture: &Fixture) -> usize {
fixture.text("links.arcadia").find("source @").unwrap() + "source ".len()
}
#[test]
fn exact_multifile_unicode_crlf_definition_and_repeated_lexical_references() {
let fixture = Fixture::standard();
let original = fixture.files.clone();
let snapshot = fixture.snapshot(Some(&fixture), true, Limits::default());
assert!(snapshot.scope().closure_complete && snapshot.scope().validated);
assert_eq!(
(
snapshot.scope().included_files,
snapshot.scope().detached_files
),
(3, 0)
);
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&fixture),
Action::Definition,
);
assert_eq!(result.disposition, Disposition::Direct);
assert_eq!(
(result.total_definitions, result.omitted_definitions),
(1, 0)
);
let definition = &result.definitions[0];
assert_eq!(definition.path, "模块/活動.arcadia");
assert_eq!(definition.declaration.kind, "oa_activity");
assert_eq!(definition.declaration.name.as_deref(), Some("泵 🚀"));
assert_eq!(
definition.declaration.authored_id,
Some(Id::parse_str(PUMP).unwrap())
);
assert_eq!(
definition.position,
Position {
line: 1,
byte_column: "oa_activity ".len()
}
);
assert_eq!(
&fixture.text(&definition.path)[definition.span.start..definition.span.end],
"pump"
);
let uses = query(
&snapshot,
&definition.path,
definition.span.start,
Action::References,
);
assert_eq!(uses.disposition, Disposition::LexicalReferences);
assert_eq!((uses.total_references, uses.omitted_references), (2, 0));
assert_eq!(
uses.references[0].position,
Position {
line: 3,
byte_column: 3
}
);
let target_prefix = " description \"船 @pump\"; target @";
assert_ne!(target_prefix.len(), target_prefix.chars().count());
assert_eq!(
uses.references[1].position,
Position {
line: 4,
byte_column: target_prefix.len()
}
);
for row in &uses.references {
let text = fixture.text(&row.path);
assert_eq!(&text[row.span.start..row.span.end], "pump");
assert_eq!(&text[row.marker.start..row.marker.end], "@");
let context = row.context.as_ref().unwrap();
assert_eq!(context.alias, "connection");
assert_eq!(context.kind, "interaction");
assert_eq!(context.name.as_deref(), Some("流れ"));
assert_eq!(row.evidence, Evidence::Validated);
}
assert_eq!(
uses.stamp,
QueryStamp {
snapshot: key(1),
serial: 37
}
);
assert_eq!(
fixture.files, original,
"no stabilization, newline rewrite or accepted adoption"
);
for (index, (path, text)) in original.iter().enumerate() {
let owned = snapshot.file(index).unwrap();
assert_eq!((owned.path, owned.text), (path.as_str(), text.as_str()));
}
}
#[test]
fn comments_strings_and_comment_gap_are_not_navigation_hits() {
let fixture = Fixture::standard();
let snapshot = fixture.snapshot(None, true, Limits::default());
let text = fixture.text("links.arcadia");
for offset in [
text.find("separator @pump").unwrap() + "separator ".len(),
text.find("船 @pump").unwrap() + "船 ".len(),
text.find("@ //").unwrap() + 1,
] {
let result = query(&snapshot, "links.arcadia", offset, Action::Definition);
assert_eq!(result.disposition, Disposition::NoSymbol);
assert_eq!(result.total_definitions, 0);
}
assert_eq!(
query(
&snapshot,
"links.arcadia",
text.find(" pump;").unwrap() + 3,
Action::Definition
)
.total_definitions,
1
);
let inside_utf8 = text.find('船').unwrap() + 1;
assert_eq!(
snapshot.query(Query {
stamp: QueryStamp {
snapshot: key(1),
serial: 1
},
path: "links.arcadia",
byte_offset: inside_utf8,
action: Action::Definition
}),
Err(QueryError::Query(symbols::QueryError::InvalidBytePosition))
);
}
#[test]
fn dirty_but_parseable_text_has_current_names_and_no_validated_fallback() {
let original = Fixture::standard();
let mut dirty = original.clone();
*dirty.text_mut("模块/活動.arcadia") = dirty
.text("模块/活動.arcadia")
.replace("泵 🚀", "Edited 泵\\nwith detail");
let snapshot = dirty.snapshot(Some(&original), true, Limits::default());
assert!(snapshot.scope().closure_complete);
assert!(!snapshot.scope().validated);
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&dirty),
Action::Definition,
);
assert_eq!(result.disposition, Disposition::Choices);
assert_eq!(
result.definitions[0].declaration.name.as_deref(),
Some("Edited 泵\nwith detail")
);
assert_eq!(result.definitions[0].evidence, Evidence::Draft);
assert_eq!(
snapshot.file(1).unwrap().text,
dirty.text("模块/活動.arcadia")
);
assert_ne!(
snapshot.file(1).unwrap().text,
original.text("模块/活動.arcadia")
);
}
#[test]
fn invalid_include_syntax_never_borrows_the_old_reachable_file_set() {
let original = Fixture::standard();
let mut invalid = original.clone();
*invalid.text_mut("project.arcadia") = invalid
.text("project.arcadia")
.replace("include \"links.arcadia\";", "include \"links.arcadia\"");
let snapshot = invalid.snapshot(Some(&original), true, Limits::default());
assert!(snapshot.scope().partial());
assert!(!snapshot.scope().validated);
assert!(
snapshot
.scope()
.issues
.iter()
.any(|issue| issue.kind == ScopeIssueKind::InvalidIncludes)
);
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&invalid),
Action::Definition,
);
assert_eq!(result.total_definitions, 1);
assert_eq!(result.disposition, Disposition::Choices);
assert_eq!(result.definitions[0].membership, Membership::Unverified);
}
#[test]
fn missing_include_partial_scope_does_not_resurrect_witness_text() {
let original = Fixture::standard();
let mut missing = original.clone();
missing
.files
.retain(|(path, _)| path != "模块/活動.arcadia");
let snapshot = missing.snapshot(Some(&original), true, Limits::default());
assert!(snapshot.scope().partial());
assert!(
snapshot
.scope()
.issues
.iter()
.any(|issue| issue.kind == ScopeIssueKind::MissingInclude)
);
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&missing),
Action::Definition,
);
assert_eq!(result.disposition, Disposition::NoDefinition);
assert!(result.definitions.is_empty());
assert!(
result.scope.partial(),
"zero means no loaded definition, not no project definition"
);
assert!(snapshot.file(2).is_none());
}
#[test]
fn detached_alias_and_identity_collisions_never_auto_select() {
let accepted = Fixture::standard();
for (alias, id) in [
("pump", "00000000-0000-0000-0000-000000000099"),
("other", PUMP),
] {
let mut loaded = accepted.clone();
loaded.files.push((
"detached.arcadia".into(),
format!("oa_activity {alias} \"Detached\" id \"{id}\" {{}}"),
));
let snapshot = loaded.snapshot(Some(&accepted), true, Limits::default());
assert!(snapshot.scope().validated);
assert_eq!(snapshot.scope().detached_files, 1);
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&loaded),
Action::Definition,
);
assert_eq!(result.disposition, Disposition::Choices);
if alias == "pump" {
assert_eq!(result.total_definitions, 2);
assert!(result.definitions.iter().any(
|row| row.membership == Membership::Detached && row.evidence == Evidence::Draft
));
} else {
assert_eq!(result.total_definitions, 1);
assert_eq!(
result.definitions[0].declaration.identity,
Identity::Collision { count: 2 }
);
}
}
}
#[test]
fn sole_detached_candidate_and_unapplied_equal_bytes_require_choice() {
let accepted = Fixture::standard();
let mut detached = accepted.clone();
*detached.text_mut("project.arcadia") = detached
.text("project.arcadia")
.replace(" include \"模块/活動.arcadia\";\r\n", "");
let snapshot = detached.snapshot(None, true, Limits::default());
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&detached),
Action::Definition,
);
assert_eq!(result.disposition, Disposition::Choices);
assert_eq!(result.definitions[0].membership, Membership::Detached);
let unapplied = accepted.snapshot(Some(&accepted), false, Limits::default());
assert!(unapplied.scope().closure_complete && unapplied.scope().partial());
assert!(!unapplied.scope().validated);
assert_eq!(
query(
&unapplied,
"links.arcadia",
reference_offset(&accepted),
Action::Definition
)
.disposition,
Disposition::Choices
);
}
#[test]
fn include_cycle_depth_and_aggregate_edges_are_explicit_partial_outcomes() {
let mut fixture = Fixture::standard();
fixture
.text_mut("模块/活動.arcadia")
.push_str("include \"../project.arcadia\";\r\n");
let cycle = fixture.snapshot(None, true, Limits::default());
assert!(
cycle
.scope()
.issues
.iter()
.any(|issue| issue.kind == ScopeIssueKind::IncludeCycle)
);
let fixture = Fixture::standard();
for (depth, edges, expected) in [
(0, 1024, ScopeIssueKind::IncludeDepth),
(32, 1, ScopeIssueKind::IncludeBudget),
] {
let snapshot = fixture.snapshot(
None,
true,
Limits {
include_depth: depth,
include_edges: edges,
..Limits::default()
},
);
assert!(snapshot.scope().partial());
assert!(
snapshot
.scope()
.issues
.iter()
.any(|issue| issue.kind == expected)
);
assert_eq!(
query(
&snapshot,
"links.arcadia",
reference_offset(&fixture),
Action::Definition
)
.disposition,
Disposition::Choices
);
}
}
#[test]
fn exact_snapshot_readback_rejects_same_key_byte_membership_and_evidence_changes() {
let fixture = Fixture::standard();
let files = fixture.borrowed();
let validation = Some(ValidatedSources {
entry: &fixture.entry,
files: &files,
});
let input = Input {
key: key(1),
entry: &fixture.entry,
files: &files,
applied: true,
validation,
};
let snapshot = capture(input, Limits::default()).unwrap();
assert!(snapshot.matches(input));
assert!(!snapshot.matches(Input {
key: key(2),
..input
}));
assert!(!snapshot.matches(Input {
validation: None,
..input
}));
assert!(!snapshot.matches(Input {
applied: false,
..input
}));
let mut reversed = files.clone();
reversed.reverse();
assert!(snapshot.matches(Input {
files: &reversed,
..input
}));
let mut changed = fixture.clone();
changed.text_mut("links.arcadia").push(' ');
let altered = changed.borrowed();
assert!(!snapshot.matches(Input {
files: &altered,
..input
}));
let missing = &files[..files.len() - 1];
assert!(!snapshot.matches(Input {
files: missing,
..input
}));
let duplicated = [files[0], files[0], files[2]];
assert!(!snapshot.matches(Input {
files: &duplicated,
..input
}));
assert_eq!(
snapshot.query(Query {
stamp: QueryStamp {
snapshot: key(2),
serial: 37
},
path: "links.arcadia",
byte_offset: 0,
action: Action::Definition
}),
Err(QueryError::Query(symbols::QueryError::StaleSnapshot))
);
}
#[test]
fn omitted_rows_are_counted_before_result_allocation_and_never_confer_uniqueness() {
let fixture = Fixture::standard();
let snapshot = fixture.snapshot(
Some(&fixture),
true,
Limits {
result_rows: 2,
..Limits::default()
},
);
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&fixture),
Action::References,
);
assert_eq!((result.total_definitions, result.total_references), (1, 2));
assert_eq!(
(
result.definitions.len(),
result.references.len(),
result.omitted_references
),
(1, 1, 1)
);
let zero = fixture.snapshot(
Some(&fixture),
true,
Limits {
result_rows: 0,
..Limits::default()
},
);
let result = query(
&zero,
"links.arcadia",
reference_offset(&fixture),
Action::Definition,
);
assert_eq!(
(
result.definitions.len(),
result.total_definitions,
result.omitted_definitions
),
(0, 1, 1)
);
assert_eq!(result.disposition, Disposition::Choices);
let envelope = fixture.snapshot(
Some(&fixture),
true,
Limits {
result_bytes: 0,
..Limits::default()
},
);
assert_eq!(
envelope.query(Query {
stamp: QueryStamp {
snapshot: key(1),
serial: 1
},
path: "links.arcadia",
byte_offset: reference_offset(&fixture),
action: Action::Definition
}),
Err(QueryError::ResultEnvelopeLimit)
);
}
#[test]
fn large_display_name_cannot_escape_the_owned_row_string_budget() {
let mut fixture = Fixture::standard();
*fixture.text_mut("模块/活動.arcadia") = fixture
.text("模块/活動.arcadia")
.replace("泵 🚀", &"長".repeat(8192));
let original = fixture.files.clone();
let snapshot = fixture.snapshot(
None,
true,
Limits {
result_bytes: 64,
..Limits::default()
},
);
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&fixture),
Action::Definition,
);
assert_eq!(
(result.total_definitions, result.omitted_definitions),
(1, 1)
);
assert!(result.definitions.is_empty());
assert_eq!(result.disposition, Disposition::Choices);
assert_eq!(fixture.files, original);
}
#[test]
fn validation_witness_must_match_entry_and_complete_included_file_set() {
let fixture = Fixture::standard();
for mutation in 0..3 {
let mut witness = fixture.clone();
match mutation {
0 => witness.entry = "other.arcadia".into(),
1 => {
witness.files.pop();
}
_ => witness.files.push(("unused.arcadia".into(), String::new())),
}
let snapshot = fixture.snapshot(Some(&witness), true, Limits::default());
assert!(snapshot.scope().closure_complete);
assert!(!snapshot.scope().validated);
assert_eq!(
query(
&snapshot,
"links.arcadia",
reference_offset(&fixture),
Action::Definition
)
.disposition,
Disposition::Choices
);
}
}
#[test]
fn raw_aggregate_limits_refuse_before_outline_or_copied_snapshot() {
// Token budget zero and malformed paths/text would fail later. Raw byte/path
// limits must win, including a large second file; no partial Snapshot exists.
let large = "not a model \0".repeat(16_384);
let files = [
DraftFile {
path: "../bad.arcadia",
text: "?",
},
DraftFile {
path: "large.arcadia",
text: &large,
},
];
let input = Input {
key: key(1),
entry: "project.arcadia",
files: &files,
applied: true,
validation: None,
};
for (resource, files_limit, bytes_limit, paths_limit) in [
(symbols::Resource::Files, 1, usize::MAX, usize::MAX),
(symbols::Resource::SourceBytes, 8, 1, usize::MAX),
(symbols::Resource::PathBytes, 8, usize::MAX, 1),
] {
let limits = Limits {
index: symbols::Limits {
files: files_limit,
source_bytes: bytes_limit,
path_bytes: paths_limit,
tokens: 0,
records: 0,
},
..Limits::default()
};
assert!(
matches!(capture(input, limits), Err(AdmissionError::Index(symbols::BuildError::Limit { resource: actual, .. })) if actual == resource)
);
}
assert_eq!(files[1].text, large);
}
#[test]
fn token_declaration_and_live_reference_limits_are_aggregate_not_per_file() {
let files = [
DraftFile {
path: "a.arcadia",
text: "oa_activity a \"A\" {}",
},
DraftFile {
path: "b.arcadia",
text: "oa_activity b \"B\" {}",
},
];
let input = Input {
key: key(1),
entry: "a.arcadia",
files: &files,
applied: false,
validation: None,
};
let limits = Limits {
index: symbols::Limits {
tokens: 10,
..Limits::default().index
},
..Limits::default()
};
assert!(matches!(
capture(input, limits),
Err(AdmissionError::Outline {
file: 1,
error: language::OutlineLimit {
resource: language::OutlineResource::Tokens,
..
}
})
));
let limits = Limits {
index: symbols::Limits {
records: 1,
..Limits::default().index
},
..Limits::default()
};
assert!(matches!(
capture(input, limits),
Err(AdmissionError::Outline {
file: 1,
error: language::OutlineLimit {
resource: language::OutlineResource::Declarations,
..
}
})
));
let use_files = [
files[0],
DraftFile {
path: "uses.arcadia",
text: "source @a; target @a; // @a ignored\n",
},
];
let limits = Limits {
index: symbols::Limits {
records: 2,
..Limits::default().index
},
..Limits::default()
};
assert!(matches!(
capture(
Input {
files: &use_files,
..input
},
limits
),
Err(AdmissionError::Index(symbols::BuildError::Limit {
resource: symbols::Resource::Records,
observed_at_least: 3,
..
}))
));
}
#[test]
fn missing_and_noncanonical_authored_ids_remain_draft_spans_without_generated_anchors() {
let fixture = Fixture::standard();
for replacement in [
String::new(),
" id \"00000000000000000000000000000002\"".into(),
] {
let mut draft = fixture.clone();
let original_id = format!(" id \"{PUMP}\"");
*draft.text_mut("模块/活動.arcadia") = draft
.text("模块/活動.arcadia")
.replace(&original_id, &replacement);
draft
.text_mut("模块/活動.arcadia")
.push_str(&format!("// Historical UUID {PUMP} and @pump\r\n"));
let before = draft.files.clone();
let snapshot = draft.snapshot(None, false, Limits::default());
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&draft),
Action::Definition,
);
assert_eq!(result.definitions[0].declaration.authored_id, None);
assert_eq!(
result.definitions[0].declaration.identity,
Identity::Missing
);
assert_eq!(result.disposition, Disposition::Choices);
assert_eq!(draft.files, before);
assert_eq!(
snapshot.file(1).unwrap().text,
draft.text("模块/活動.arcadia")
);
}
}
#[test]
fn keyword_alias_and_loaded_path_case_collisions_use_reviewed_index_rules() {
let mut fixture = Fixture::standard();
for (_, text) in &mut fixture.files {
*text = text.replace("pump", "source");
}
let snapshot = fixture.snapshot(None, true, Limits::default());
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&fixture),
Action::Definition,
);
assert_eq!(result.alias.as_deref(), Some("source"));
assert_eq!(result.total_definitions, 1);
fixture.files.push(("LINKS.arcadia".into(), String::new()));
let files = fixture.borrowed();
assert!(matches!(
capture(
Input {
key: key(1),
entry: &fixture.entry,
files: &files,
applied: true,
validation: None
},
Limits::default()
),
Err(AdmissionError::Index(symbols::BuildError::Input {
problem: symbols::InputProblem::DuplicateOrCaseCollidingPath,
..
}))
));
}
#[test]
fn owned_request_moves_exact_text_into_worker_snapshot_and_matches_sync_results() {
let fixture = Fixture::standard();
let files = fixture.borrowed();
let input = Input {
key: key(1),
entry: &fixture.entry,
files: &files,
applied: true,
validation: Some(ValidatedSources {
entry: &fixture.entry,
files: &files,
}),
};
let owned = admit_owned(input, Limits::default()).unwrap();
let allocations: Vec<_> = owned.files.iter().map(|file| file.text.as_ptr()).collect();
let snapshot = owned.capture().unwrap();
for (file, allocation) in allocations.iter().enumerate() {
assert_eq!(
snapshot.file(file).unwrap().text.as_ptr(),
*allocation,
"worker moves the one current-text copy"
);
}
assert!(snapshot.matches(input));
let synchronous = capture(input, Limits::default()).unwrap();
assert_eq!(
query(
&snapshot,
"links.arcadia",
reference_offset(&fixture),
Action::References
),
query(
&synchronous,
"links.arcadia",
reference_offset(&fixture),
Action::References
)
);
let mut edited = fixture.clone();
edited
.text_mut("links.arcadia")
.push_str("// edited after request\r\n");
let changed = edited.borrowed();
assert!(!snapshot.matches(Input {
files: &changed,
..input
}));
assert!(!snapshot.matches(Input {
validation: None,
..input
}));
}
#[test]
fn owned_request_checks_raw_limits_immediately_and_extracts_only_on_worker() {
let fixture = Fixture::standard();
let files = fixture.borrowed();
let input = Input {
key: key(1),
entry: &fixture.entry,
files: &files,
applied: true,
validation: None,
};
let no_tokens = Limits {
index: symbols::Limits {
tokens: 0,
..Limits::default().index
},
..Limits::default()
};
let owned = admit_owned(input, no_tokens).expect("request admission does not lex or parse");
assert!(matches!(
owned.capture(),
Err(AdmissionError::Outline {
file: 0,
error: language::OutlineLimit {
resource: language::OutlineResource::Tokens,
..
}
})
));
let no_bytes = Limits {
index: symbols::Limits {
source_bytes: 1,
..Limits::default().index
},
..Limits::default()
};
assert!(matches!(
admit_owned(input, no_bytes),
Err(AdmissionError::Index(symbols::BuildError::Limit {
resource: symbols::Resource::SourceBytes,
..
}))
));
assert_eq!(files[1].text, fixture.text("模块/活動.arcadia"));
}
#[test]
fn owned_validation_proof_preserves_full_witness_count_and_partial_scope() {
let accepted = Fixture::standard();
for missing_include in [false, true] {
let mut current = accepted.clone();
current
.files
.retain(|(path, _)| path != "模块/活動.arcadia");
if !missing_include {
*current.text_mut("project.arcadia") = current
.text("project.arcadia")
.replace(" include \"模块/活動.arcadia\";\r\n", "");
}
let files = current.borrowed();
let old = accepted.borrowed();
let input = Input {
key: key(1),
entry: &current.entry,
files: &files,
applied: true,
validation: Some(ValidatedSources {
entry: &accepted.entry,
files: &old,
}),
};
let snapshot = admit_owned(input, Limits::default())
.unwrap()
.capture()
.unwrap();
assert_eq!(snapshot.scope().closure_complete, !missing_include);
assert!(
!snapshot.scope().validated,
"the old witness is not silently reduced to matching loaded files"
);
let result = query(
&snapshot,
"links.arcadia",
reference_offset(&current),
Action::Definition,
);
assert_eq!(result.disposition, Disposition::NoDefinition);
assert!(snapshot.matches(input));
}
}
File diff suppressed because it is too large Load Diff
+217 -4
View File
@@ -1,7 +1,7 @@
//! Per-file drafts and navigation. Accepted model/source history lives in Document. //! Per-file drafts and navigation. Accepted model/source history lives in Document.
use iced::widget::text_editor::Cursor; use iced::widget::text_editor::Cursor;
use oa_core::{ use oa_core::{
language, Id, language,
source_project::{self, CompiledSourceProject, ProjectLimits, SourceBundle, SourceDiagnostic}, source_project::{self, CompiledSourceProject, ProjectLimits, SourceBundle, SourceDiagnostic},
}; };
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
@@ -86,6 +86,7 @@ pub struct Buffer {
pub cursor: Cursor, pub cursor: Cursor,
past: Vec<String>, past: Vec<String>,
future: Vec<String>, future: Vec<String>,
generation: u64,
} }
impl Buffer { impl Buffer {
@@ -99,14 +100,20 @@ impl Buffer {
}, },
past: Vec::new(), past: Vec::new(),
future: Vec::new(), future: Vec::new(),
generation: 0,
} }
} }
pub fn dirty(&self) -> bool { pub fn dirty(&self) -> bool {
self.text != self.baseline self.text != self.baseline
} }
pub fn generation(&self) -> u64 {
self.generation
}
} }
pub struct Workspace { pub struct Workspace {
session: Id,
revision: u64,
pub entry: String, pub entry: String,
pub active: String, pub active: String,
pub files: BTreeMap<String, Buffer>, pub files: BTreeMap<String, Buffer>,
@@ -117,6 +124,35 @@ pub struct Workspace {
} }
impl Workspace { impl Workspace {
/// Ephemeral editor identity, never a model identity or recovery payload.
pub fn session(&self) -> Id {
self.session
}
pub fn revision(&self) -> u64 {
self.revision
}
fn advance(&mut self) -> u64 {
if let Some(revision) = self.revision.checked_add(1) {
self.revision = revision;
} else {
self.reset_navigation_session();
}
self.revision
}
/// A changed filesystem root must not reuse queued navigation from Save As.
pub fn reset_navigation_session(&mut self) {
self.session = Id::new_v4();
self.revision = 0;
for buffer in self.files.values_mut() {
buffer.generation = 0;
}
}
pub fn set_reachable(&mut self, reachable: BTreeSet<String>) {
if self.reachable != reachable {
self.advance();
self.reachable = reachable;
}
}
pub fn recovery_snapshot(&self) -> RecoveryWorkspace { pub fn recovery_snapshot(&self) -> RecoveryWorkspace {
RecoveryWorkspace { RecoveryWorkspace {
entry: self.entry.clone(), entry: self.entry.clone(),
@@ -136,6 +172,8 @@ impl Workspace {
pub fn from_recovery(saved: RecoveryWorkspace) -> Result<Self, String> { pub fn from_recovery(saved: RecoveryWorkspace) -> Result<Self, String> {
saved.validate()?; saved.validate()?;
Ok(Self { Ok(Self {
session: Id::new_v4(),
revision: 0,
entry: saved.entry, entry: saved.entry,
active: saved.active, active: saved.active,
files: saved files: saved
@@ -154,6 +192,8 @@ impl Workspace {
} }
pub fn new(bundle: &SourceBundle, applied: bool) -> Self { pub fn new(bundle: &SourceBundle, applied: bool) -> Self {
Self { Self {
session: Id::new_v4(),
revision: 0,
entry: bundle.entry.clone(), entry: bundle.entry.clone(),
active: bundle.entry.clone(), active: bundle.entry.clone(),
files: bundle files: bundle
@@ -191,11 +231,20 @@ impl Workspace {
} }
} }
pub fn edit(&mut self, text: String, cursor: Cursor) { pub fn edit(&mut self, text: String, cursor: Cursor) {
let changed = self.files.get(&self.active).is_none_or(|b| b.text != text);
let generation = if changed {
self.advance()
} else {
self.revision
};
let buffer = self let buffer = self
.files .files
.entry(self.active.clone()) .entry(self.active.clone())
.or_insert_with(|| Buffer::new(String::new())); .or_insert_with(|| Buffer::new(String::new()));
buffer.cursor = cursor; buffer.cursor = cursor;
if changed {
buffer.generation = generation;
}
if text != buffer.text { if text != buffer.text {
buffer.past.push(std::mem::replace(&mut buffer.text, text)); buffer.past.push(std::mem::replace(&mut buffer.text, text));
if buffer.past.len() > 100 { if buffer.past.len() > 100 {
@@ -268,6 +317,8 @@ impl Workspace {
} else { } else {
buffer.future.push(previous); buffer.future.push(previous);
} }
let generation = self.advance();
self.files.get_mut(&self.active).unwrap().generation = generation;
self.trim_history(DRAFT_HISTORY_BYTES); self.trim_history(DRAFT_HISTORY_BYTES);
true true
} }
@@ -281,6 +332,7 @@ impl Workspace {
} }
} }
pub fn accept(&mut self, bundle: &SourceBundle) { pub fn accept(&mut self, bundle: &SourceBundle) {
let generation = self.advance();
if self.entry != bundle.entry if self.entry != bundle.entry
&& !bundle.files.contains_key(&self.entry) && !bundle.files.contains_key(&self.entry)
&& self.files.get(&self.entry).is_some_and(|b| !b.dirty()) && self.files.get(&self.entry).is_some_and(|b| !b.dirty())
@@ -291,7 +343,13 @@ impl Workspace {
self.reachable = bundle.files.keys().cloned().collect(); self.reachable = bundle.files.keys().cloned().collect();
for (path, text) in &bundle.files { for (path, text) in &bundle.files {
let cursor = self.files.get(path).map(|b| b.cursor); let cursor = self.files.get(path).map(|b| b.cursor);
let previous_generation = self
.files
.get(path)
.filter(|b| b.text == *text)
.map(|b| b.generation);
let mut buffer = Buffer::new(text.clone()); let mut buffer = Buffer::new(text.clone());
buffer.generation = previous_generation.unwrap_or(generation);
if let Some(cursor) = cursor { if let Some(cursor) = cursor {
buffer.cursor = cursor; buffer.cursor = cursor;
} }
@@ -303,10 +361,22 @@ impl Workspace {
self.applied = true; self.applied = true;
} }
pub fn discovered(&mut self, bundle: &SourceBundle, reachable: BTreeSet<String>) { pub fn discovered(&mut self, bundle: &SourceBundle, reachable: BTreeSet<String>) {
let changed = self.reachable != reachable
|| bundle
.files
.keys()
.any(|path| !self.files.contains_key(path));
let generation = if changed {
self.advance()
} else {
self.revision
};
for (path, text) in &bundle.files { for (path, text) in &bundle.files {
self.files self.files.entry(path.clone()).or_insert_with(|| {
.entry(path.clone()) let mut buffer = Buffer::new(text.clone());
.or_insert_with(|| Buffer::new(text.clone())); buffer.generation = generation;
buffer
});
} }
self.reachable = reachable; self.reachable = reachable;
} }
@@ -314,6 +384,7 @@ impl Workspace {
if self.reachable.contains(path) || self.files.get(path).is_none_or(Buffer::dirty) { if self.reachable.contains(path) || self.files.get(path).is_none_or(Buffer::dirty) {
return false; return false;
} }
self.advance();
self.files.remove(path); self.files.remove(path);
if self.active == path { if self.active == path {
self.active = self.entry.clone(); self.active = self.entry.clone();
@@ -376,6 +447,148 @@ pub fn lint(bundle: &SourceBundle) -> Vec<SourceDiagnostic> {
mod tests { mod tests {
use super::*; use super::*;
use oa_core::Project; use oa_core::Project;
#[test]
fn fresh_session_cannot_reuse_a_retained_buffer_generation() {
let bundle = SourceBundle {
entry: "main.arcadia".into(),
files: BTreeMap::from([
("main.arcadia".into(), "first".into()),
("other.arcadia".into(), "other".into()),
]),
};
let mut workspace = Workspace::new(&bundle, true);
let cursor = workspace.files["main.arcadia"].cursor;
workspace.edit("second".into(), cursor);
workspace.reset_navigation_session();
let before = workspace.files["main.arcadia"].generation();
workspace.edit("third".into(), cursor);
assert_ne!(workspace.files["main.arcadia"].generation(), before);
workspace.switch("other.arcadia", cursor);
workspace.revision = u64::MAX;
workspace.edit("changed other".into(), cursor);
let after_wrap = workspace.files["main.arcadia"].generation();
workspace.switch("main.arcadia", cursor);
workspace.edit("fourth".into(), cursor);
assert_ne!(workspace.files["main.arcadia"].generation(), after_wrap);
assert!(workspace.undo(false));
assert_eq!(workspace.text(), "third");
}
#[test]
fn navigation_versions_distinguish_reopened_recovered_and_changed_drafts() {
let bundle = SourceBundle {
entry: "project.arcadia".into(),
files: BTreeMap::from([
("project.arcadia".into(), "entry\r\n".into()),
("part.arcadia".into(), "雨 draft\r\n".into()),
]),
};
let mut workspace = Workspace::new(&bundle, true);
let reopened = Workspace::new(&bundle, true);
let recovered = Workspace::from_recovery(workspace.recovery_snapshot()).unwrap();
assert_ne!(workspace.session(), reopened.session());
assert_ne!(workspace.session(), recovered.session());
assert_eq!(workspace.bundle(), recovered.bundle());
let saved = serde_json::to_value(workspace.recovery_snapshot()).unwrap();
assert!(saved.get("session").is_none() && saved.get("revision").is_none());
let cursor = Cursor {
position: iced::widget::text_editor::Position { line: 0, column: 3 },
selection: None,
};
let revision = workspace.revision();
workspace.edit(workspace.text().into(), cursor);
assert_eq!(
workspace.revision(),
revision,
"selection is not a text change"
);
workspace.switch("part.arcadia", cursor);
assert_eq!(
workspace.revision(),
revision,
"switching retains the snapshot"
);
let untouched = workspace.files["project.arcadia"].generation();
workspace.edit("雨 unfinished !\r\n".into(), cursor);
let edited = workspace.files["part.arcadia"].generation();
assert!(workspace.revision() > revision);
assert_eq!(workspace.files["project.arcadia"].generation(), untouched);
assert!(workspace.undo(false));
assert_eq!(workspace.bundle(), bundle);
assert!(workspace.files["part.arcadia"].generation() > edited);
assert!(workspace.undo(true));
assert_eq!(workspace.text(), "雨 unfinished !\r\n");
let previous_session = workspace.session();
let previous_text = workspace.bundle();
workspace.reset_navigation_session();
assert_ne!(workspace.session(), previous_session);
assert_eq!(workspace.bundle(), previous_text);
assert!(
workspace.undo(false),
"session reset preserves text history"
);
}
#[test]
fn navigation_scope_changes_invalidate_without_changing_unchanged_positions() {
let bundle = SourceBundle {
entry: "project.arcadia".into(),
files: BTreeMap::from([
("project.arcadia".into(), "entry".into()),
("part.arcadia".into(), "part".into()),
]),
};
let mut workspace = Workspace::new(&bundle, true);
let entry_generation = workspace.files[&bundle.entry].generation();
let initial_revision = workspace.revision();
workspace.set_reachable(BTreeSet::from([bundle.entry.clone()]));
assert!(workspace.revision() > initial_revision);
let membership_revision = workspace.revision();
workspace.set_reachable(workspace.reachable.clone());
assert_eq!(workspace.revision(), membership_revision);
assert!(workspace.discard_detached("part.arcadia"));
assert!(workspace.revision() > membership_revision);
let closed_revision = workspace.revision();
workspace.discovered(&bundle, BTreeSet::from([bundle.entry.clone()]));
assert!(workspace.revision() > closed_revision);
assert_eq!(
workspace.files[&bundle.entry].generation(),
entry_generation
);
assert!(workspace.files["part.arcadia"].generation() > closed_revision);
let discovered_revision = workspace.revision();
workspace.discovered(&bundle, workspace.reachable.clone());
assert_eq!(workspace.revision(), discovered_revision);
workspace.accept(&bundle);
assert!(
workspace.revision() > discovered_revision,
"validation evidence changed"
);
assert_eq!(
workspace.files[&bundle.entry].generation(),
entry_generation
);
assert_eq!(workspace.bundle(), bundle);
}
#[test]
fn navigation_revision_wrap_cannot_reuse_an_old_workspace_key() {
let bundle = SourceBundle {
entry: "project.arcadia".into(),
files: BTreeMap::from([("project.arcadia".into(), "original".into())]),
};
let mut workspace = Workspace::new(&bundle, true);
workspace.revision = u64::MAX;
let before = workspace.session();
let cursor = workspace.files[&bundle.entry].cursor;
workspace.edit("changed".into(), cursor);
assert_ne!(workspace.session(), before);
assert_eq!(workspace.revision(), 0);
assert!(workspace.undo(false));
assert_eq!(workspace.bundle(), bundle);
}
#[test] #[test]
fn draft_history_budget_covers_inactive_files_without_discarding_drafts() { fn draft_history_budget_covers_inactive_files_without_discarding_drafts() {
let bundle = SourceBundle { let bundle = SourceBundle {
+4 -2
View File
@@ -377,7 +377,8 @@ fn source_navigation_waits_for_editor_layout_and_cancels_on_edit() {
send(&mut app, Message::SourceForSelection); send(&mut app, Message::SourceForSelection);
assert_eq!(app.page, Page::Text); assert_eq!(app.page, Page::Text);
assert!(app.source_jump.is_some()); assert!(app.source_jump.is_some());
send(&mut app, Message::SourceViewport); let ticket = app.source_reveal_ticket();
send(&mut app, Message::SourceViewport(ticket));
assert!(app.source_jump.is_none()); assert!(app.source_jump.is_none());
send(&mut app, Message::SourceForSelection); send(&mut app, Message::SourceForSelection);
assert!(app.source_jump.is_some()); assert!(app.source_jump.is_some());
@@ -409,7 +410,8 @@ fn source_find_navigates_an_invalid_draft_without_applying_or_losing_it() {
cursor.selection, cursor.selection,
Some(text_editor::Position { line: 0, column: 9 }) Some(text_editor::Position { line: 0, column: 9 })
); );
send(&mut app, Message::SourceViewport); let ticket = app.source_reveal_ticket();
send(&mut app, Message::SourceViewport(ticket));
assert_eq!(app.source_editor.cursor(), cursor); assert_eq!(app.source_editor.cursor(), cursor);
send( send(
&mut app, &mut app,
+76 -6
View File
@@ -1,3 +1,4 @@
mod source_symbols;
pub(crate) mod traceability; pub(crate) mod traceability;
use crate::{ use crate::{
app::{App, Choice, FileOperation, Message, Page, Pending}, app::{App, Choice, FileOperation, Message, Page, Pending},
@@ -1113,8 +1114,12 @@ fn source(app: &App) -> View<'_, Message> {
} }
} }
let editor = widget::text_editor(&app.source_editor) let editor = widget::text_editor(&app.source_editor)
.id("source-editor") .id(app.source_editor_id())
.on_action(Message::SourceEdit) .on_action(Message::SourceEdit)
.key_binding({
let context = app.source_symbol_context();
move |press| source_binding(press, &context)
})
.font(Font::MONOSPACE) .font(Font::MONOSPACE)
.size(14) .size(14)
.padding(16) .padding(16)
@@ -1123,8 +1128,7 @@ fn source(app: &App) -> View<'_, Message> {
app.source_snapshot.clone(), app.source_snapshot.clone(),
crate::highlight::format, crate::highlight::format,
); );
column![ let header = container(
container(
column![ column![
row![ row![
container(heading( container(heading(
@@ -1167,17 +1171,83 @@ fn source(app: &App) -> View<'_, Message> {
"Undo text affects this file's draft. Model Undo restores accepted files together (100 changes / about 32 MiB)." "Undo text affects this file's draft. Model Undo restores accepted files together (100 changes / about 32 MiB)."
}), }),
navigation, navigation,
row![
action("Definition · F12", app.source_symbol_message(crate::source_navigation::SymbolEvent::Query(crate::source_navigation::query::Action::Definition))),
action("References · Shift F12", app.source_symbol_message(crate::source_navigation::SymbolEvent::Query(crate::source_navigation::query::Action::References))),
button(text("Back · Alt ←").size(12)).padding([8, 10]).style(style::nav)
.on_press_maybe((app.source_symbols.back.iter().any(|entry| entry.session == app.source_workspace.session())).then(|| app.source_symbol_message(crate::source_navigation::SymbolEvent::Back))),
].spacing(7),
scrollable(diagnostics) scrollable(diagnostics)
.height((visible_diagnostics as f32 * 32.).min(132.)) .height((visible_diagnostics as f32 * 32.).min(132.))
] ]
.spacing(12) .spacing(12)
) )
.padding(18), .padding(18);
widget::sensor(editor).key((app.source_workspace.active.clone(),app.source_jump)) let editor = widget::sensor(editor)
.on_show(|_| Message::SourceViewport).on_resize(|_| Message::SourceViewport) .key((
app.source_workspace.active.clone(),
app.source_reveal_ticket(),
))
.on_show({
let ticket = app.source_reveal_ticket();
move |_| Message::SourceViewport(ticket)
})
.on_resize({
let ticket = app.source_reveal_ticket();
move |_| Message::SourceViewport(ticket)
});
let workspace: View<'_, Message> = if app.source_symbols.open {
row![
container(editor).width(Fill).height(Fill),
container(scrollable(source_symbols::panel(app)))
.width(300)
.height(Fill),
]
.height(Fill)
.into()
} else {
container(editor).width(Fill).height(Fill).into()
};
column![
container(scrollable(header)).max_height((app.window_size.height * 0.42).max(180.)),
workspace,
] ]
.height(Fill)
.into() .into()
} }
fn source_binding(
press: widget::text_editor::KeyPress,
context: &crate::source_navigation::SymbolContext,
) -> Option<widget::text_editor::Binding<Message>> {
use crate::source_navigation::{SymbolEvent, query::Action};
use iced::keyboard::{Key, key::Named};
use widget::text_editor::{Binding, Status};
if matches!(press.status, Status::Focused { .. })
&& !press.modifiers.control()
&& !press.modifiers.logo()
{
let event = match &press.key {
Key::Named(Named::F12) if !press.modifiers.alt() => {
Some(SymbolEvent::Query(if press.modifiers.shift() {
Action::References
} else {
Action::Definition
}))
}
Key::Named(Named::ArrowLeft) if press.modifiers.alt() && !press.modifiers.shift() => {
Some(SymbolEvent::Back)
}
_ => None,
};
if let Some(event) = event {
return Some(Binding::Custom(Message::SourceSymbols(
context.clone(),
event,
)));
}
}
Binding::from_key_press(press)
}
fn checks(app: &App) -> View<'_, Message> { fn checks(app: &App) -> View<'_, Message> {
let issues = &app.model_issues; let issues = &app.model_issues;
let mut out = column![heading( let mut out = column![heading(
@@ -0,0 +1,260 @@
use crate::{
app::{App, Message},
source_navigation::{
SymbolEvent,
query::{self, Declaration, Disposition, Evidence, Identity, Membership, Position},
},
style,
};
use iced::{
Element, Fill,
widget::{Space, button, column, container, row, scrollable, text, tooltip},
};
pub(super) fn panel(app: &App) -> Element<'_, Message> {
let state = &app.source_symbols;
if !state.open
|| (state.results.is_none() && state.in_flight.is_none() && state.notice.is_none())
{
return column![].into();
}
let title = state.results.as_ref().map_or_else(
|| "Source symbols".to_owned(),
|results| {
let action = match results.action {
query::Action::Definition => "Definitions",
query::Action::References => "References",
};
results.alias.as_ref().map_or_else(
|| action.to_owned(),
|alias| format!("{action} · @{}", preview(alias, 40)),
)
},
);
let mut content = column![
row![
text(title).size(13),
Space::new().width(Fill),
button(text("Close").size(11))
.padding([3, 8])
.style(style::nav)
.on_press(app.source_symbol_message(SymbolEvent::Close)),
]
.align_y(iced::Center)
]
.spacing(5);
if let Some(notice) = &state.notice {
content = content.push(super::label(preview(notice, 240)));
}
if state.in_flight.is_some() {
content = content.push(super::label("Finding source symbols…"));
} else if let Some(results) = &state.results {
let stale = results.stamp.snapshot != app.source_key();
if stale {
content = content.push(super::label(
"Stale results — source changed. Run Definition or References again.",
));
}
let scope = &results.scope;
content = content.push(super::label(format!(
"{} · {} · {} included / {} detached / {} unverified files · {} scope issues",
if scope.partial() {
"Partial scope"
} else {
"Complete include scope"
},
if !scope.applied {
"Unapplied drafts"
} else if scope.validated {
"Validated sources"
} else {
"Draft sources"
},
scope.included_files,
scope.detached_files,
scope.unverified_files,
scope.issues.len(),
)));
let explanation = match results.disposition {
Disposition::NoSymbol => "Place the caret on a declaration alias or an @reference.",
Disposition::NoDefinition => "No matching declaration in the loaded sources.",
Disposition::Choices => {
"Choose a declaration; draft and detached candidates need an explicit choice."
}
Disposition::Direct => "Definition in the current sources.",
Disposition::LexicalReferences => {
"Lexical uses of this alias; these do not establish a semantic target."
}
};
content = content.push(super::label(explanation));
if results.total_definitions > 1 {
content = content.push(super::label(format!(
"Alias collision: {} declarations. Uses are not attributed to a single declaration.",
results.total_definitions,
)));
}
let enabled = !stale && !app.busy;
let mut rows = column![super::label(counts(
"Declarations",
results.definitions.len(),
results.total_definitions,
results.omitted_definitions,
))]
.spacing(4);
for (index, definition) in results.definitions.iter().enumerate() {
rows = rows.push(location_row(
declaration_title(&definition.declaration),
&definition.path,
definition.position,
provenance(
definition.membership,
definition.evidence,
definition.declaration.identity,
false,
),
enabled.then(|| {
app.source_symbol_message(SymbolEvent::Choose {
stamp: results.stamp,
reference: false,
index,
})
}),
));
}
rows = rows.push(super::label(counts(
"Lexical uses",
results.references.len(),
results.total_references,
results.omitted_references,
)));
for (index, reference) in results.references.iter().enumerate() {
let title = reference.context.as_ref().map_or_else(
|| format!("@{} · lexical use", preview(&reference.alias, 48)),
|context| {
format!(
"@{} · inside {}",
preview(&reference.alias, 48),
declaration_title(context)
)
},
);
rows = rows.push(location_row(
title,
&reference.path,
reference.position,
provenance(
reference.membership,
reference.evidence,
reference
.context
.as_ref()
.map_or(Identity::Missing, |context| context.identity),
true,
),
enabled.then(|| {
app.source_symbol_message(SymbolEvent::Choose {
stamp: results.stamp,
reference: true,
index,
})
}),
));
}
let row_count = results.definitions.len() + results.references.len();
content =
content.push(scrollable(rows).height((44.0 + row_count as f32 * 48.0).min(180.0)));
}
container(content)
.padding(8)
.width(Fill)
.style(style::subtle)
.into()
}
fn counts(label: &str, shown: usize, total: usize, omitted: usize) -> String {
format!("{label}: {total} total · {shown} shown · {omitted} omitted")
}
fn declaration_title(declaration: &Declaration) -> String {
let name = declaration
.name
.as_ref()
.map_or_else(String::new, |name| format!(" \"{}\"", preview(name, 48)));
format!(
"{}{} · @{}",
preview(&declaration.kind, 24),
name,
preview(&declaration.alias, 48)
)
}
fn provenance(
membership: Membership,
evidence: Evidence,
identity: Identity,
context: bool,
) -> String {
let membership = match membership {
Membership::Included => "Included",
Membership::Detached => "Detached",
Membership::Unverified => "Unverified",
};
let evidence = match evidence {
Evidence::Validated => "Validated",
Evidence::Draft => "Draft",
};
let collision = match identity {
Identity::Collision { count } => format!(
" · {}ID collision ({count})",
if context { "Context " } else { "" },
),
Identity::Missing | Identity::Unique(_) => String::new(),
};
format!("{membership} · {evidence}{collision}")
}
fn location_row(
title: String,
path: &str,
position: Position,
status: String,
event: Option<Message>,
) -> Element<'static, Message> {
let line = position.line.saturating_add(1);
let column = position.byte_column.saturating_add(1);
let location = format!("{}:{line}:{column}", preview(path, 72));
tooltip(
button(
column![
text(title).size(12),
super::label(format!("{location} · {status}"))
]
.spacing(2),
)
.padding([4, 6])
.width(Fill)
.style(style::nav)
.on_press_maybe(event),
text(format!(
"{path}:{line}:{column} (1-based line and UTF-8 byte column)"
))
.size(11),
tooltip::Position::Top,
)
.into()
}
/// Keep headings compact without copying the remainder of a long admitted value.
fn preview(value: &str, limit: usize) -> String {
let mut chars = value.chars();
let mut result: String = chars
.by_ref()
.take(limit)
.map(|ch| if ch.is_whitespace() { ' ' } else { ch })
.collect();
if chars.next().is_some() {
result.push('…');
}
result
}
+17
View File
@@ -2633,6 +2633,23 @@ trace links, occurrence identity, comments and file ownership. Each open file
retains its own unapplied draft across file navigation. Located lint diagnostics retains its own unapplied draft across file navigation. Located lint diagnostics
refer to the raw draft bytes rather than an identity-stabilized intermediate. refer to the raw draft bytes rather than an identity-stabilized intermediate.
Property editing MUST NOT silently discard a pending source draft.</p> Property editing MUST NOT silently discard a pending source draft.</p>
<p>In Textual model, place the caret on a declaration alias or an <span class="docutils literal">&#64;reference</span>
and choose <strong>Definition</strong> (<span class="docutils literal">F12</span>) or <strong>References</strong> (<span class="docutils literal">Shift+F12</span>).
<strong>Back</strong> (<span class="docutils literal">Alt+Left</span>) returns to the previous source location in this
workspace. These shortcuts act while the source editor has focus; the Text
toolbar also exposes the actions. If the previous draft changed, Back restores
its current cursor rather than reusing an obsolete selection.</p>
<p>Symbol navigation reads bounded snapshots of the currently loaded source
drafts. It does not apply drafts or load missing included files. The results
identify partial scope, draft evidence, detached or unverified files, alias
ambiguity and authored-ID collisions. Draft, detached and ambiguous definition
candidates require an explicit row choice. References are lexical uses of an
alias, not a list of resolved typed relationships; comments and strings are
excluded. Declaration and use counts include any rows omitted by the result
limits. If sources change, stale rows cannot navigate: run the query again.
Navigation MUST preserve the accepted model and every source draft, and select
locations in the original UTF-8 bytes. Displayed locations use one-based lines
and UTF-8 byte columns.</p>
<p>Changing a graphical UUID must atomically update map keys and every reference. <p>Changing a graphical UUID must atomically update map keys and every reference.
Alias changes preserve UUID identity. Deletion must account for owned elements, Alias changes preserve UUID identity. Deletion must account for owned elements,
incident relationships, ordered occurrences, and diagram placements without incident relationships, ordered occurrences, and diagram placements without
+19
View File
@@ -2054,6 +2054,25 @@ retains its own unapplied draft across file navigation. Located lint diagnostics
refer to the raw draft bytes rather than an identity-stabilized intermediate. refer to the raw draft bytes rather than an identity-stabilized intermediate.
Property editing MUST NOT silently discard a pending source draft. Property editing MUST NOT silently discard a pending source draft.
In Textual model, place the caret on a declaration alias or an ``@reference``
and choose **Definition** (``F12``) or **References** (``Shift+F12``).
**Back** (``Alt+Left``) returns to the previous source location in this
workspace. These shortcuts act while the source editor has focus; the Text
toolbar also exposes the actions. If the previous draft changed, Back restores
its current cursor rather than reusing an obsolete selection.
Symbol navigation reads bounded snapshots of the currently loaded source
drafts. It does not apply drafts or load missing included files. The results
identify partial scope, draft evidence, detached or unverified files, alias
ambiguity and authored-ID collisions. Draft, detached and ambiguous definition
candidates require an explicit row choice. References are lexical uses of an
alias, not a list of resolved typed relationships; comments and strings are
excluded. Declaration and use counts include any rows omitted by the result
limits. If sources change, stale rows cannot navigate: run the query again.
Navigation MUST preserve the accepted model and every source draft, and select
locations in the original UTF-8 bytes. Displayed locations use one-based lines
and UTF-8 byte columns.
Changing a graphical UUID must atomically update map keys and every reference. Changing a graphical UUID must atomically update map keys and every reference.
Alias changes preserve UUID identity. Deletion must account for owned elements, Alias changes preserve UUID identity. Deletion must account for owned elements,
incident relationships, ordered occurrences, and diagram placements without incident relationships, ordered occurrences, and diagram placements without
@@ -0,0 +1 @@
* -text
@@ -0,0 +1,29 @@
# Text navigation component evidence — 2026-09-11
This archive preserves component execution and native **input preparation** from Codex-9e8r6t `/root/linux_readiness`. It does not establish mounted editor behavior, native acceptance, desktop integration or navigation performance. Linux remains user-paused. Root owns integrated desktop/native evidence and publication; live coordination is [Gitea #6](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/6).
Authoritative explanations are the [core/query integration report](../../release-text-navigation-outline-integration-20260911.md) and [independent v2 source review](../../release-text-navigation-outline-review-v2-20260911.md). These reports remain in place rather than being duplicated here.
## What passed, and on which inputs
| Evidence | Actual scope |
| --- | --- |
| `components/core1*`, `clippy1*` | Windows core: 445 passed, 0 failed, 1 ignored; strict all-target Clippy passed. Four newly added Unicode fixture strings still had the preparation mojibake defect during these runs. |
| `components/outline2*`, `clippy-tests2*` | Corrected explicit-UTF-8 fixtures: 12 focused tests and applicable core lib/tests Clippy passed. Full core was not rerun; production `language.rs` was byte-unchanged. |
| `components/query-compile3*`, `query-tests3*` | Corrected private query: direct rustc compilation with warnings denied and 20 tests passed. Exact Cargo artifact/fingerprint binding is preserved. This is not the later production App/adapter gate. |
| `native-preparation/valid-same*` | Existing pinned oracle compared complete model/identity and four exact reachable/disk sources against a separate copy; exit 0. |
| `native-preparation/release1-same*` | Existing release walkthrough and separate copy: complete model/identity and 30 exact reachable/disk sources; exit 0. Not a 100-module performance trial. |
| `native-preparation/*-rejected*` | Expected loader failures, exit 101: duplicate declaration and missing include. GUI repair reachability was not tested. |
The original broader source base is `b2c3e54001fc19a05423bcd5808ceea78d13ff59`; later instruction-only HEAD `b70bf1d` does not change that provenance. Executions ran in the shared working tree under the recorded compiler lease, not an isolated checkout.
## Contents and limitations
- `components/` contains every exact member of the prior `evidence-records.zip`, including its internal manifest. The original ZIP SHA256 is `7E17DAA1F718344CC17E5A8090FBC1AB16CF3158634EAEB0452549F4D2549CA5`; no second ZIP copy is retained.
- `component-inputs/` adds the exact reviewed v2 patches/original private query and final core implementation/corrected tests. These are historical test inputs, not another production source location. Their hashes match the integration report. Reconstructing every historical full-core input still requires the identified repository state plus the manifests; duplicate 322-file input copies and dependency artifacts are deliberately omitted.
- Failed query candidates, bad-encoding outline tests, E0271 stderr, artifact-binding helper failure, literal verifier corrections and successful replacements remain distinguishable. `query-source-reconstruction.json` is the original incorrect reconstruction claim, superseded by `utf8-reconstruction-correction.json`.
- `native-preparation/` retains original helpers, logs, manifests, expected Unicode/CRLF byte positions and one baseline of each fixture, including the complete 37-file release walkthrough. Original `valid-work` and `release1-work` copies are omitted. To follow its unchanged historical README, copy `valid-baseline` to a fresh `valid-work` and `release1-baseline` to a fresh `release1-work`; copy invalid fixtures before GUI repair. The original 90-file fixture manifest describes both baseline and work copies at preparation time, not this archive's entry set.
- Original helper paths identify the execution environment and may refer to `.local` inputs. No runtime executable is included. The existing oracle compares full decoded model values but exposes no full-model JSON export. Its hash and compatible runtime hash are in the receipts.
- `native-preparation/helper-initial-failure.json` and `readback-print-initial-failure.json` preserve pre-oracle environment-key and read-only stdout-encoding failures; neither modified fixture bytes.
`archive-manifest.json` is the exact payload index with byte counts, SHA256 and origins. `readback.json` records successful entry-set, byte and source-equality checks. The manifest and readback receipt are control files outside the payload count. `.gitattributes` keeps this directory's raw evidence bytes unchanged when staged. Root owns staging and the separate Git-index byte check. No executable, rlib, Cargo cache, duplicate work tree or GUI capture was added here.
@@ -0,0 +1,794 @@
{
"scope": "Exact component evidence and native fixture preparation; no desktop/native acceptance",
"source_zip_sha256": "7e17daa1f718344cc17e5a8090fbc1ab16cf3158634eaeb0452549f4d2549ca5",
"payload_files": 131,
"payload_bytes": 934554,
"records": [
{
"path": ".gitattributes",
"bytes": 8,
"sha256": "705fd4d6451a31d36b3df7de96f83f30ac976c9b4a6d1e51671d8e2f33e2d0da",
"origin": "archive documentation/verification control authored for this consolidation"
},
{
"path": "README.md",
"bytes": 4855,
"sha256": "2b82742dc797aada7e2351e54f4f43da29790846cfd04b4d7fe0329af0049517",
"origin": "archive documentation/verification control authored for this consolidation"
},
{
"path": "component-inputs/language.rs",
"bytes": 105312,
"sha256": "34cbb144a111e6f0ddadfca7d40636a8e3323fe65ea8920fd2402f0352b41f57",
"origin": "crates/oa-core/src/language.rs"
},
{
"path": "component-inputs/language_outline_tests.rs",
"bytes": 14877,
"sha256": "4c79a01e8aea243dd9ef66ce71b9fae263d0e79c319a46c51223679897e8b9df",
"origin": "crates/oa-core/src/language_outline_tests.rs"
},
{
"path": "component-inputs/outline-seam-v2.patch",
"bytes": 25126,
"sha256": "2b37d404fd60bc871554cec2fa4493063f3cc0134d13e7ea90dd1361a394eec1",
"origin": ".local/text-navigation-probe-20260911/outline-seam-v2.patch"
},
{
"path": "component-inputs/query-admission-v2.patch",
"bytes": 7285,
"sha256": "f38b2d5bab3ca6ab66b8bd865f3b01562299fb961c48c8172d39e1d35d90e329",
"origin": ".local/text-navigation-probe-20260911/query-admission-v2.patch"
},
{
"path": "component-inputs/source_symbols-baseline.rs",
"bytes": 49800,
"sha256": "cf82e34544ce508e446787b6335aefe97e146ea5e7cca0a9788deb9097f8f7bb",
"origin": ".local/text-navigation-probe-20260911/source_symbols.rs"
},
{
"path": "components/artifacts1-status.json",
"bytes": 299,
"sha256": "6c162b92780232b5b3bfd24159cfef52d3bb4fb786485572f091ec2383735053",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/artifacts1-status.json"
},
{
"path": "components/artifacts1-stderr.log",
"bytes": 61,
"sha256": "d8b07b9fdfbce4832604bee2b69736dbb7054a3433d972cb15ad8c8fdc7a65c6",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/artifacts1-stderr.log"
},
{
"path": "components/artifacts1-stdout.log",
"bytes": 35777,
"sha256": "5b4441c8f4862d0bad438bbc8b8dddd3d4628586283c0add445248b4a12d85be",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/artifacts1-stdout.log"
},
{
"path": "components/clippy-tests2-status.json",
"bytes": 299,
"sha256": "04910578164f5dce73f8348caccd0590ac9f24150e2b331c554b9c287f2dc191",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/clippy-tests2-status.json"
},
{
"path": "components/clippy-tests2.log",
"bytes": 151,
"sha256": "78c52948b2dd53aca55947ccd1039fec7e054f0d8e61de56b9bd54960e883f61",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/clippy-tests2.log"
},
{
"path": "components/clippy1-status.json",
"bytes": 291,
"sha256": "60818516ec45371a8f4766b4936e11d7b53552f1d1e423846d5c02b55a9acea6",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/clippy1-status.json"
},
{
"path": "components/clippy1.log",
"bytes": 151,
"sha256": "5d3c946198a0870c7245b8ebd8eecef6bff21765f6d98a72221dd1dded3e233e",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/clippy1.log"
},
{
"path": "components/compiler1-status.json",
"bytes": 191,
"sha256": "865fbfc81fa2e58b5b8d6a9d666c18dfb6515f129a026f9cc5df2db6a94b01d9",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/compiler1-status.json"
},
{
"path": "components/compiler1-stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/compiler1-stderr.log"
},
{
"path": "components/compiler1-stdout.log",
"bytes": 197,
"sha256": "cdaaa400be47332d69e678836251d4635b5ff2ecd34aa962b69d71f8961d274b",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/compiler1-stdout.log"
},
{
"path": "components/core1-status.json",
"bytes": 264,
"sha256": "fcd9fae539fa0f82ce0906576971e0b16aec709155363dc1f0a4a201b986edb9",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/core1-status.json"
},
{
"path": "components/core1.log",
"bytes": 48639,
"sha256": "4556049fbfc4ccecc118cad85afb2b1f92af10bfd787ed416ec2aa4389b7bf24",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/core1.log"
},
{
"path": "components/evidence-manifest.json",
"bytes": 8557,
"sha256": "cd55f663f126460e3ef857b55a24595349e28771537d94cfd4d36036b6b3f671",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/evidence-manifest.json"
},
{
"path": "components/final-readback.json",
"bytes": 1775,
"sha256": "29a07e2be5b608d4950b6728398d8f64c0c5c7cb38a014c8dde821ee4b18a390",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/final-readback.json"
},
{
"path": "components/fingerprints/oa-core-781c6973417b169c/lib-oa_core",
"bytes": 16,
"sha256": "32d7fadb58b89d0877ab923522a0bbb715ac42c34526de01cd3cec0be61df760",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/fingerprints/oa-core-781c6973417b169c/lib-oa_core"
},
{
"path": "components/fingerprints/oa-core-781c6973417b169c/lib-oa_core.json",
"bytes": 776,
"sha256": "7664e5d9695d989d99873c6937409b188ee00489f6a808051d8fbafdaf826baa",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/fingerprints/oa-core-781c6973417b169c/lib-oa_core.json"
},
{
"path": "components/fingerprints/serde_json-b48005beba7e4267/lib-serde_json",
"bytes": 16,
"sha256": "9202101a31af6f8d24edceacbb8300c10dddd94fb496cbf6451c8860133ce784",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/fingerprints/serde_json-b48005beba7e4267/lib-serde_json"
},
{
"path": "components/fingerprints/serde_json-b48005beba7e4267/lib-serde_json.json",
"bytes": 826,
"sha256": "310bedb04f5f35eef3a04e8019f0a204cc0f30b94ca808cb4d702cd7c6403737",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/fingerprints/serde_json-b48005beba7e4267/lib-serde_json.json"
},
{
"path": "components/inputs-supplement.json",
"bytes": 388,
"sha256": "480e04d38ec1fda35727cc0b6f2f2837964484c90cffc0199bfe5bcef4236745",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/inputs-supplement.json"
},
{
"path": "components/inputs.json",
"bytes": 61752,
"sha256": "e0dd3e617c1c365e1d315b498ce032f375b734341d2eb87d6dc89867b636196e",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/inputs.json"
},
{
"path": "components/language_outline_tests-pre-encoding-fix.rs",
"bytes": 14922,
"sha256": "f64bd89959554cd5842609c031d442f3d9e27b73a216dd936715284c9fe9fb97",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/language_outline_tests-pre-encoding-fix.rs"
},
{
"path": "components/literal-byte-readback.json",
"bytes": 1291,
"sha256": "0030e88a1a74e2bbf25c1bb3b7dad6dc25ce0477762f8cb71a5034344573d577",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/literal-byte-readback.json"
},
{
"path": "components/outline1-status.json",
"bytes": 312,
"sha256": "3efbfd96f6b5921fa2079b8732d3c32705528989051629b357fb389b4a20933c",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/outline1-status.json"
},
{
"path": "components/outline1.log",
"bytes": 1593,
"sha256": "2582a9e5894d4caee7d092e6b0aa15bd02f49261a6beebaaca91d94affae9230",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/outline1.log"
},
{
"path": "components/outline2-inputs.json",
"bytes": 399,
"sha256": "5eeddbcef8643a75b1582575089405f717bae429c9bf3bf7614a846c712d45ec",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/outline2-inputs.json"
},
{
"path": "components/outline2-status.json",
"bytes": 312,
"sha256": "434a9410460a7c4bf1dedf948a76015b0b0cc63ae19843b834fd02df44ed6d1c",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/outline2-status.json"
},
{
"path": "components/outline2.log",
"bytes": 1593,
"sha256": "0e045f4287675661fde873950bce2387584b377ee747b663fa41ec7ffacd1bc7",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/outline2.log"
},
{
"path": "components/query-artifacts3.json",
"bytes": 206,
"sha256": "25298a1f6b40fd0e60e4bcbda610c81dc851ec37e4d0d58c00099ca1b4128018",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-artifacts3.json"
},
{
"path": "components/query-binding1-failure.json",
"bytes": 905,
"sha256": "b41e3478707a7b3aeb91ee9fd62ca3c2ee45401aff615fd202ffed7fc13c43b1",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-binding1-failure.json"
},
{
"path": "components/query-bindings.json",
"bytes": 6727,
"sha256": "158f1c1797abb634f74b2cbc8f09656871d999bfb6aaa9220feacb443bc48889",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-bindings.json"
},
{
"path": "components/query-compile1-status.json",
"bytes": 987,
"sha256": "a3f9acff4713d9491cbaf7d66180d36e19fa44f8617d6449f9d7f8b4c5a8a383",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile1-status.json"
},
{
"path": "components/query-compile1-stderr.log",
"bytes": 1857,
"sha256": "82b4baefdbb06c4b744cb750268c02dd0d540c0ae77dbd36359403b03dfbf5d0",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile1-stderr.log"
},
{
"path": "components/query-compile1-stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile1-stdout.log"
},
{
"path": "components/query-compile2-status.json",
"bytes": 997,
"sha256": "a64df6b29650a5b9a4d990e1c6ef65a22c8b0068b0e2fa151f912116521b7884",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile2-status.json"
},
{
"path": "components/query-compile2-stderr.log",
"bytes": 2819,
"sha256": "b0206bb2a0be17e6e6c27934566d145425bcf99cb3cc22f7f15143a5733d44fc",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile2-stderr.log"
},
{
"path": "components/query-compile2-stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile2-stdout.log"
},
{
"path": "components/query-compile3-status.json",
"bytes": 1009,
"sha256": "8bff40eed5dbf499ea41119cc2696fe998a7071ac5ce15fecf447d6a86eb127b",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile3-status.json"
},
{
"path": "components/query-compile3-stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile3-stderr.log"
},
{
"path": "components/query-compile3-stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-compile3-stdout.log"
},
{
"path": "components/query-source-reconstruction.json",
"bytes": 673,
"sha256": "7692eaf4ed52e0de5f95d1ea26b0b3c3d91b8b89cda7a0c0198394a0403ea03e",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-source-reconstruction.json"
},
{
"path": "components/query-tests3-status.json",
"bytes": 332,
"sha256": "e2edbb9cdb986ba5215a53830393e2c11f5d8e428a81ebbaede0e06bb395db9d",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-tests3-status.json"
},
{
"path": "components/query-tests3-stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-tests3-stderr.log"
},
{
"path": "components/query-tests3-stdout.log",
"bytes": 1785,
"sha256": "faec6eb5a3be074a755dfb0ce0bf7b34d2358ff543e0999ee51a27d7a8bcabc9",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-tests3-stdout.log"
},
{
"path": "components/query-type-correction.json",
"bytes": 414,
"sha256": "eb3675d734354dd8dcb2682b77276d4f2d08790fa98c20c045b0286959ecfcf7",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/query-type-correction.json"
},
{
"path": "components/run-gates.ps1",
"bytes": 1231,
"sha256": "070c986b1ca9de6c01750597d68478201736093b70bba76812752cafb522e867",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/run-gates.ps1"
},
{
"path": "components/run-query-resume.ps1",
"bytes": 5572,
"sha256": "07c707cfe4c143af8a64a5ba88de24c866d9a9929f23206f39e21df589c0977b",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/run-query-resume.ps1"
},
{
"path": "components/run-query-typed.ps1",
"bytes": 3119,
"sha256": "92cde88b43382b6b7557bf341d7168f98e3838d3d2f3bd25e802780d400cb05c",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/run-query-typed.ps1"
},
{
"path": "components/run-query-utf8.ps1",
"bytes": 3107,
"sha256": "ebb7b16ed431df7df6885a5aff6dbbe55db5b01cc899821e1a4af665ed2d3c18",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/run-query-utf8.ps1"
},
{
"path": "components/run-query.ps1",
"bytes": 4240,
"sha256": "c112d1a496ed9d39e202f7704548863af45e532dfe89c675bb84b2569201b1ec",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/run-query.ps1"
},
{
"path": "components/run-utf8-outline-gates.ps1",
"bytes": 1505,
"sha256": "742695aa1b1aadebfb475306fdcbfbb31af5a7f5dd4920e7c5c49df757d89962",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/run-utf8-outline-gates.ps1"
},
{
"path": "components/source_symbols-v2-utf8-typed.rs",
"bytes": 54554,
"sha256": "fe37cd55b95c892c05aec6c37a113154cab7646dcfc333646fa8218345919751",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/source_symbols-v2-utf8-typed.rs"
},
{
"path": "components/source_symbols-v2-utf8.rs",
"bytes": 54542,
"sha256": "86666c8390f0c63ec75b045366494a80d0ecde82924f2bac312afd01675aee56",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/source_symbols-v2-utf8.rs"
},
{
"path": "components/source_symbols-v2.rs",
"bytes": 54637,
"sha256": "8f3f20a7e72c870cfd1ad46f0aa8b8998ffc1ebf3357911957ed4995758e7520",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/source_symbols-v2.rs"
},
{
"path": "components/utf8-reconstruction-correction.json",
"bytes": 776,
"sha256": "3140aab739ad4351f8538b8169b3fe972b975138cc95c6e12be82a0d5f76c7a3",
"origin": ".local/text-navigation-integration-20260911/evidence-records.zip!/utf8-reconstruction-correction.json"
},
{
"path": "native-preparation/README.md",
"bytes": 6775,
"sha256": "92b5de00ae6aed2c1434bee304b5c348bc154985ba972c3058165b9bd65a8659",
"origin": ".local/text-navigation-native-20260911-preparation/README.md"
},
{
"path": "native-preparation/ambiguous-open/links.arcadia",
"bytes": 211,
"sha256": "d3229ecf6300804103eb7f85bd5891c022f6f6c194dbdbbdcb54e9550338dc3b",
"origin": ".local/text-navigation-native-20260911-preparation/ambiguous-open/links.arcadia"
},
{
"path": "native-preparation/ambiguous-open/project.arcadia",
"bytes": 277,
"sha256": "79e26836c048a35aaf98b21ff006ae8ac931160abd9913b9e67b542303215414",
"origin": ".local/text-navigation-native-20260911-preparation/ambiguous-open/project.arcadia"
},
{
"path": "native-preparation/ambiguous-open/救援/assess.arcadia",
"bytes": 192,
"sha256": "d99593537e67b2dfd293623f467ffbd46af4ea259dffae55d1fe9995c86e6992",
"origin": ".local/text-navigation-native-20260911-preparation/ambiguous-open/救援/assess.arcadia"
},
{
"path": "native-preparation/ambiguous-open/救援/confirm.arcadia",
"bytes": 186,
"sha256": "ba3e222bdc7dfa94e4f1b16df091447835da6b5bea8a72701e12e077e77319a6",
"origin": ".local/text-navigation-native-20260911-preparation/ambiguous-open/救援/confirm.arcadia"
},
{
"path": "native-preparation/ambiguous-rejected-result.json",
"bytes": 709,
"sha256": "ec41f8661711bc85890748f23f7cb40682c35f03de0203ceb22e673a369351f6",
"origin": ".local/text-navigation-native-20260911-preparation/ambiguous-rejected-result.json"
},
{
"path": "native-preparation/ambiguous-rejected.stderr.log",
"bytes": 527,
"sha256": "85bd641d9e3eac3ef5c6a7746906fc498f2b17bc71248b612ee0083f5c3a99d6",
"origin": ".local/text-navigation-native-20260911-preparation/ambiguous-rejected.stderr.log"
},
{
"path": "native-preparation/ambiguous-rejected.stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-native-20260911-preparation/ambiguous-rejected.stdout.log"
},
{
"path": "native-preparation/check-summary.json",
"bytes": 3221,
"sha256": "c92add757cd1e2e80a2c04407ec2f928339167cc8d710e5141d9528a6dddad7a",
"origin": ".local/text-navigation-native-20260911-preparation/check-summary.json"
},
{
"path": "native-preparation/check.py",
"bytes": 2611,
"sha256": "9357d11a16e63ad495fab48ca63f4e7ccf3c81fecf5475e29666a3723477ea53",
"origin": ".local/text-navigation-native-20260911-preparation/check.py"
},
{
"path": "native-preparation/expected-locations.json",
"bytes": 8654,
"sha256": "81574d2c9c0aec1657a293af52a469506ccddfa2914e820c61af619d5622837f",
"origin": ".local/text-navigation-native-20260911-preparation/expected-locations.json"
},
{
"path": "native-preparation/fixture-manifest.json",
"bytes": 15760,
"sha256": "edd4157fc31823f4494dee91862728b87f12ef51c49b8d1fd86a954bc9ecc1ed",
"origin": ".local/text-navigation-native-20260911-preparation/fixture-manifest.json"
},
{
"path": "native-preparation/helper-initial-failure.json",
"bytes": 211,
"sha256": "b76221bc6f9bc6ac9359f1ad82a99f71001abc8e9f7bf6d2776e28599e79f951",
"origin": ".local/text-navigation-native-20260911-preparation/helper-initial-failure.json"
},
{
"path": "native-preparation/missing-include-open/links.arcadia",
"bytes": 211,
"sha256": "d3229ecf6300804103eb7f85bd5891c022f6f6c194dbdbbdcb54e9550338dc3b",
"origin": ".local/text-navigation-native-20260911-preparation/missing-include-open/links.arcadia"
},
{
"path": "native-preparation/missing-include-open/project.arcadia",
"bytes": 320,
"sha256": "573357995f0a68fef39aa3eef3125e2271242d1ce01607c129624399b77e682e",
"origin": ".local/text-navigation-native-20260911-preparation/missing-include-open/project.arcadia"
},
{
"path": "native-preparation/missing-include-open/救援/assess.arcadia",
"bytes": 192,
"sha256": "d99593537e67b2dfd293623f467ffbd46af4ea259dffae55d1fe9995c86e6992",
"origin": ".local/text-navigation-native-20260911-preparation/missing-include-open/救援/assess.arcadia"
},
{
"path": "native-preparation/missing-include-open/救援/confirm.arcadia",
"bytes": 92,
"sha256": "591b32db3b1282825750d002d9293cfc450d55252506623302ce36c949fe9919",
"origin": ".local/text-navigation-native-20260911-preparation/missing-include-open/救援/confirm.arcadia"
},
{
"path": "native-preparation/missing-include-rejected-result.json",
"bytes": 721,
"sha256": "ba00c3411a62c1eb56fe3c095c38a728f51a26b06f74345ea61d7ae013ad1468",
"origin": ".local/text-navigation-native-20260911-preparation/missing-include-rejected-result.json"
},
{
"path": "native-preparation/missing-include-rejected.stderr.log",
"bytes": 695,
"sha256": "88899097199b509e9e2854588f524e532aa2d21521254d993b9955572c9d65c8",
"origin": ".local/text-navigation-native-20260911-preparation/missing-include-rejected.stderr.log"
},
{
"path": "native-preparation/missing-include-rejected.stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-native-20260911-preparation/missing-include-rejected.stdout.log"
},
{
"path": "native-preparation/prepare.py",
"bytes": 4821,
"sha256": "2c291f227f74b8c625b6bee9ac05ea7639cdca25dd0fafcd61b685bbda6d5404",
"origin": ".local/text-navigation-native-20260911-preparation/prepare.py"
},
{
"path": "native-preparation/readback-print-initial-failure.json",
"bytes": 262,
"sha256": "92751765c7a21f7e201bf65f5453691916c8e932bd3f9d431ff24f4c3aaed8bc",
"origin": ".local/text-navigation-native-20260911-preparation/readback-print-initial-failure.json"
},
{
"path": "native-preparation/release1-baseline/README.md",
"bytes": 11137,
"sha256": "113cfb1cf38a98b51bff60442d86a35d636a3d80ef206bece7d53d0aae67f2d5",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/README.md"
},
{
"path": "native-preparation/release1-baseline/evidence/repair-check.md",
"bytes": 1419,
"sha256": "f4db17bdca4ecbb1bf0caef01b2da5f1f7f798ab3152b648ce6dd8696a6a68e5",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/evidence/repair-check.md"
},
{
"path": "native-preparation/release1-baseline/expected-diagnostics.json",
"bytes": 288,
"sha256": "3700393d76b940cfc076bf52861bd7b1f43370f8eabce3594531bd0bf1fc851e",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/expected-diagnostics.json"
},
{
"path": "native-preparation/release1-baseline/model.json",
"bytes": 134520,
"sha256": "ef0ef4006c3e09d5db6e1b621256b3f7d6642f3a7b09cc34607cfbcca830c727",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/model.json"
},
{
"path": "native-preparation/release1-baseline/model.rs",
"bytes": 28762,
"sha256": "15f30f6bde655808fe754665c26d560e36f2a9bad340f346b09137d0d05045f5",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/model.rs"
},
{
"path": "native-preparation/release1-baseline/oa/activities/activity_oa_restore_work.arcadia",
"bytes": 1307,
"sha256": "83e73d0a013d5c3e1a4af0d9139ab0cfa362d25a846671fc2dac59181061a9d4",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/activities/activity_oa_restore_work.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/behavior/process_oa_assessment_procedure.arcadia",
"bytes": 697,
"sha256": "172c32c044ef4b5bc58a1f4635cc81f48dabb4014479b47dce7b25fedf2dbd0d",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/behavior/process_oa_assessment_procedure.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/behavior/process_oa_field_procedure.arcadia",
"bytes": 1781,
"sha256": "d2552dc5383e2e91cb302a790364e197f663c2edc013a2ab1978789825c9c324",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/behavior/process_oa_field_procedure.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/behavior/process_oa_response.arcadia",
"bytes": 3225,
"sha256": "cf86f46fa5c5d70592ef43f1bc1cb4d968efd8add384ba88036bef6b88aa4abc",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/behavior/process_oa_response.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/behavior/scenario_oa_conversation.arcadia",
"bytes": 1795,
"sha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/behavior/scenario_oa_conversation.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/behavior/scenario_oa_full_scenario.arcadia",
"bytes": 1261,
"sha256": "00a1edf2c9707a0eb62ac070c2d02467874f2c9c1f273cc6ddb53d6d65999a1c",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/behavior/scenario_oa_full_scenario.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/behavior/state_machine_oa_monitor.arcadia",
"bytes": 2022,
"sha256": "447c9ad1359f4a31ecf975ad07c0b08d8e7e03191fb0858e2fc56f377b223cd5",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/behavior/state_machine_oa_monitor.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/capabilities.arcadia",
"bytes": 781,
"sha256": "fc8012e5554350b12e1cb80080f8feab80d933c9b33c0f2a7bb500cb7d609936",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/capabilities.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/model.arcadia",
"bytes": 661,
"sha256": "f7cf914766ea73ec53b85e32d117ea9a9dba52d3e038246863541ae7069b1a15",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/model.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/participants.arcadia",
"bytes": 1834,
"sha256": "951764c14179f27c10e315acf2ea37d1fff54c77b8441e23addd239e8c715ce3",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/participants.arcadia"
},
{
"path": "native-preparation/release1-baseline/oa/types.arcadia",
"bytes": 788,
"sha256": "9d0396fb82dd5733edd8d1cf52f968ca84906927c704f9cf0944a7fae215cf49",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/oa/types.arcadia"
},
{
"path": "native-preparation/release1-baseline/project.arcadia",
"bytes": 1958,
"sha256": "b2674e6bf77cfe0f6f0ba79c81d2e96d92f39c02ca2c6266d80e91723bfb9fda",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/project.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/behavior/process_sa_assessment_procedure.arcadia",
"bytes": 706,
"sha256": "73928ced61c06cbc08728d7956676a50fd4c05aa5b7f1ff4f29ce27a0b0f2088",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/behavior/process_sa_assessment_procedure.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/behavior/process_sa_field_procedure.arcadia",
"bytes": 1790,
"sha256": "886d462af83110cbfa55dd232a667ea1446761234471357cbb878794e98e8768",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/behavior/process_sa_field_procedure.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/behavior/process_sa_response.arcadia",
"bytes": 3234,
"sha256": "041785fc22842423822431bd5e6e8d16094ebd0716965e7c765fb8c1d7549e8a",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/behavior/process_sa_response.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/behavior/scenario_sa_conversation.arcadia",
"bytes": 2127,
"sha256": "97276f5757ee9aa12a0dbd9d3ccd58174b3091162bb8bcce357cec20a45f5d85",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/behavior/scenario_sa_conversation.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/behavior/scenario_sa_full_scenario.arcadia",
"bytes": 1256,
"sha256": "e12fc406b99d60a2f7768aaa0b25ba560e8605f0b8e37f3a7cdd3b8443562b74",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/behavior/scenario_sa_full_scenario.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/behavior/state_machine_sa_monitor.arcadia",
"bytes": 2022,
"sha256": "05ce29af99424c491c47fe2450dc6f5f8ce995511c01ec7e17bb5855be3c9736",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/behavior/state_machine_sa_monitor.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/capabilities.arcadia",
"bytes": 781,
"sha256": "b6912fb3ece439912345fa71724acd462e716a1e5a88203a1058a5c3b2c20a4f",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/capabilities.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/functions/function_sa_audit_thresholds.arcadia",
"bytes": 297,
"sha256": "e5a04325d52183956dca814dd90f4e56c96c6b7db0f4f202f203ecb49c3e0f4f",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/functions/function_sa_audit_thresholds.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/functions/function_sa_restore_work.arcadia",
"bytes": 2576,
"sha256": "fddeb67308051325041fee641fe758ddf43345b7c47b66d433616ad07fdccdd6",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/functions/function_sa_restore_work.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/model.arcadia",
"bytes": 661,
"sha256": "d431509251acb859fbb98733b6d18add952495e10a78703fbe8f31e40bc083c4",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/model.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/participants.arcadia",
"bytes": 4012,
"sha256": "780d2eb08b217b67b55febb3d34846f727b8ee9018df6c5741748647e36b2ff8",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/participants.arcadia"
},
{
"path": "native-preparation/release1-baseline/sa/types.arcadia",
"bytes": 1227,
"sha256": "101fc0fbd99f1101514aa7b6da4f8e535aae0bb94c9e2b9e7e6c151135b28660",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/sa/types.arcadia"
},
{
"path": "native-preparation/release1-baseline/traceability.arcadia",
"bytes": 29506,
"sha256": "48a96f543456c9b5a5798fc795594e4119147fe45f11a6f109f141b7f514560f",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/traceability.arcadia"
},
{
"path": "native-preparation/release1-baseline/transition-before.json",
"bytes": 35801,
"sha256": "2253e6434f741687e22327c37d520ed15c043bc36025498650bc2366bb6a874d",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/transition-before.json"
},
{
"path": "native-preparation/release1-baseline/transition-request.json",
"bytes": 4276,
"sha256": "43b9a22e5f95ad3bc0ebd2478ead0e14406854abc989ae94ded9367b013d812a",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/transition-request.json"
},
{
"path": "native-preparation/release1-baseline/views/diagram_oa_allocation_view.arcadia",
"bytes": 2176,
"sha256": "dfc0eb61e0e2aa5bda45524571fbfa3494f44ce19696f3e15e07438074a07bc7",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/views/diagram_oa_allocation_view.arcadia"
},
{
"path": "native-preparation/release1-baseline/views/diagram_sa_allocation_view.arcadia",
"bytes": 2173,
"sha256": "b78b43a26a82efb8fbd5374b09c329fa341f57b29f635d397b9ef8aede71d389",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/views/diagram_sa_allocation_view.arcadia"
},
{
"path": "native-preparation/release1-baseline/views/diagram_sa_capability_view.arcadia",
"bytes": 1620,
"sha256": "75e8dc9fb30f25d6f8fd3c6b595593ab4f98958a25798f961e336e0fac557649",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/views/diagram_sa_capability_view.arcadia"
},
{
"path": "native-preparation/release1-baseline/views/diagram_sa_service_view.arcadia",
"bytes": 2209,
"sha256": "b08c84f3ea633e7c78dfdad3272f75415f6256cf3614b6d99bfd4f0269076c9b",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/views/diagram_sa_service_view.arcadia"
},
{
"path": "native-preparation/release1-baseline/views/diagram_sa_state_view.arcadia",
"bytes": 1931,
"sha256": "5f42f4c605e57b817d8400ed21f2b14bfc4e1592aebe941ff113767504c2b869",
"origin": ".local/text-navigation-native-20260911-preparation/release1-baseline/views/diagram_sa_state_view.arcadia"
},
{
"path": "native-preparation/release1-same-result.json",
"bytes": 707,
"sha256": "7b2423cd8a860195ebfee1393abf72610219669fef4e80f92308eddba46ef142",
"origin": ".local/text-navigation-native-20260911-preparation/release1-same-result.json"
},
{
"path": "native-preparation/release1-same.stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-native-20260911-preparation/release1-same.stderr.log"
},
{
"path": "native-preparation/release1-same.stdout.log",
"bytes": 88,
"sha256": "61b58865f8e6253e9fff5bfe7d7a812a3ea455df84edd503323b3741b36dadba",
"origin": ".local/text-navigation-native-20260911-preparation/release1-same.stdout.log"
},
{
"path": "native-preparation/valid-baseline/links.arcadia",
"bytes": 211,
"sha256": "d3229ecf6300804103eb7f85bd5891c022f6f6c194dbdbbdcb54e9550338dc3b",
"origin": ".local/text-navigation-native-20260911-preparation/valid-baseline/links.arcadia"
},
{
"path": "native-preparation/valid-baseline/project.arcadia",
"bytes": 277,
"sha256": "79e26836c048a35aaf98b21ff006ae8ac931160abd9913b9e67b542303215414",
"origin": ".local/text-navigation-native-20260911-preparation/valid-baseline/project.arcadia"
},
{
"path": "native-preparation/valid-baseline/救援/assess.arcadia",
"bytes": 192,
"sha256": "d99593537e67b2dfd293623f467ffbd46af4ea259dffae55d1fe9995c86e6992",
"origin": ".local/text-navigation-native-20260911-preparation/valid-baseline/救援/assess.arcadia"
},
{
"path": "native-preparation/valid-baseline/救援/confirm.arcadia",
"bytes": 92,
"sha256": "591b32db3b1282825750d002d9293cfc450d55252506623302ce36c949fe9919",
"origin": ".local/text-navigation-native-20260911-preparation/valid-baseline/救援/confirm.arcadia"
},
{
"path": "native-preparation/valid-same-result.json",
"bytes": 701,
"sha256": "14316e6dda215780b807abeb4e351438f0ccb321e9dd6eda266da7172ca8ceca",
"origin": ".local/text-navigation-native-20260911-preparation/valid-same-result.json"
},
{
"path": "native-preparation/valid-same.stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"origin": ".local/text-navigation-native-20260911-preparation/valid-same.stderr.log"
},
{
"path": "native-preparation/valid-same.stdout.log",
"bytes": 86,
"sha256": "5ac622cfcc05242dca7c1368aba77293d42ab9ce5e56df7b2aedd2287d66d5e7",
"origin": ".local/text-navigation-native-20260911-preparation/valid-same.stdout.log"
},
{
"path": "verify_archive.py",
"bytes": 830,
"sha256": "357b9bee26014b9f6cbc88cf5b3f196a528c7cb822940560cdfead1c663a8acc",
"origin": "archive documentation/verification control authored for this consolidation"
}
]
}
@@ -0,0 +1,386 @@
//! Prepared outline tests. Explicit compatibility tests additionally exercise
//! the existing parsers/analyze; the outline entry itself never calls them.
use super::*;
fn limits() -> OutlineLimits {
OutlineLimits {
max_source_bytes: 1024 * 1024,
max_tokens: 100_000,
max_declarations: 1_000,
}
}
fn declaration<'a>(result: &'a Outline<'_>, alias: &str) -> &'a OutlineDeclaration {
result
.declarations
.iter()
.find(|d| d.declaration.alias == alias)
.unwrap()
}
fn text(source: &str, span: Span) -> &str {
&source[span.start..span.end]
}
#[test]
fn outline_roles_preserve_unicode_crlf_and_exact_escaped_uuid_literal() {
let source = "// 検査 🚒\r\noa_actor responder \"救助\" id \"\\u00300000000-0000-0000-0000-000000000001\" {}\r\nsource @ // 使用\r\n responder;";
let before = source.as_bytes().to_vec();
let result = outline(source, limits()).unwrap();
assert_eq!(result.source.as_bytes(), before);
assert_eq!(result.source.as_ptr(), source.as_ptr());
let d = declaration(&result, "responder");
assert_eq!(text(source, d.kind_span), "oa_actor");
assert_eq!(text(source, d.alias_span), "responder");
assert_eq!(
text(source, d.id_literal_span.unwrap()),
"\"\\u00300000000-0000-0000-0000-000000000001\""
);
assert_eq!(d.declaration.id, Some(Id::from_u128(1)));
assert_eq!(d.declaration.span.start, source.find("oa_actor").unwrap());
assert_eq!(d.declaration.span.end, source.find("{}\r\n").unwrap() + 2);
let mut end = 0;
for token in &result.tokens {
assert_eq!(token.span.start, end);
assert!(token.span.start < token.span.end);
assert!(source.is_char_boundary(token.span.start));
assert!(source.is_char_boundary(token.span.end));
end = token.span.end;
}
assert_eq!(end, source.len());
assert!(!result.has_lexical_errors);
assert!(!result.has_unmatched_braces);
}
#[test]
fn closed_id_at_eof_is_inside_the_declaration_extent() {
for source in [
"oa_actor a \"Actor\" id \"00000000-0000-0000-0000-000000000001\"",
"node placed id \"00000000-0000-0000-0000-000000000001\"",
] {
let result = outline(source, limits()).unwrap();
let d = &result.declarations[0];
let literal = d.id_literal_span.unwrap();
assert_eq!(d.declaration.id, Some(Id::from_u128(1)));
assert_eq!(d.declaration.span.end, source.len());
assert!(d.declaration.span.start <= literal.start);
assert!(literal.end <= d.declaration.span.end);
}
for source in ["oa_actor a \"Actor\"", "oa_actor a \"Actor\" id"] {
let result = outline(source, limits()).unwrap();
let d = &result.declarations[0];
assert_eq!(d.declaration.span.end, source.len());
assert_eq!(d.declaration.id, None);
assert_eq!(d.id_literal_span, None);
}
}
#[test]
fn missing_bad_and_historical_ids_never_allocate_authored_identity() {
let source = "oa_actor missing \"No ID\" {}\noa_actor bad \"Bad ID\" id \"not-a-uuid\" {}\noa_actor historical \"00000000-0000-0000-0000-000000000001\" { history uuid \"00000000-0000-0000-0000-000000000001\"; }";
let first = outline(source, limits()).unwrap();
let second = outline(source, limits()).unwrap();
assert_eq!(first, second);
assert!(
first
.declarations
.iter()
.all(|d| d.declaration.id.is_none())
);
assert_eq!(declaration(&first, "missing").id_literal_span, None);
assert_eq!(declaration(&first, "historical").id_literal_span, None);
assert_eq!(
text(source, declaration(&first, "bad").id_literal_span.unwrap()),
"\"not-a-uuid\""
);
// Balanced tokens are not a successful syntax/semantic validation claim.
assert!(!first.has_lexical_errors);
assert!(!first.has_unmatched_braces);
}
#[test]
fn invalid_full_scan_keeps_closed_children_and_reports_lexical_body_facts() {
let source = "oa_entity outer \"Outer\" {\n oa_actor ready \"Ready\" { description \"} stays text\"; }\n oa_actor pending \"Pending\" { description \"unfinished 🌊";
let result = outline(source, limits()).unwrap();
assert_eq!(result.source, source);
assert_eq!(result.tokens.last().unwrap().span.end, source.len());
assert!(result.has_lexical_errors);
assert!(result.has_unmatched_braces);
let ready = declaration(&result, "ready");
assert_eq!(
text(source, ready.declaration.span),
"oa_actor ready \"Ready\" { description \"} stays text\"; }"
);
assert_eq!(
declaration(&result, "outer").declaration.span.end,
source.len()
);
assert_eq!(
declaration(&result, "pending").declaration.span.end,
source.len()
);
let unmatched_close = outline("}\n// brace in comment {\n", limits()).unwrap();
assert!(unmatched_close.has_unmatched_braces);
assert!(!unmatched_close.has_lexical_errors);
}
#[test]
fn missing_body_syntax_is_unchecked_even_when_known_error_flags_are_clear() {
let source = "oa_actor a \"A\" id \"00000000-0000-0000-0000-000000000001\"";
let result = outline(source, limits()).unwrap();
assert_eq!(result.declarations.len(), 1);
assert!(!result.has_lexical_errors);
assert!(!result.has_unmatched_braces);
// There is deliberately no `valid` flag: the known-complete fact is scanning
// these bytes, not the missing body becoming legal or the draft being applied.
assert_eq!(result.source, source);
}
#[test]
fn keyword_alias_and_collisions_keep_every_source_ordered_header() {
let source = "project root_model \"Model\" {\n oa_actor oa_activity \"First\" id \"00000000-0000-0000-0000-000000000001\" {}\n oa_actor oa_activity \"Second\" id \"00000000-0000-0000-0000-000000000001\" {}\n diagram view_one \"View\" {}\n node placement { diagram @view_one; }\n}";
let result = outline(source, limits()).unwrap();
assert_eq!(result.declarations.len(), 5);
let duplicates: Vec<_> = result
.declarations
.iter()
.filter(|d| d.declaration.alias == "oa_activity")
.collect();
assert_eq!(duplicates.len(), 2);
assert!(duplicates[0].alias_span.start < duplicates[1].alias_span.start);
assert_eq!(duplicates[0].declaration.id, duplicates[1].declaration.id);
assert!(
result
.tokens
.iter()
.any(|t| t.span == duplicates[0].alias_span && t.class == TokenClass::Keyword)
);
assert_eq!(
text(source, declaration(&result, "placement").kind_span),
"node"
);
assert_eq!(declaration(&result, "placement").declaration.id, None);
}
#[test]
fn bounds_refuse_before_returning_a_partial_outline() {
let source = "oa_actor a \"A\" {}\noa_actor b \"B\" {}";
let admitted = outline(source, limits()).unwrap();
let exact = OutlineLimits {
max_source_bytes: source.len(),
max_tokens: admitted.tokens.len(),
max_declarations: 2,
};
assert_eq!(outline(source, exact).unwrap(), admitted);
for resource in [
OutlineResource::SourceBytes,
OutlineResource::Tokens,
OutlineResource::Declarations,
] {
let mut lower = exact;
match resource {
OutlineResource::SourceBytes => lower.max_source_bytes -= 1,
OutlineResource::Tokens => lower.max_tokens -= 1,
OutlineResource::Declarations => lower.max_declarations -= 1,
}
let error = outline(source, lower).unwrap_err();
assert_eq!(error.resource, resource);
assert!(error.observed_at_least > error.limit);
assert!(source.is_char_boundary(error.offset));
if resource == OutlineResource::Declarations {
assert_eq!(error.offset, source.find("oa_actor b").unwrap());
}
}
let empty = outline(
"",
OutlineLimits {
max_source_bytes: 0,
max_tokens: 0,
max_declarations: 0,
},
)
.unwrap();
assert!(empty.tokens.is_empty() && empty.declarations.is_empty());
let unicode = "// 🌊\r\noa_actor a \"A\" {}";
let error = outline(
unicode,
OutlineLimits {
max_source_bytes: 4,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::SourceBytes);
assert_eq!(error.offset, 0);
let error = outline(
unicode,
OutlineLimits {
max_tokens: 1,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::Tokens);
assert_eq!(error.offset, unicode.find('\n').unwrap());
}
#[test]
fn outline_ranges_follow_current_bytes_without_identity_stabilization() {
let old = "oa_actor a \"A\" {}\nsource @a;";
let current = format!("// 航海 🚒\r\n{old}");
let old_outline = outline(old, limits()).unwrap();
let current_outline = outline(&current, limits()).unwrap();
let shift = current.len() - old.len();
let old_role = &old_outline.declarations[0];
let current_role = &current_outline.declarations[0];
assert_eq!(
current_role.alias_span.start,
old_role.alias_span.start + shift
);
assert_eq!(
current_role.kind_span.start,
old_role.kind_span.start + shift
);
assert_eq!(
current_role.declaration.span.end,
old_role.declaration.span.end + shift
);
assert_eq!(current_outline.source, current);
assert_eq!(old_outline.source, old);
assert_eq!(current_role.declaration.id, None);
assert!(!current_outline.source.contains(" id "));
// Workspace revision/stale-handle rejection belongs to the query/adapter,
// not a claim that an old owned span can be applied to any other string.
}
#[test]
fn deeply_nested_bounds_use_the_same_iterative_walk_and_declaration_budget() {
let mut source = String::new();
for index in 0..600 {
source.push_str(&format!("oa_activity work_{index} \"Work\" {{\n"));
}
source.push_str(&"}\n".repeat(600));
let result = outline(&source, limits()).unwrap();
assert_eq!(result.declarations.len(), 600);
assert!(!result.has_unmatched_braces);
assert_eq!(
result.declarations[0].declaration.span.end,
source.len() - 1
);
let error = outline(
&source,
OutlineLimits {
max_declarations: 599,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::Declarations);
assert_eq!(error.observed_at_least, 600);
assert_eq!(error.offset, source.find("oa_activity work_599").unwrap());
}
#[test]
fn noncanonical_uuid_spellings_have_no_outline_or_analysis_identity() {
for raw in [
"00000000000000000000000000000001",
"{00000000-0000-0000-0000-000000000001}",
"urn:uuid:00000000-0000-0000-0000-000000000001",
] {
assert!(
Id::parse_str(raw).is_ok(),
"The UUID crate alone is too permissive"
);
assert!(!has_uuid_header_shape(raw));
let literal = format!("\"{raw}\"");
let modern = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let before = modern.clone();
let result = outline(&modern, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, None);
assert_eq!(text(&modern, d.id_literal_span.unwrap()), literal);
assert_eq!(modern, before);
let errors = parse(&modern).unwrap_err();
assert!(
errors
.iter()
.any(|error| error.message.contains("8-4-4-4-12")
&& error.span.start == modern.find(&literal).unwrap())
);
// Intentional compatibility correction: old analyze yielded Some(Id(1))
// here despite lint rejecting the header. It now shares outline's None.
let analysis = analyze(&modern);
assert_eq!(
analysis
.declarations
.iter()
.find(|d| d.alias == "model")
.unwrap()
.id,
None
);
assert!(
analysis
.diagnostics
.iter()
.any(|error| error.message.contains("8-4-4-4-12"))
);
let legacy_source = format!("arcadia 1; project \"Legacy\" id {literal} {{}}");
let legacy_errors = legacy::parse(&legacy_source).unwrap_err();
assert!(
legacy_errors
.iter()
.any(|error| error.message.contains("8-4-4-4-12"))
);
}
}
#[test]
fn uppercase_and_json_escaped_header_ids_survive_both_parsers_and_outline() {
let expected = Id::from_u128(0xabcdef);
let canonical = expected.to_string();
let uppercase = canonical.to_uppercase();
assert_ne!(uppercase, canonical);
for raw in [uppercase.clone(), format!("\\u0030{}", &uppercase[1..])] {
let literal = format!("\"{raw}\"");
let decoded: String = serde_json::from_str(&literal).unwrap();
assert!(has_uuid_header_shape(&decoded));
let modern = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let result = outline(&modern, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, Some(expected));
assert_eq!(text(&modern, d.id_literal_span.unwrap()), literal);
assert_eq!(result.source.as_bytes(), modern.as_bytes());
assert_eq!(parse(&modern).unwrap().id, expected);
let analysis = analyze(&modern);
assert_eq!(analysis.declarations[0].id, Some(expected));
assert!(
!analysis
.diagnostics
.iter()
.any(|error| error.severity == crate::validation::Severity::Error)
);
let legacy_source = format!("arcadia 1; project \"Legacy\" id {literal} {{}}");
assert_eq!(legacy::parse(&legacy_source).unwrap().id, expected);
}
}
#[test]
fn header_shape_still_requires_valid_hexadecimal_uuid_data() {
let raw = "00000000-0000-0000-0000-00000000000Z";
assert!(has_uuid_header_shape(raw));
assert!(Id::parse_str(raw).is_err());
let literal = format!("\"{raw}\"");
let source = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let result = outline(&source, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, None);
assert_eq!(text(&source, d.id_literal_span.unwrap()), literal);
assert!(
parse(&source)
.unwrap_err()
.iter()
.any(|error| error.message == "Invalid UUID identity.")
);
assert_eq!(analyze(&source).declarations[0].id, None);
}
@@ -0,0 +1,569 @@
--- a/crates/oa-core/src/language.rs
+++ b/crates/oa-core/src/language.rs
@@ -141,14 +141,89 @@
pub diagnostics: Vec<Diagnostic>,
pub declarations: Vec<DeclarationSpan>,
}
+/// Check the decoded spelling required by declaration-header UUID clauses.
+/// This is the shared 36-byte/hyphen shape rule, not a hexadecimal parser:
+/// callers must additionally parse the UUID. Uppercase hex and JSON escapes
+/// that decode to this spelling remain accepted. URN/braced/compact forms do not.
+pub fn has_uuid_header_shape(decoded: &str) -> bool {
+ decoded.len() == 36
+ && [8, 13, 18, 23]
+ .into_iter()
+ .all(|index| decoded.as_bytes()[index] == b'-')
+}
+
+/// Budgets for one original source buffer. Policy is caller-owned; these
+/// limits do not change the grammar or perform model admission.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct OutlineLimits {
+ pub max_source_bytes: usize,
+ pub max_tokens: usize,
+ pub max_declarations: usize,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum OutlineResource {
+ SourceBytes,
+ Tokens,
+ Declarations,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct OutlineLimit {
+ pub resource: OutlineResource,
+ pub limit: usize,
+ pub observed_at_least: usize,
+ /// Original byte offset where admission stopped; never a rewritten offset.
+ pub offset: usize,
+}
+
+/// Roles discovered by the existing tolerant declaration walk. Keeping the
+/// wrapper preserves DeclarationSpan and Analysis as existing public APIs.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct OutlineDeclaration {
+ pub declaration: DeclarationSpan,
+ pub kind_span: Span,
+ pub alias_span: Span,
+ /// Whole quoted header ID token, even if it is not a valid UUID. In that
+ /// case declaration.id is None. Missing/non-string ID values have no span.
+ pub id_literal_span: Option<Span>,
+}
+
+/// A full-file tolerant scan, not a successful parse or validated model. Invalid
+/// text remains available. Lexical errors and unmatched braces are facts only:
+/// their absence does not establish syntactic or semantic validity.
+///
+/// A budget failure returns Err and no partial Outline. Include reachability,
+/// project completeness and editor revision are intentionally not inferred here.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Outline<'a> {
+ pub source: &'a str,
+ pub tokens: Vec<TokenSpan>,
+ pub declarations: Vec<OutlineDeclaration>,
+ pub has_lexical_errors: bool,
+ pub has_unmatched_braces: bool,
+}
+
/// Tolerant highlighting tokens cover the whole input, including incomplete
/// strings and unexpected characters. No model is created or modified.
pub fn tokenize(source: &str) -> Vec<TokenSpan> {
+ tokenize_with_limit(source, usize::MAX).expect("unlimited token scan")
+}
+
+fn tokenize_with_limit(source: &str, max_tokens: usize) -> Result<Vec<TokenSpan>, OutlineLimit> {
let mut tokens = Vec::new();
let mut cursor = 0;
while cursor < source.len() {
+ if tokens.len() == max_tokens {
+ return Err(OutlineLimit {
+ resource: OutlineResource::Tokens,
+ limit: max_tokens,
+ observed_at_least: tokens.len().saturating_add(1),
+ offset: cursor,
+ });
+ }
let start = cursor;
let ch = source[cursor..].chars().next().expect("in bounds");
let class = if matches!(ch, ' ' | '\t' | '\r' | '\n') {
cursor += 1;
@@ -223,9 +298,9 @@
class,
span: Span { start, end: cursor },
});
}
- tokens
+ Ok(tokens)
}
pub fn lint(source: &str) -> Vec<Diagnostic> {
match parse_document(source, ParseLimits::UNLIMITED) {
@@ -1229,13 +1304,9 @@
}
self.cursor += 1;
let offset = self.current().span.start;
let value = self.quoted()?;
- if value.len() != 36
- || ![8, 13, 18, 23]
- .into_iter()
- .all(|i| value.as_bytes()[i] == b'-')
- {
+ if !has_uuid_header_shape(&value) {
return Err(Error {
code: "invalid_source",
offset,
message: "Expected UUID in 8-4-4-4-12 hexadecimal form.".into(),
@@ -1961,29 +2032,74 @@
}
/// Analyze an incomplete source buffer without adopting a candidate. Declaration
/// spans remain available even when a later declaration contains errors.
+/// Invalid compact/braced/URN header IDs retain no authored identity, matching
+/// the declaration parser rather than the UUID crate's broader accepted forms.
pub fn analyze(source: &str) -> Analysis {
let tokens = tokenize(source);
+ let (declarations, _) =
+ declaration_outline(source, &tokens, usize::MAX).expect("unlimited declaration walk");
+ Analysis {
+ tokens,
+ diagnostics: lint(source),
+ declarations: declarations.into_iter().map(|d| d.declaration).collect(),
+ }
+}
+
+/// Read exact current text without lint, parsing a model, stabilization or I/O.
+/// Source bytes are admitted before token allocation; token/declaration limits
+/// are checked before lexing the next token or materializing the next record.
+pub fn outline(source: &str, limits: OutlineLimits) -> Result<Outline<'_>, OutlineLimit> {
+ if source.len() > limits.max_source_bytes {
+ return Err(OutlineLimit {
+ resource: OutlineResource::SourceBytes,
+ limit: limits.max_source_bytes,
+ observed_at_least: source.len(),
+ offset: 0,
+ });
+ }
+ let tokens = tokenize_with_limit(source, limits.max_tokens)?;
+ let has_lexical_errors = tokens.iter().any(|token| token.class == TokenClass::Error);
+ let (declarations, has_unmatched_braces) =
+ declaration_outline(source, &tokens, limits.max_declarations)?;
+ Ok(Outline {
+ source,
+ tokens,
+ declarations,
+ has_lexical_errors,
+ has_unmatched_braces,
+ })
+}
+
+fn declaration_outline(
+ source: &str,
+ tokens: &[TokenSpan],
+ max_declarations: usize,
+) -> Result<(Vec<OutlineDeclaration>, bool), OutlineLimit> {
let significant = tokens
.iter()
.filter(|t| !matches!(t.class, TokenClass::Whitespace | TokenClass::Comment))
.collect::<Vec<_>>();
// Recover matched body bounds once. Scanning each aggregate's descendants
// again would make tolerant navigation quadratic on deeply nested drafts.
let mut body_ends = vec![None; significant.len()];
let mut bodies = Vec::new();
+ let mut unmatched_close = false;
for (index, token) in significant.iter().enumerate() {
match &source[token.span.start..token.span.end] {
"{" => bodies.push(index),
"}" => {
if let Some(open) = bodies.pop() {
body_ends[open] = Some(token.span.end);
+ } else {
+ unmatched_close = true;
}
}
_ => {}
}
}
+ let has_unmatched_braces = unmatched_close || !bodies.is_empty();
let mut declarations = Vec::new();
for (i, t) in significant.iter().enumerate() {
let word = &source[t.span.start..t.span.end];
if declaration_kind(word).is_none() && word != "project" {
@@ -2006,48 +2122,69 @@
continue;
}
j += 1;
}
+ if declarations.len() == max_declarations {
+ return Err(OutlineLimit {
+ resource: OutlineResource::Declarations,
+ limit: max_declarations,
+ observed_at_least: declarations.len().saturating_add(1),
+ offset: t.span.start,
+ });
+ }
let mut id = None;
+ let mut id_literal_span = None;
if significant
.get(j)
.is_some_and(|t| &source[t.span.start..t.span.end] == "id")
{
if let Some(value) = significant.get(j + 1)
&& value.class == TokenClass::String
{
+ id_literal_span = Some(value.span);
let text =
serde_json::from_str::<String>(&source[value.span.start..value.span.end])
.unwrap();
- id = Id::parse_str(&text).ok();
+ if has_uuid_header_shape(&text) {
+ id = Id::parse_str(&text).ok();
+ }
}
j += 2;
}
- let mut end = significant
- .get(j)
- .map_or(alias_token.span.end, |t| t.span.end);
+ // A recognized header ID at EOF must remain inside the whole span.
+ // Keep the old next-token/body behavior; only the EOF fallback changes.
+ let header_end = significant
+ .get(j.saturating_sub(1))
+ .or_else(|| significant.last())
+ .map_or(alias_token.span.end, |token| token.span.end);
+ let mut end = significant.get(j).map_or(header_end, |t| t.span.end);
if significant
.get(j)
.is_some_and(|t| &source[t.span.start..t.span.end] == "{")
{
end = body_ends[j].unwrap_or(source.len());
}
- declarations.push(DeclarationSpan {
- alias: alias.into(),
- id,
- kind: word.into(),
- span: Span {
- start: t.span.start,
- end,
+ declarations.push(OutlineDeclaration {
+ declaration: DeclarationSpan {
+ alias: alias.into(),
+ id,
+ kind: word.into(),
+ span: Span {
+ start: t.span.start,
+ end,
+ },
},
+ kind_span: t.span,
+ alias_span: alias_token.span,
+ id_literal_span,
});
}
- Analysis {
- tokens,
- diagnostics: lint(source),
- declarations,
- }
-}
+ Ok((declarations, has_unmatched_braces))
+}
+
+#[cfg(test)]
+#[path = "language_outline_tests.rs"]
+mod outline_tests;
#[cfg(test)]
#[path = "language_nesting_tests.rs"]
mod nesting_tests;
@@ -2441,13 +2578,9 @@
let offset = self.current().offset;
let value = self.quoted()?;
// Require the portable 8-4-4-4-12 spelling, not the UUID crate's URN,
// braces, or compact alternatives. Uppercase hexadecimal is accepted.
- if value.len() != 36
- || ![8, 13, 18, 23]
- .into_iter()
- .all(|index| value.as_bytes()[index] == b'-')
- {
+ if !super::has_uuid_header_shape(&value) {
return Err(Error {
code: "invalid_source",
offset,
message: "Expected a UUID string in 8-4-4-4-12 hexadecimal form.".into(),
--- /dev/null
+++ b/crates/oa-core/src/language_outline_tests.rs
@@ -0,0 +1,271 @@
+//! Prepared outline tests. Explicit compatibility tests additionally exercise
+//! the existing parsers/analyze; the outline entry itself never calls them.
+use super::*;
+
+fn limits() -> OutlineLimits {
+ OutlineLimits {
+ max_source_bytes: 1024 * 1024,
+ max_tokens: 100_000,
+ max_declarations: 1_000,
+ }
+}
+
+fn declaration<'a>(result: &'a Outline<'_>, alias: &str) -> &'a OutlineDeclaration {
+ result.declarations.iter().find(|d| d.declaration.alias == alias).unwrap()
+}
+
+fn text(source: &str, span: Span) -> &str {
+ &source[span.start..span.end]
+}
+
+#[test]
+fn outline_roles_preserve_unicode_crlf_and_exact_escaped_uuid_literal() {
+ let source = "// 検査 🚒\r\noa_actor responder \"救助\" id \"\\u00300000000-0000-0000-0000-000000000001\" {}\r\nsource @ // 使用\r\n responder;";
+ let before = source.as_bytes().to_vec();
+ let result = outline(source, limits()).unwrap();
+ assert_eq!(result.source.as_bytes(), before);
+ assert_eq!(result.source.as_ptr(), source.as_ptr());
+ let d = declaration(&result, "responder");
+ assert_eq!(text(source, d.kind_span), "oa_actor");
+ assert_eq!(text(source, d.alias_span), "responder");
+ assert_eq!(text(source, d.id_literal_span.unwrap()), "\"\\u00300000000-0000-0000-0000-000000000001\"");
+ assert_eq!(d.declaration.id, Some(Id::from_u128(1)));
+ assert_eq!(d.declaration.span.start, source.find("oa_actor").unwrap());
+ assert_eq!(d.declaration.span.end, source.find("{}\r\n").unwrap() + 2);
+ let mut end = 0;
+ for token in &result.tokens {
+ assert_eq!(token.span.start, end);
+ assert!(token.span.start < token.span.end);
+ assert!(source.is_char_boundary(token.span.start));
+ assert!(source.is_char_boundary(token.span.end));
+ end = token.span.end;
+ }
+ assert_eq!(end, source.len());
+ assert!(!result.has_lexical_errors);
+ assert!(!result.has_unmatched_braces);
+}
+
+#[test]
+fn closed_id_at_eof_is_inside_the_declaration_extent() {
+ for source in [
+ "oa_actor a \"Actor\" id \"00000000-0000-0000-0000-000000000001\"",
+ "node placed id \"00000000-0000-0000-0000-000000000001\"",
+ ] {
+ let result = outline(source, limits()).unwrap();
+ let d = &result.declarations[0];
+ let literal = d.id_literal_span.unwrap();
+ assert_eq!(d.declaration.id, Some(Id::from_u128(1)));
+ assert_eq!(d.declaration.span.end, source.len());
+ assert!(d.declaration.span.start <= literal.start);
+ assert!(literal.end <= d.declaration.span.end);
+ }
+ for source in ["oa_actor a \"Actor\"", "oa_actor a \"Actor\" id"] {
+ let result = outline(source, limits()).unwrap();
+ let d = &result.declarations[0];
+ assert_eq!(d.declaration.span.end, source.len());
+ assert_eq!(d.declaration.id, None);
+ assert_eq!(d.id_literal_span, None);
+ }
+}
+
+#[test]
+fn missing_bad_and_historical_ids_never_allocate_authored_identity() {
+ let source = "oa_actor missing \"No ID\" {}\noa_actor bad \"Bad ID\" id \"not-a-uuid\" {}\noa_actor historical \"00000000-0000-0000-0000-000000000001\" { history uuid \"00000000-0000-0000-0000-000000000001\"; }";
+ let first = outline(source, limits()).unwrap();
+ let second = outline(source, limits()).unwrap();
+ assert_eq!(first, second);
+ assert!(first.declarations.iter().all(|d| d.declaration.id.is_none()));
+ assert_eq!(declaration(&first, "missing").id_literal_span, None);
+ assert_eq!(declaration(&first, "historical").id_literal_span, None);
+ assert_eq!(text(source, declaration(&first, "bad").id_literal_span.unwrap()), "\"not-a-uuid\"");
+ // Balanced tokens are not a successful syntax/semantic validation claim.
+ assert!(!first.has_lexical_errors);
+ assert!(!first.has_unmatched_braces);
+}
+
+#[test]
+fn invalid_full_scan_keeps_closed_children_and_reports_lexical_body_facts() {
+ let source = "oa_entity outer \"Outer\" {\n oa_actor ready \"Ready\" { description \"} stays text\"; }\n oa_actor pending \"Pending\" { description \"unfinished 🌊";
+ let result = outline(source, limits()).unwrap();
+ assert_eq!(result.source, source);
+ assert_eq!(result.tokens.last().unwrap().span.end, source.len());
+ assert!(result.has_lexical_errors);
+ assert!(result.has_unmatched_braces);
+ let ready = declaration(&result, "ready");
+ assert_eq!(text(source, ready.declaration.span), "oa_actor ready \"Ready\" { description \"} stays text\"; }");
+ assert_eq!(declaration(&result, "outer").declaration.span.end, source.len());
+ assert_eq!(declaration(&result, "pending").declaration.span.end, source.len());
+ let unmatched_close = outline("}\n// brace in comment {\n", limits()).unwrap();
+ assert!(unmatched_close.has_unmatched_braces);
+ assert!(!unmatched_close.has_lexical_errors);
+}
+
+#[test]
+fn missing_body_syntax_is_unchecked_even_when_known_error_flags_are_clear() {
+ let source = "oa_actor a \"A\" id \"00000000-0000-0000-0000-000000000001\"";
+ let result = outline(source, limits()).unwrap();
+ assert_eq!(result.declarations.len(), 1);
+ assert!(!result.has_lexical_errors);
+ assert!(!result.has_unmatched_braces);
+ // There is deliberately no `valid` flag: the known-complete fact is scanning
+ // these bytes, not the missing body becoming legal or the draft being applied.
+ assert_eq!(result.source, source);
+}
+
+#[test]
+fn keyword_alias_and_collisions_keep_every_source_ordered_header() {
+ let source = "project root_model \"Model\" {\n oa_actor oa_activity \"First\" id \"00000000-0000-0000-0000-000000000001\" {}\n oa_actor oa_activity \"Second\" id \"00000000-0000-0000-0000-000000000001\" {}\n diagram view_one \"View\" {}\n node placement { diagram @view_one; }\n}";
+ let result = outline(source, limits()).unwrap();
+ assert_eq!(result.declarations.len(), 5);
+ let duplicates: Vec<_> = result.declarations.iter().filter(|d| d.declaration.alias == "oa_activity").collect();
+ assert_eq!(duplicates.len(), 2);
+ assert!(duplicates[0].alias_span.start < duplicates[1].alias_span.start);
+ assert_eq!(duplicates[0].declaration.id, duplicates[1].declaration.id);
+ assert!(result.tokens.iter().any(|t| t.span == duplicates[0].alias_span && t.class == TokenClass::Keyword));
+ assert_eq!(text(source, declaration(&result, "placement").kind_span), "node");
+ assert_eq!(declaration(&result, "placement").declaration.id, None);
+}
+
+#[test]
+fn bounds_refuse_before_returning_a_partial_outline() {
+ let source = "oa_actor a \"A\" {}\noa_actor b \"B\" {}";
+ let admitted = outline(source, limits()).unwrap();
+ let exact = OutlineLimits {
+ max_source_bytes: source.len(),
+ max_tokens: admitted.tokens.len(),
+ max_declarations: 2,
+ };
+ assert_eq!(outline(source, exact).unwrap(), admitted);
+ for resource in [OutlineResource::SourceBytes, OutlineResource::Tokens, OutlineResource::Declarations] {
+ let mut lower = exact;
+ match resource {
+ OutlineResource::SourceBytes => lower.max_source_bytes -= 1,
+ OutlineResource::Tokens => lower.max_tokens -= 1,
+ OutlineResource::Declarations => lower.max_declarations -= 1,
+ }
+ let error = outline(source, lower).unwrap_err();
+ assert_eq!(error.resource, resource);
+ assert!(error.observed_at_least > error.limit);
+ assert!(source.is_char_boundary(error.offset));
+ if resource == OutlineResource::Declarations {
+ assert_eq!(error.offset, source.find("oa_actor b").unwrap());
+ }
+ }
+ let empty = outline("", OutlineLimits { max_source_bytes: 0, max_tokens: 0, max_declarations: 0 }).unwrap();
+ assert!(empty.tokens.is_empty() && empty.declarations.is_empty());
+ let unicode = "// 🌊\r\noa_actor a \"A\" {}";
+ let error = outline(unicode, OutlineLimits { max_source_bytes: 4, ..limits() }).unwrap_err();
+ assert_eq!(error.resource, OutlineResource::SourceBytes);
+ assert_eq!(error.offset, 0);
+ let error = outline(unicode, OutlineLimits { max_tokens: 1, ..limits() }).unwrap_err();
+ assert_eq!(error.resource, OutlineResource::Tokens);
+ assert_eq!(error.offset, unicode.find('\n').unwrap());
+}
+
+#[test]
+fn outline_ranges_follow_current_bytes_without_identity_stabilization() {
+ let old = "oa_actor a \"A\" {}\nsource @a;";
+ let current = format!("// 航海 🚒\r\n{old}");
+ let old_outline = outline(old, limits()).unwrap();
+ let current_outline = outline(&current, limits()).unwrap();
+ let shift = current.len() - old.len();
+ let old_role = &old_outline.declarations[0];
+ let current_role = &current_outline.declarations[0];
+ assert_eq!(current_role.alias_span.start, old_role.alias_span.start + shift);
+ assert_eq!(current_role.kind_span.start, old_role.kind_span.start + shift);
+ assert_eq!(current_role.declaration.span.end, old_role.declaration.span.end + shift);
+ assert_eq!(current_outline.source, current);
+ assert_eq!(old_outline.source, old);
+ assert_eq!(current_role.declaration.id, None);
+ assert!(!current_outline.source.contains(" id "));
+ // Workspace revision/stale-handle rejection belongs to the query/adapter,
+ // not a claim that an old owned span can be applied to any other string.
+}
+
+#[test]
+fn deeply_nested_bounds_use_the_same_iterative_walk_and_declaration_budget() {
+ let mut source = String::new();
+ for index in 0..600 {
+ source.push_str(&format!("oa_activity work_{index} \"Work\" {{\n"));
+ }
+ source.push_str(&"}\n".repeat(600));
+ let result = outline(&source, limits()).unwrap();
+ assert_eq!(result.declarations.len(), 600);
+ assert!(!result.has_unmatched_braces);
+ assert_eq!(result.declarations[0].declaration.span.end, source.len() - 1);
+ let error = outline(&source, OutlineLimits { max_declarations: 599, ..limits() }).unwrap_err();
+ assert_eq!(error.resource, OutlineResource::Declarations);
+ assert_eq!(error.observed_at_least, 600);
+ assert_eq!(error.offset, source.find("oa_activity work_599").unwrap());
+}
+
+#[test]
+fn noncanonical_uuid_spellings_have_no_outline_or_analysis_identity() {
+ for raw in [
+ "00000000000000000000000000000001",
+ "{00000000-0000-0000-0000-000000000001}",
+ "urn:uuid:00000000-0000-0000-0000-000000000001",
+ ] {
+ assert!(Id::parse_str(raw).is_ok(), "The UUID crate alone is too permissive");
+ assert!(!has_uuid_header_shape(raw));
+ let literal = format!("\"{raw}\"");
+ let modern = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
+ let before = modern.clone();
+ let result = outline(&modern, limits()).unwrap();
+ let d = declaration(&result, "model");
+ assert_eq!(d.declaration.id, None);
+ assert_eq!(text(&modern, d.id_literal_span.unwrap()), literal);
+ assert_eq!(modern, before);
+ let errors = parse(&modern).unwrap_err();
+ assert!(errors.iter().any(|error| error.message.contains("8-4-4-4-12")
+ && error.span.start == modern.find(&literal).unwrap()));
+ // Intentional compatibility correction: old analyze yielded Some(Id(1))
+ // here despite lint rejecting the header. It now shares outline's None.
+ let analysis = analyze(&modern);
+ assert_eq!(analysis.declarations.iter().find(|d| d.alias == "model").unwrap().id, None);
+ assert!(analysis.diagnostics.iter().any(|error| error.message.contains("8-4-4-4-12")));
+ let legacy_source = format!("arcadia 1; project \"Legacy\" id {literal} {{}}");
+ let legacy_errors = legacy::parse(&legacy_source).unwrap_err();
+ assert!(legacy_errors.iter().any(|error| error.message.contains("8-4-4-4-12")));
+ }
+}
+
+#[test]
+fn uppercase_and_json_escaped_header_ids_survive_both_parsers_and_outline() {
+ let expected = Id::from_u128(0xabcdef);
+ let canonical = expected.to_string();
+ let uppercase = canonical.to_uppercase();
+ assert_ne!(uppercase, canonical);
+ for raw in [uppercase.clone(), format!("\\u0030{}", &uppercase[1..])] {
+ let literal = format!("\"{raw}\"");
+ let decoded: String = serde_json::from_str(&literal).unwrap();
+ assert!(has_uuid_header_shape(&decoded));
+ let modern = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
+ let result = outline(&modern, limits()).unwrap();
+ let d = declaration(&result, "model");
+ assert_eq!(d.declaration.id, Some(expected));
+ assert_eq!(text(&modern, d.id_literal_span.unwrap()), literal);
+ assert_eq!(result.source.as_bytes(), modern.as_bytes());
+ assert_eq!(parse(&modern).unwrap().id, expected);
+ let analysis = analyze(&modern);
+ assert_eq!(analysis.declarations[0].id, Some(expected));
+ assert!(!analysis.diagnostics.iter().any(|error| error.severity == crate::validation::Severity::Error));
+ let legacy_source = format!("arcadia 1; project \"Legacy\" id {literal} {{}}");
+ assert_eq!(legacy::parse(&legacy_source).unwrap().id, expected);
+ }
+}
+
+#[test]
+fn header_shape_still_requires_valid_hexadecimal_uuid_data() {
+ let raw = "00000000-0000-0000-0000-00000000000Z";
+ assert!(has_uuid_header_shape(raw));
+ assert!(Id::parse_str(raw).is_err());
+ let literal = format!("\"{raw}\"");
+ let source = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
+ let result = outline(&source, limits()).unwrap();
+ let d = declaration(&result, "model");
+ assert_eq!(d.declaration.id, None);
+ assert_eq!(text(&source, d.id_literal_span.unwrap()), literal);
+ assert!(parse(&source).unwrap_err().iter().any(|error| error.message == "Invalid UUID identity."));
+ assert_eq!(analyze(&source).declarations[0].id, None);
+}
@@ -0,0 +1,129 @@
--- a/.local/text-navigation-probe-20260911/source_symbols.rs
+++ b/.local/text-navigation-probe-20260911/source_symbols.rs
@@ -7,9 +7,9 @@
//! Its matches are authored lexical uses, not typed semantic dependency edges.
use oa_core::language::{Span, TokenClass, TokenSpan};
use oa_core::Id;
-use std::collections::BTreeMap;
+use std::collections::{BTreeMap, BTreeSet};
use std::ops::Range;
/// Fresh editor/workspace session identity plus a revision changed for EVERY
/// indexed input change, including membership, outline and validation evidence.
@@ -357,16 +357,19 @@
|| files.iter().any(|file| file.membership == Membership::Unverified))
{
return Err(input_error(0, None, InputProblem::InconsistentCompleteScope));
}
+ // Scratch storage is allocated only after aggregate file/path admission.
+ // Each admitted path is folded once, retaining core's Unicode policy.
+ let mut folded_paths = BTreeSet::new();
for (file_index, file) in files.iter().copied().enumerate() {
if file.syntax != SyntaxCoverage::FullFile {
return Err(input_error(file_index, None, InputProblem::IncompleteSyntax));
}
if oa_core::source_project::resolve_include("", file.path).as_deref() != Ok(file.path) {
return Err(input_error(file_index, None, InputProblem::NonCanonicalPath));
}
- if files[..file_index].iter().any(|other| other.path.eq_ignore_ascii_case(file.path)) {
+ if !folded_paths.insert(file.path.to_lowercase()) {
return Err(input_error(file_index, None, InputProblem::DuplicateOrCaseCollidingPath));
}
let mut end = 0;
for (token_index, token) in file.tokens.iter().enumerate() {
@@ -417,8 +420,9 @@
}
let literal = &file.text[identity.literal_span.start..identity.literal_span.end];
let decoded = serde_json::from_str::<String>(literal)
.ok()
+ .filter(|value| oa_core::language::has_uuid_header_shape(value))
.and_then(|value| Id::parse_str(&value).ok());
if decoded != Some(identity.id) {
return Err(problem(InputProblem::IdentityLiteral));
}
@@ -1005,8 +1009,84 @@
}
}
#[test]
+ fn unicode_path_collisions_match_core_lowercase_policy() {
+ for (first_path, second_path) in [("Ä.arcadia", "ä.arcadia"), ("ΟΣ/model.arcadia", "ος/model.arcadia")] {
+ let first = Fixture::new(first_path, "source @a;".into(), &[]);
+ let second = Fixture::new(second_path, "source @b;".into(), &[]);
+ assert_eq!(first_path.to_lowercase(), second_path.to_lowercase());
+ assert!(!first_path.eq_ignore_ascii_case(second_path));
+ assert!(matches!(Index::build(snapshot(1), &[first.included(), second.included()], Scope::CompleteProject, limits()), Err(BuildError::Input { problem: InputProblem::DuplicateOrCaseCollidingPath, .. })));
+ }
+ }
+
+ #[test]
+ fn noncanonical_header_identity_cannot_enter_through_query_metadata() {
+ for raw in [
+ "00000000000000000000000000000001",
+ "{00000000-0000-0000-0000-000000000001}",
+ "urn:uuid:00000000-0000-0000-0000-000000000001",
+ ] {
+ let literal = format!("\"{raw}\"");
+ let source = format!("oa_actor a \"A\" id {literal} {{}}\nsource @a;");
+ let mut fixture = Fixture::new("project.arcadia", source.clone(), &[("oa_actor", "a", None)]);
+ let start = source.find(&literal).unwrap();
+ // This fixture has one explicit empty body. A brace inside the
+ // quoted UUID must not become the test's declaration end.
+ let body_start = source.find("{}\n").unwrap();
+ fixture.declarations[0].span.end = body_start + 2;
+ assert!(start + literal.len() <= body_start);
+ // An adapter passes None from the corrected outline; lexical
+ // definition/reference navigation survives without an ID anchor.
+ {
+ let admitted = index(&[fixture.included()]);
+ let d = definition(&admitted, "a");
+ assert_eq!(admitted.identity(d), Ok(Identity::Missing));
+ assert_eq!(admitted.references_to(d, Domain::Included).unwrap().count(), 1);
+ assert_eq!(admitted.source(0).unwrap().text, source);
+ }
+ // A forged/stale caller cannot put the UUID crate's permissive
+ // interpretation back into an authored anchor via the raw API.
+ fixture.declarations[0].identity = Some(AuthoredIdentity {
+ id: A,
+ literal_span: Span { start, end: start + literal.len() },
+ });
+ assert!(matches!(Index::build(snapshot(1), &[fixture.included()], Scope::CompleteProject, limits()), Err(BuildError::Input { problem: InputProblem::IdentityLiteral, .. })));
+ }
+ }
+
+ #[test]
+ fn query_header_admission_preserves_uppercase_and_json_escape_bytes() {
+ let expected = Id::from_u128(0xabcdef);
+ let uppercase = expected.to_string().to_uppercase();
+ for raw in [uppercase.clone(), format!("\\u0030{}", &uppercase[1..])] {
+ let literal = format!("\"{raw}\"");
+ let source = format!("oa_actor a \"A\" id {literal} {{}}\nsource @a;");
+ let mut fixture = Fixture::new("project.arcadia", source.clone(), &[("oa_actor", "a", None)]);
+ let start = source.find(&literal).unwrap();
+ fixture.declarations[0].identity = Some(AuthoredIdentity {
+ id: expected,
+ literal_span: Span { start, end: start + literal.len() },
+ });
+ let admitted = index(&[fixture.included()]);
+ assert_eq!(anchor(&admitted, definition(&admitted, "a")).id(), expected);
+ assert_eq!(admitted.source(0).unwrap().text.as_bytes(), source.as_bytes());
+ }
+ }
+
+ #[test]
+ fn admitted_unicode_path_budget_keeps_original_policy_after_single_fold() {
+ let fixture = Fixture::new("İ.arcadia", String::new(), &[]);
+ assert!(fixture.path.to_lowercase().len() > fixture.path.len());
+ let exact = Limits { files: 1, source_bytes: 0, path_bytes: fixture.path.len(), tokens: 0, records: 0 };
+ let admitted = Index::build(snapshot(1), &[fixture.included()], Scope::CompleteProject, exact).unwrap();
+ assert_eq!(admitted.source(0).unwrap().path, "İ.arcadia");
+ // PathBytes continues to count authored input. One lowercase key's
+ // Unicode expansion is bounded scratch, not a new path rejection rule.
+ }
+
+ #[test]
fn every_budget_admits_boundary_and_returns_no_index_one_below() {
let fixture = Fixture::new("project.arcadia", "oa_actor a \"Text\" {}\nsource @a; target @a;".into(), &[("oa_actor", "a", None)]);
let exact = Limits { files: 1, source_bytes: fixture.text.len(), path_bytes: fixture.path.len(), tokens: fixture.tokens.len(), records: 3 };
assert!(Index::build(snapshot(1), &[fixture.included()], Scope::CompleteProject, exact).is_ok());
@@ -0,0 +1,16 @@
{
"started": "2026-09-11T16:56:18.6477215Z",
"finished": "2026-09-11T16:56:23.5765392Z",
"exitCode": 0,
"executable": "cargo",
"args": [
"build",
"--locked",
"--offline",
"-p",
"oa-core",
"--lib",
"--message-format=json"
],
"buildJobs": 1
}
@@ -0,0 +1 @@
Finished `dev` profile [unoptimized] target(s) in 3.41s
@@ -0,0 +1,44 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.107","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\proc-macro2-1.0.107\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\proc-macro2-1.0.107\\build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\proc-macro2-8bd275bc14efcc6d\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.107","linked_libs":[],"linked_paths":[],"cfgs":["wrap_proc_macro","proc_macro_span_location","proc_macro_span_file"],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\proc-macro2-678fa29727a3d951\\out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#quote@1.0.47","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\quote-1.0.47\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\quote-1.0.47\\build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\quote-78b7b00c15767e2b\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.24","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\unicode-ident-1.0.24\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unicode_ident","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\unicode-ident-1.0.24\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libunicode_ident-37cacd323a49429c.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libunicode_ident-37cacd323a49429c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.107","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\proc-macro2-1.0.107\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"proc_macro2","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\proc-macro2-1.0.107\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libproc_macro2-80e9e45547beebf5.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libproc_macro2-80e9e45547beebf5.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#quote@1.0.47","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\quote-db749d68bbb2dbfe\\out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#quote@1.0.47","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\quote-1.0.47\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"quote","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\quote-1.0.47\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libquote-b79aec363b458000.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libquote-b79aec363b458000.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.229","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_core-1.0.229\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_core-1.0.229\\build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["result","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\serde_core-161b3ae2683262f1\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.229","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\serde_core-a1da37301c02ee2a\\out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#syn@3.0.5","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\syn-3.0.5\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"syn","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\syn-3.0.5\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["clone-impls","default","derive","parsing","printing","proc-macro"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libsyn-2232b8c89352da95.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libsyn-2232b8c89352da95.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#windows-link@0.2.1","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\windows-link-0.2.1\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"windows_link","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\windows-link-0.2.1\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libwindows_link-23f115c823619f71.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libwindows_link-23f115c823619f71.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.3","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\getrandom-0.4.3\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\getrandom-0.4.3\\build.rs","edition":"2024","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\getrandom-168cb7f91c8645ca\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.3","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\getrandom-4967b63cf7b288b8\\out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#windows-sys@0.61.2","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\windows-sys-0.61.2\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"windows_sys","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\windows-sys-0.61.2\\src\\lib.rs","edition":"2021","doc":true,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["Win32","Win32_Foundation","Win32_Storage","Win32_Storage_FileSystem","Win32_System","Win32_System_Console","Win32_System_SystemInformation","default"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libwindows_sys-43b3d9a205b229b7.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libwindows_sys-43b3d9a205b229b7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.229","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_core-1.0.229\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_core","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_core-1.0.229\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["result","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_core-f52ac0796dd4fc39.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_core-f52ac0796dd4fc39.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\cfg-if-1.0.4\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cfg_if","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\cfg-if-1.0.4\\src\\lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libcfg_if-805b2ebc84d544f1.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libcfg_if-805b2ebc84d544f1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.23","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\zmij-1.0.23\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\zmij-1.0.23\\build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\zmij-e8f67a20243f3063\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.23","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\zmij-c8f8f3187a72be14\\out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.3","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\getrandom-0.4.3\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"getrandom","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\getrandom-0.4.3\\src\\lib.rs","edition":"2024","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libgetrandom-6e8efb5a01ff0cbb.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libgetrandom-6e8efb5a01ff0cbb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.20","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\thiserror-2.0.20\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\thiserror-2.0.20\\build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\thiserror-d9d1cecb0b9dfa9d\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde-1.0.229\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde-1.0.229\\build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","derive","serde_derive","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\serde-c9911adbe87e85d2\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_json-1.0.151\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_json-1.0.151\\build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\serde_json-28521d5277e5c15b\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151","linked_libs":[],"linked_paths":[],"cfgs":["fast_arithmetic=\"64\""],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\serde_json-908788f6700df5fb\\out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229","linked_libs":[],"linked_paths":[],"cfgs":["if_docsrs_then_no_serde_core"],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\serde-963672309bf9e4ba\\out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.20","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\thiserror-2e28320913ae6f8a\\out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zmij@1.0.23","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\zmij-1.0.23\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zmij","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\zmij-1.0.23\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libzmij-9f8770986f00ef15.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libzmij-9f8770986f00ef15.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#winapi-util@0.1.11","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\winapi-util-0.1.11\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"winapi_util","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\winapi-util-0.1.11\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libwinapi_util-be9ab0847edf5b05.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libwinapi_util-be9ab0847edf5b05.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.20","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\thiserror-impl-2.0.20\\Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"thiserror_impl","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\thiserror-impl-2.0.20\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\thiserror_impl-774eb7636a800724.dll","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libthiserror_impl-774eb7636a800724.dll.a"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.229","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_derive-1.0.229\\Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"serde_derive","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_derive-1.0.229\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\serde_derive-c07a6353fdd1d8a1.dll","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_derive-c07a6353fdd1d8a1.dll.a"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.4","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\once_cell-1.21.4\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"once_cell","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\once_cell-1.21.4\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","race","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libonce_cell-f7e62c44737ecbb9.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libonce_cell-f7e62c44737ecbb9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#sha1_smol@1.0.1","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\sha1_smol-1.0.1\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"sha1_smol","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\sha1_smol-1.0.1\\src\\lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libsha1_smol-c4b7e5ec8b41792e.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libsha1_smol-c4b7e5ec8b41792e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.18","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\itoa-1.0.18\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"itoa","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\itoa-1.0.18\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libitoa-971c3e13d32ffcf2.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libitoa-971c3e13d32ffcf2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fastrand@2.5.0","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\fastrand-2.5.0\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fastrand","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\fastrand-2.5.0\\src\\lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libfastrand-3df248e815d242e1.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libfastrand-3df248e815d242e1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.3","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\memchr-2.8.3\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"memchr","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\memchr-2.8.3\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libmemchr-088af8780d4df76d.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libmemchr-088af8780d4df76d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"path+file:///C:/Users/User/Documents/Git/ARCADIA-Studio/crates/oa-core#0.2.0","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\crates\\oa-core\\Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\crates\\oa-core\\build.rs","edition":"2024","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\oa-core-6f46b396061b0e99\\build-script-build.exe"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"path+file:///C:/Users/User/Documents/Git/ARCADIA-Studio/crates/oa-core#0.2.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\build\\oa-core-08552b12a2cacda2\\out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_json-1.0.151\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_json","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_json-1.0.151\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tempfile@3.27.0","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\tempfile-3.27.0\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tempfile","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\tempfile-3.27.0\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","getrandom"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libtempfile-20c336358d7a22b5.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libtempfile-20c336358d7a22b5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#uuid@1.26.0","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\uuid-1.26.0\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"uuid","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\uuid-1.26.0\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","rng","serde","sha1","std","v4","v5"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libuuid-f7851e8936dae115.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libuuid-f7851e8936dae115.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.229","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde-1.0.229\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde-1.0.229\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","derive","serde_derive","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde-968c91fb77bb5d38.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde-968c91fb77bb5d38.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.20","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\thiserror-2.0.20\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"thiserror","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\thiserror-2.0.20\\src\\lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libthiserror-add096f46a35d6d2.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libthiserror-add096f46a35d6d2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\same-file-1.0.6\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"same_file","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\same-file-1.0.6\\src\\lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libsame_file-a21d6395ce590b18.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libsame_file-a21d6395ce590b18.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"path+file:///C:/Users/User/Documents/Git/ARCADIA-Studio/crates/oa-core#0.2.0","manifest_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\crates\\oa-core\\Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"oa_core","src_path":"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\crates\\oa-core\\src\\lib.rs","edition":"2024","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\liboa_core.rlib","C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\liboa_core-781c6973417b169c.rmeta"],"executable":null,"fresh":true}
{"reason":"build-finished","success":true}
@@ -0,0 +1,18 @@
{
"started": "2026-09-11T17:18:18.6539471Z",
"finished": "2026-09-11T17:18:37.5366321Z",
"exitCode": 0,
"args": [
"clippy",
"--locked",
"--offline",
"-p",
"oa-core",
"--lib",
"--tests",
"--",
"-D",
"warnings"
],
"buildJobs": 1
}
@@ -0,0 +1,2 @@
Checking oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\crates\oa-core)
Finished `dev` profile [unoptimized] target(s) in 18.22s
@@ -0,0 +1,17 @@
{
"started": "2026-09-11T16:48:34.5596000Z",
"finished": "2026-09-11T16:55:38.1131532Z",
"exitCode": 0,
"args": [
"clippy",
"--locked",
"--offline",
"-p",
"oa-core",
"--all-targets",
"--",
"-D",
"warnings"
],
"buildJobs": 1
}
@@ -0,0 +1,2 @@
Checking oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\crates\oa-core)
Finished `dev` profile [unoptimized] target(s) in 7m 02s
@@ -0,0 +1,10 @@
{
"started": "2026-09-11T16:56:16.8520811Z",
"finished": "2026-09-11T16:56:18.0426484Z",
"exitCode": 0,
"executable": "rustc",
"args": [
"-vV"
],
"buildJobs": 1
}
@@ -0,0 +1,7 @@
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
@@ -0,0 +1,15 @@
{
"started": "2026-09-11T16:23:10.2275390Z",
"finished": "2026-09-11T16:48:34.5241796Z",
"exitCode": 0,
"args": [
"test",
"--locked",
"--offline",
"-p",
"oa-core",
"--",
"--test-threads=1"
],
"buildJobs": 1
}
@@ -0,0 +1,694 @@
Compiling oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\crates\oa-core)
Finished `test` profile [unoptimized] target(s) in 21m 33s
Running unittests src\lib.rs (.local\target-gnullvm\debug\deps\oa_core-e594d1d7e7cdca87.exe)
running 54 tests
test language::nesting_tests::checked_in_example_supports_cross_file_reparent_without_changing_allocations ... ok
test language::nesting_tests::checked_in_nested_example_has_stable_ids_typed_exchanges_and_three_clear_views ... ok
test language::nesting_tests::containment_validation_rejects_allocation_like_or_cross_layer_nesting ... ok
test language::nesting_tests::declarations_are_preorder_occurrences_with_real_own_field_and_body_spans ... ok
test language::nesting_tests::deep_declaration_parsing_and_positions_use_a_bounded_rust_stack ... ok
test language::nesting_tests::matching_explicit_parent_is_accepted_but_none_or_another_owner_is_located ... ok
test language::nesting_tests::nested_aliases_remain_global_and_forward_references_remain_legal ... ok
test language::nesting_tests::nested_elements_infer_only_parent_and_keep_typed_fields_and_allocations_explicit ... ok
test language::nesting_tests::nested_fragment_id_stabilization_preserves_comments_and_indexes_real_bytes ... ok
test language::nesting_tests::nested_record_admission_precedes_resolution_and_typed_depth_stays_bounded ... ok
test language::nesting_tests::non_elements_includes_and_declarations_inside_typed_values_are_rejected ... ok
test language::nesting_tests::normative_nested_ownership_example_compiles_as_a_source_fragment ... ok
test language::nesting_tests::syntax_edit_positions_retain_duplicate_identity_occurrences_during_a_command ... ok
test language::nesting_tests::tolerant_nested_analysis_retains_closed_children_before_an_unfinished_sibling ... ok
test language::outline_tests::bounds_refuse_before_returning_a_partial_outline ... ok
test language::outline_tests::closed_id_at_eof_is_inside_the_declaration_extent ... ok
test language::outline_tests::deeply_nested_bounds_use_the_same_iterative_walk_and_declaration_budget ... ok
test language::outline_tests::header_shape_still_requires_valid_hexadecimal_uuid_data ... ok
test language::outline_tests::invalid_full_scan_keeps_closed_children_and_reports_lexical_body_facts ... ok
test language::outline_tests::keyword_alias_and_collisions_keep_every_source_ordered_header ... ok
test language::outline_tests::missing_bad_and_historical_ids_never_allocate_authored_identity ... ok
test language::outline_tests::missing_body_syntax_is_unchecked_even_when_known_error_flags_are_clear ... ok
test language::outline_tests::noncanonical_uuid_spellings_have_no_outline_or_analysis_identity ... ok
test language::outline_tests::outline_ranges_follow_current_bytes_without_identity_stabilization ... ok
test language::outline_tests::outline_roles_preserve_unicode_crlf_and_exact_escaped_uuid_literal ... ok
test language::outline_tests::uppercase_and_json_escaped_header_ids_survive_both_parsers_and_outline ... ok
test semantic::catalog::coverage::every_current_payload_field_has_a_closed_typed_capture_and_write_scope ... ok
test source_files::transaction_tests::interrupted_publication_without_write_marker_never_rolls_back_external_matching_bytes ... ok
test source_files::transaction_tests::interrupted_save_and_interrupted_recovery_can_both_be_resumed ... ok
test source_files::transaction_tests::journal_publication_does_not_replace_empty_target_created_after_precheck ... ok
test source_files::transaction_tests::journal_publication_exhaustion_and_permanent_errors_keep_stage_and_report_original_path ... ok
test source_files::transaction_tests::journal_publication_never_replaces_another_journal_that_appears_during_retry ... ok
test source_files::transaction_tests::journal_publication_retries_only_transient_windows_errors_before_transferring_ownership ... ok
test source_files::transaction_tests::malformed_v2_write_marker_refuses_recovery_without_changing_source_bytes ... ok
test source_files::transaction_tests::partial_save_failures_restore_every_original_and_write_entry_last ... ok
test source_files::transaction_tests::recovery_before_any_write_accepts_v2_marker_and_keeps_v1_rollback_compatibility ... ok
test source_files::transaction_tests::recovery_rechecks_external_changes_between_restorations ... ok
test source_files::transaction_tests::recovery_rejects_untrusted_escape_paths_before_touching_files ... ok
test source_files::transaction_tests::rollback_refuses_external_edits_even_in_an_unchanged_dependency ... ok
test source_files::transaction_tests::rollback_removes_only_our_new_file_and_retains_detached_files ... ok
test source_files::transaction_tests::unwritten_journal_never_rolls_back_a_completed_writer_with_identical_after_bytes ... ok
test topology_context::analysis::tests::edge_work_budget_stops_repeated_expansion_not_just_output_storage ... ok
test topology_context::analysis::tests::exact_edge_budget_includes_reference_boundaries_and_node_abort_has_no_bypass ... ok
test topology_context::analysis::tests::unresolved_authored_edges_consume_work_budget_without_stored_output ... ok
test validation::coverage::tests::malformed_self_reuse_is_bounded_even_without_structural_gate ... ok
test view_options::tests::global_behavior_coverage_and_chosen_context_are_independent_intersecting_predicates ... ok
test view_options::tests::hidden_identity_survives_label_and_category_changes_without_mutating_the_model ... ok
test view_options::tests::no_lines_and_explicit_trace_selection_include_actual_trace_identities ... ok
test view_options::tests::omission_reasons_distinguish_missing_placements_folded_edges_and_explicit_hides ... ok
test view_options::tests::persisted_empty_selectors_and_lifecycle_never_widen_to_all ... ok
test view_options::tests::reusable_sequences_and_nested_scenarios_use_listed_contributions_in_both_layers ... ok
test view_options::tests::separate_category_families_obey_all_any_empty_and_union_truth_table ... ok
test view_options::tests::traceability_defaults_preserve_both_layers_and_explicit_selectors_still_apply ... ok
test view_options::tests::wrong_family_layer_and_unknown_references_reject_and_draft_filters_fail_closed ... ok
test result: ok. 54 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 44.50s
Running tests\communication_boundary_scenarios.rs (.local\target-gnullvm\debug\deps\communication_boundary_scenarios-9e00f9e11def63f8.exe)
running 3 tests
test mapped_unoriented_boundary_resolves_reverse_call_and_reply_from_actual_binding ... ok
test reverse_boundary_scenario_transition_keeps_call_orientation_and_reply_identity ... ok
test unoriented_flow_boundary_honors_ordinary_direction_but_preserves_correlated_reply_exception ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.37s
Running tests\communication_means.rs (.local\target-gnullvm\debug\deps\communication_means-671949388cdc4026.exe)
running 9 tests
test communication_allocation_checks_whole_partial_pair_and_does_not_guess_roles ... ok
test communication_allocation_items_use_specialization_and_empty_is_not_wildcard ... ok
test communication_means_are_distinct_oa_participant_relations_and_strict_source6_records ... ok
test communication_reverse_transition_projects_owners_without_oa_ports ... ok
test communication_scenario_ambiguous_and_incomplete_bindings_never_guess ... ok
test communication_scenario_reverse_call_and_reply_follow_actual_direction ... ok
test communication_schema5_upgrade_preserves_legacy_data_and_exact_source_trivia ... ok
test communication_semantic_endpoint_take_needs_scoped_decision_and_exact_history ... ok
test communication_transition_requires_explicit_ports_and_preserves_participant_mapping ... ok
test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.01s
Running tests\coverage_diagnostics.rs (.local\target-gnullvm\debug\deps\coverage_diagnostics-b265a0dc28672d93.exe)
running 6 tests
test grouping_and_scenario_only_capabilities_do_not_duplicate_support_warnings ... ok
test included_process_and_nested_scenario_evidence_is_identity_based_in_both_layers ... ok
test incomplete_oa_repairs_exact_records_and_ordered_membership_without_inference ... ok
test multifile_lint_preserves_core_codes_ids_and_actual_owning_source_paths ... ok
test non_leaf_exchange_locations_use_work_endpoints_including_typed_sa_ports ... ok
test structural_errors_suppress_completeness_cascades_and_rejection_keeps_the_model ... ok
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.56s
Running tests\language.rs (.local\target-gnullvm\debug\deps\language-ae9c78e7ce7d98ed.exe)
running 16 tests
test all_typed_fields_round_trip_with_stable_aliases_and_occurrences ... ok
test authoring_defaults_and_forward_references_remain_strict ... ok
test branching_reused_processes_and_chains_have_lossless_readable_source ... ok
test complete_normative_examples_are_accepted_by_the_real_parser ... ok
test coordinate_bits_and_permitted_strings_survive_text_and_storage ... ok
test deeply_nested_invalid_draft_returns_a_diagnostic_without_exhausting_the_stack ... ok
test global_identity_and_alias_collisions_include_diagram_nodes_and_project ... ok
test malformed_json_never_ignores_duplicate_maps_or_nested_unknown_fields ... ok
test original_v2_text_and_json_preserve_identity_and_mixed_scenarios_after_extensions ... ok
test text_and_model_transactions_preserve_history_with_stable_aliases ... ok
test tolerant_analysis_covers_unicode_and_returns_declarations_before_failure ... ok
test typed_events_vertices_and_transition_kinds_round_trip_in_both_layers ... ok
test typed_scenario_messages_values_and_reuse_round_trip_in_both_work_perspectives ... ok
test typed_unknown_fields_enums_duplicates_and_reference_spelling_are_rejected ... ok
test v1_repeated_exchange_occurrences_and_authored_aliases_survive ... ok
test v1_text_and_json_migrate_deterministically_without_losing_legacy_semantics ... ok
test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.96s
Running tests\port_anchors.rs (.local\target-gnullvm\debug\deps\port_anchors-d5a981eee97b6682.exe)
running 13 tests
test every_side_uses_exact_final_border_fraction_and_outward_routing_normal ... ok
test invalid_anchors_and_payloads_fail_atomically_including_duplicate_owner_placements ... ok
test malformed_source_anchor_records_have_located_errors ... ok
test many_neutral_ports_balance_capacity_without_a_giant_bottom_footer ... ok
test narrow_peer_gap_uses_clear_side_instead_of_a_blocked_facing_stub ... ok
test nested_owner_bounds_group_movement_and_authored_routes_share_the_same_geometry ... ok
test neutral_connected_ports_face_peers_and_unconnected_ports_use_four_sides ... ok
test port_upsert_reset_and_undo_preserve_unrelated_node_fields_and_list_order ... ok
test reidentification_deletion_reuse_and_owner_repair_preserve_correct_identity ... ok
test resetting_last_source_anchors_preserves_comments_and_can_add_a_new_manual_record ... ok
test separate_views_resize_layout_and_hidden_owners_keep_manual_metadata ... ok
test source_json_roundtrip_defaults_and_admission_include_anchor_records ... ok
test source_updater_keeps_comment_attachment_through_identity_swap_and_anchor_reordering ... ok
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.26s
Running tests\port_migration.rs (.local\target-gnullvm\debug\deps\port_migration-57b7ebd0823fc2a7.exe)
running 8 tests
test frozen_original_v2_reader_preserves_every_original_record ... ok
test generated_alias_collision_is_deterministically_suffixed ... ok
test generated_endpoint_collision_in_any_object_category_is_located_and_rejected ... ok
test legacy_oa_inout_ports_attachments_and_traces_remain_unclassified ... ok
test loading_v2_does_not_rewrite_original_bytes ... ok
test migration_admission_counts_generated_objects_records_and_references ... ok
test missing_v2_endpoints_are_deterministic_reported_and_independently_typed ... ok
test old_contract_is_validated_before_new_shapes_and_v1_flows_through_v2 ... ok
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.11s
Running tests\port_source.rs (.local\target-gnullvm\debug\deps\port_source-f086cdb039d4e546.exe)
running 3 tests
test source4_covers_typed_contracts_roles_allocations_and_nested_legacy_references ... ok
test source4_rejects_mixed_component_kinds_and_nested_reference_typos ... ok
test source4_requires_explicit_port_contract_and_fe_endpoints_without_generation ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.36s
Running tests\prepared_commands.rs (.local\target-gnullvm\debug\deps\prepared_commands-886b16f33cc6f1e4.exe)
running 7 tests
test all_edit_commands_record_their_implicit_identity_change ... ok
test deletion_and_cascade_discard_origins_before_uuid_reuse ... ok
test embedded_diagram_replacement_cannot_revive_deleted_node_origin ... ok
test explicit_chains_and_nested_swaps_compose_original_identity ... ok
test failed_preparation_leaves_input_unchanged_after_intermediate_identity_work ... ok
test fresh_creation_has_no_origin_even_when_subsequently_reidentified ... ok
test replacement_resets_correspondence_against_the_original_input ... ok
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.78s
Running tests\process_diagnostics.rs (.local\target-gnullvm\debug\deps\process_diagnostics-61c82df507b624ee.exe)
running 1 test
test sequence_gaps_name_occurrences_exchanges_and_endpoints ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.17s
Running tests\r3_constructor_ack.rs (.local\target-gnullvm\debug\deps\r3_constructor_ack-0a72505cb81ae402.exe)
running 8 tests
test equal_constructor_candidate_requires_independent_selection_of_changed_descendants ... ok
test first_constructor_acknowledgement_agrees_only_on_its_canonical_discriminator_slot ... ok
test first_equal_constructor_acknowledges_only_discriminator_in_every_family_and_direction ... ok
test historical_switches_retain_groups_and_completed_requests_still_reject_in_both_directions ... ok
test independent_constructor_and_leaf_selections_complete_missing_or_empty_baselines ... ok
test migrated_equal_constructor_can_complete_semantic_review_without_model_changes ... ok
test one_sided_or_disappeared_message_constructor_is_not_an_equal_scalar_acknowledgement ... ok
test reset_equal_constructor_does_not_refresh_previously_reviewed_descendants ... ok
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 14.06s
Running tests\r3_migration.rs (.local\target-gnullvm\debug\deps\r3_migration-8b4f10639d05f128.exe)
running 5 tests
test authored_v4_modules_upgrade_only_the_version_and_preserve_nested_comments ... ok
test frozen_v4_json_and_source_preserve_the_old_review_without_fabricating_semantics ... ok
test frozen_v4_trace_envelope_keeps_duplicate_and_unknown_field_rejection ... ok
test older_headers_cannot_admit_new_semantic_baselines ... ok
test original_v1_v2_v3_inputs_complete_the_explicit_upgrade_to_five ... ok
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.30s
Running tests\r3_semantic.rs (.local\target-gnullvm\debug\deps\r3_semantic-e75f0d913fd711fc.exe)
running 35 tests
test artifact_creation_requires_reviewed_metadata_and_deletion_retires_exact_facts ... ok
test artifact_metadata_is_attached_and_cannot_last_write_through_two_owner_traces ... ok
test artifact_owner_candidate_moves_link_and_conflicts_with_kept_attachment ... ok
test atomic_annotation_full_path_updates_only_selected_row ... ok
test atomic_binding_updates_local_and_rejects_pair_collision_and_remapping_without_reset ... ok
test changed_state_kind_remains_reviewable_in_both_directions ... ok
test child_membership_and_parent_resolutions_agree_by_actual_child_slot ... ok
test combined_ordered_membership_commutes_or_requires_agreed_anchors ... ok
test constructor_closure_does_not_restore_previously_corresponding_removed_members ... ok
test constructor_closure_pairs_signal_members_and_requires_history_reset_in_both_directions ... ok
test constructor_closure_preserves_target_only_literals_in_both_directions ... ok
test constructor_retirement_cannot_override_other_sources_kept_bound_in_either_order ... ok
test constructor_union_conflicts_with_another_sources_new_member_in_either_order ... ok
test constructors_expand_into_independent_facts_without_outer_prose ... ok
test enum_members_preserve_target_only_and_no_whole_list_overwrite ... ok
test explicit_trace_selection_keeps_independent_trace_baselines ... ok
test historical_reference_remap_preserves_text_and_deleted_reference_observations ... ok
test independent_bounds_keep_take_and_stale_prepare ... ok
test keeping_keyed_rows_with_an_unrelated_header_candidate_preserves_exact_authored_order ... ok
test ordered_member_requires_anchor_or_explicit_order_and_preserves_target_only ... ok
test prepared_inherited_annotation_cleanup_must_be_explicitly_accepted ... ok
test repeated_keep_of_unequal_constructor_pair_cannot_swallow_bound_drift ... ok
test retired_source_branch_retains_historical_member_pair_in_both_directions ... ok
test reverse_existing_port_review_rejects_typed_oa_proposals_without_mutation ... ok
test reverse_existing_port_review_retains_legacy_and_roundtrips_typed_history ... ok
test reverse_new_port_counterpart_remains_an_explicit_sa_only_omission ... ok
test same_target_constructor_preserves_local_members_and_reset_precedes_expansion ... ok
test same_target_member_keys_cannot_last_write_win ... ok
test semantic_batch_is_one_undo_and_replanning_acknowledged_values_is_noop ... ok
test semantic_rollup_does_not_claim_unchanged_when_only_unit_is_reviewed ... ok
test shared_definition_drift_is_linked_without_copying_definition_into_field_baseline ... ok
test source_and_target_semantic_headers_can_be_reviewed_in_reverse ... ok
test state_guard_and_deleted_trigger_membership_preserve_target_only_trigger ... ok
test target_only_artifact_move_records_owner_and_metadata_in_either_order ... ok
test wrong_family_both_na_and_duplicate_resolutions_rejected_atomically ... ok
test result: ok. 35 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 8.08s
Running tests\r3_source.rs (.local\target-gnullvm\debug\deps\r3_source-bb0c42d15bbf39bc.exe)
running 7 tests
test facet_reordering_and_reidentification_keep_comments_with_typed_row_identity ... ok
test historical_reference_deletion_does_not_remove_the_review_or_create_a_live_alias ... ok
test historical_uuid_and_enum_tokens_are_contextual_and_text_remains_quoted ... ok
test included_historical_review_edits_save_and_reopen_without_rewriting_other_modules ... ok
test prepared_semantic_review_writes_back_and_preserves_the_accepted_target_difference ... ok
test semantic_values_remain_closed_typed_records_in_both_formats ... ok
test typed_historical_facets_roundtrip_deleted_references_and_all_leaf_categories ... ok
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.22s
Running tests\r6_data.rs (.local\target-gnullvm\debug\deps\r6_data-abc398e60ae89711.exe)
running 16 tests
test a_self_association_is_visible_with_neutral_connector_and_real_role_contracts ... ok
test ambiguous_legacy_annotations_warn_and_reference_fields_stop_payload_descent ... ok
test an_empty_enumeration_is_a_located_incomplete_draft ... ok
test empty_record_collections_are_supported_but_record_literals_and_reference_defaults_are_not ... ok
test enum_literal_edits_validate_type_and_field_defaults_in_one_candidate ... ok
test exponential_payload_expansion_is_reported_and_recursive_finite_paths_remain_valid ... ok
test identified_allocations_keep_protocols_order_artifacts_and_inherited_identity ... ok
test inheritance_chain_validation_scaling_probe ... ignored, explicit inheritance scaling probe; run with --ignored --nocapture
test inherited_interfaces_and_item_specializations_satisfy_typed_port_contracts ... ok
test initial_transition_copies_qualified_paths_inheritance_allocations_and_associations ... ok
test recursive_value_types_warn_while_optional_reference_cycles_and_associations_are_distinct ... ok
test removing_inheritance_prunes_legacy_annotations_only_when_every_reachable_path_disappears ... ok
test repeated_record_paths_enforce_call_reply_phase_and_survive_identity_changes ... ok
test required_dictionary_closure_does_not_expand_through_incident_associations ... ok
test scalar_bounds_defaults_unicode_units_and_failed_batches_are_exact ... ok
test specialization_preserves_fields_rejects_cycles_and_prunes_removed_inherited_paths ... ok
test result: ok. 15 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 5.14s
Running tests\r6_migration.rs (.local\target-gnullvm\debug\deps\r6_migration-c8aa91bbc2f4cb02.exe)
running 7 tests
test allocation_alias_collisions_are_stable_and_duplicate_legacy_payload_fields_reject ... ok
test deterministic_allocation_id_collision_is_located_without_overwriting_any_object ... ok
test genuine_v3_preserves_typed_ports_and_allocates_deterministic_relationships ... ok
test recursive_legacy_record_paths_remain_ambiguous_instead_of_becoming_one_argument ... ok
test unique_legacy_nested_value_is_qualified_and_physical_nature_is_not_guessed ... ok
test v1_and_frozen_v2_inputs_reach_four_through_the_shared_data_upgrade ... ok
test v3_changed_payloads_reject_schema4_fields_and_new_constructor_names ... ok
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.32s
Running tests\r6_source.rs (.local\target-gnullvm\debug\deps\r6_source-fc413074bb8b6a9c.exe)
running 5 tests
test authored_v3_bundle_upgrade_preserves_includes_nested_ownership_comments_and_identity ... ok
test inferring_a_legacy_path_keeps_rationale_inside_its_argument ... ok
test omitted_ids_are_stabilized_before_allocation_identity_generation ... ok
test qualified_value_reordering_and_path_reidentification_keep_each_arguments_comments ... ok
test schema4_typed_values_supertype_paths_and_protocols_roundtrip ... ok
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.77s
Running tests\release1_teaching.rs (.local\target-gnullvm\debug\deps\release1_teaching-817593550c6aba50.exe)
running 4 tests
test release1_teaching_preserves_explicit_transport_direction_reuse_and_view_identity ... ok
test release1_teaching_regeneration_and_shipped_source_are_exact_with_one_intentional_warning ... ok
test release1_teaching_rejects_guessed_ports_and_wrong_performer_without_changing_source ... ok
test release1_teaching_review_changes_only_the_selected_counterpart_and_preserves_modules ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 10.40s
Running tests\release_capabilities.rs (.local\target-gnullvm\debug\deps\release_capabilities-2cfe40068aacbf30.exe)
running 7 tests
test capability_and_mission_links_enforce_direction_family_and_layer ... ok
test capability_semantics_remain_edges_independent_of_visual_containment ... ok
test conditional_extension_remains_editable_and_condition_is_validated ... ok
test inclusion_and_specialization_reject_transitive_cycles_atomically ... ok
test mission_map_transition_preserves_all_relationship_endpoints_and_conditions_both_ways ... ok
test mission_reidentification_and_deletion_preserve_reference_integrity_and_undo ... ok
test operational_missions_have_typed_bidirectional_counterparts_and_legacy_choices ... ok
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.56s
Running tests\release_diagrams.rs (.local\target-gnullvm\debug\deps\release_diagrams-410080fa9b665574.exe)
running 4 tests
test architecture_is_nested_exchange_context_and_ports_attach_without_placements ... ok
test port_identity_collapse_and_group_movement_do_not_invent_semantic_edges ... ok
test unplaced_work_parent_cannot_detach_a_leaf_from_its_visible_performer ... ok
test view_filtering_keeps_placements_and_source_and_separates_capability_content ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.24s
Running tests\release_language_limits.rs (.local\target-gnullvm\debug\deps\release_language_limits-aa543b58fa1e4ac8.exe)
running 4 tests
test declaration_limits_precede_reference_resolution_and_structural_validation ... ok
test json_record_and_step_limits_precede_model_errors_and_preserve_the_candidate ... ok
test legacy_budgets_include_generated_occurrences_and_placements_before_migration ... ok
test lint_reports_located_engineering_warnings_without_rejecting_valid_drafts ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.44s
Running tests\release_ports.rs (.local\target-gnullvm\debug\deps\release_ports-5189ef11700a47ae.exe)
running 13 tests
test ambiguous_reuse_creates_a_fresh_port_and_collisions_never_overwrite ... ok
test component_generation_requires_real_allocations_and_reuses_existing_facts ... ok
test deferred_deletion_preserves_preview_explicit_deletion_and_reidentification ... ok
test deletion_preserves_independent_ports_but_removes_required_dependents ... ok
test directed_legacy_resolution_retains_unclassified_interface_and_role_identity ... ok
test functional_creation_reuse_and_item_sync_are_atomic_and_identity_safe ... ok
test generated_ports_respect_authored_exchange_aliases ... ok
test invalid_replacement_rolls_back_without_repairing_explicit_replacement_projects ... ok
test legacy_split_preserves_original_identity_prose_interface_artifact_constraint_and_trace ... ok
test projection_anchors_are_contract_aware_and_unoriented_connections_keep_their_identity ... ok
test replacement_port_allocation_retains_exchange_mapping_and_evidence_in_either_order ... ok
test standard_interface_roles_do_not_follow_message_direction_and_kind_mixing_is_rejected ... ok
test transitions_create_sa_ports_and_omit_sa_implementation_from_portless_oa ... ok
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.78s
Running tests\release_routing.rs (.local\target-gnullvm\debug\deps\release_routing-bea7071d5be1912a.exe)
running 13 tests
test component_ports_use_actual_owners_in_movement_and_folded_lookup ... ok
test finite_boundary_values_and_temporarily_hidden_edges_remain_editable ... ok
test group_movement_translates_internal_routes_once_and_keeps_external_pins ... ok
test group_translation_beyond_coordinate_limit_rolls_back_nodes_and_routes ... ok
test hiding_or_relocating_a_node_does_not_erase_route_metadata ... ok
test invalid_routes_reject_atomically_with_a_located_diagnostic ... ok
test layout_preserves_authored_route_count_order_labels_and_undo ... ok
test old_models_get_empty_routes_and_route_json_is_strict ... ok
test reidentify_and_delete_preserve_or_clean_routes_with_the_semantic_edge ... ok
test route_edits_are_one_history_step_and_identical_edits_preserve_redo ... ok
test route_upsert_preserves_other_entries_and_accepts_an_explicit_empty_default ... ok
test single_endpoint_raw_edits_and_differing_group_deltas_keep_world_pins ... ok
test trace_routes_follow_trace_identity_and_cleanup_without_extra_objects ... ok
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.47s
Running tests\release_scenarios.rs (.local\target-gnullvm\debug\deps\release_scenarios-a97ddc158e8fd821.exe)
running 14 tests
test calls_and_replies_have_real_direction_correlation_and_order ... ok
test conditional_and_parallel_replies_cannot_answer_one_call_twice_but_alternatives_can ... ok
test conditional_lifetime_changes_conflict_with_later_or_parallel_use_not_exclusive_use ... ok
test create_delete_and_local_timer_messages_enforce_lifetime_rules ... ok
test deleting_reused_scenarios_or_bound_lifelines_preserves_callers_and_undo ... ok
test effective_message_endpoints_are_shared_for_forward_and_reverse_reply_choices ... ok
test loop_fragment_repetition_is_distinct_from_recursive_scenario_use ... ok
test optional_cleanup_does_not_claim_a_repeated_lifetime_is_balanced ... ok
test repeated_lifecycle_requires_per_iteration_balance_without_prohibiting_balanced_loops ... ok
test replies_repeated_without_their_call_warn_in_each_extra_loop_scope ... ok
test reuse_rejects_wrong_bindings_recursive_calls_and_wrong_viewpoints ... ok
test reused_scenarios_bind_existing_roles_and_transition_the_reference_closure ... ok
test role_lifelines_require_explicit_work_assignment_not_just_a_shared_realizing_entity ... ok
test value_annotations_are_bound_to_carried_fields_and_all_references_follow_identity_changes ... ok
test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.28s
Running tests\release_states.rs (.local\target-gnullvm\debug\deps\release_states-0d0025b63e4b31b9.exe)
running 11 tests
test boundary_points_enforce_inside_outside_local_routing_and_one_route_per_region ... ok
test choices_and_junctions_report_unfinished_guards_but_reject_conflicting_defaults_or_triggers ... ok
test event_reference_identity_cleanup_and_undo_preserve_triggering_intent ... ok
test every_vertex_is_an_editable_draft_but_only_stable_states_own_behavior_or_regions ... ok
test fork_join_detect_concurrency_at_the_common_composite_not_deep_immediate_regions ... ok
test histories_remain_per_region_with_shallow_direct_and_deep_nested_fallbacks ... ok
test initial_final_and_terminate_reject_forbidden_routes_and_cardinality_atomically ... ok
test machine_subtrees_and_selected_edges_transition_events_work_and_payloads_in_both_directions ... ok
test reachability_follows_nested_default_entry_and_reports_disconnected_vertices ... ok
test transition_kinds_distinguish_internal_external_self_and_local_composite_routing ... ok
test typed_events_trigger_alternatives_and_effects_validate_without_owner_restrictions ... ok
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.45s
Running tests\release_topology.rs (.local\target-gnullvm\debug\deps\release_topology-5e64e3a9873d768b.exe)
running 6 tests
test branching_reusable_processes_transition_as_contextual_topology_in_both_directions ... ok
test contextual_links_match_work_exchange_endpoints_and_reject_foreign_owners ... ok
test legacy_linear_exchange_only_sequences_keep_their_existing_meaning ... ok
test loops_are_allowed_while_missing_guards_and_disconnected_paths_are_diagnosed ... ok
test reuse_rejects_recursive_or_cross_layer_targets_and_deleted_targets_become_drafts ... ok
test topology_identity_edits_and_deletions_preserve_remaining_paths_and_undo ... ok
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.55s
Running tests\review_regressions.rs (.local\target-gnullvm\debug\deps\review_regressions-66d7a72d208de855.exe)
running 15 tests
test an_explicit_merged_destination_stays_reviewed_on_repeated_preview ... ok
test capability_mission_transition_remains_an_explicit_choice_in_both_directions ... ok
test checked_save_rejects_external_changes_and_preserves_their_exact_bytes ... ok
test checked_save_rejects_external_deletion_without_recreating_the_file ... ok
test checked_save_returns_exact_bytes_and_accepts_unchanged_external_content ... ok
test destination_only_changes_remain_available_for_reverse_propagation ... ok
test divergent_changes_on_both_sides_still_require_review ... ok
test factory_and_add_commands_share_fragment_branch_defaults ... ok
test invalid_placement_relocations_preserve_model_artifacts_and_redo ... ok
test keeping_divergent_values_is_idempotent_in_both_directions ... ok
test later_source_changes_propagate_without_overwriting_other_reviewed_fields ... ok
test relocating_a_placement_preserves_identity_artifacts_and_history ... ok
test same_parent_reparent_preserves_fragment_branch_order_and_history ... ok
test same_parent_reparent_preserves_sequence_order_revision_and_redo ... ok
test unowned_state_machine_is_valid_incomplete_work_in_both_layers ... ok
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.39s
Running tests\route_source.rs (.local\target-gnullvm\debug\deps\route_source-04d120b08d6d38c4.exe)
running 5 tests
test invalid_route_source_has_located_errors_and_no_silent_nested_defaults ... ok
test omitted_schema_three_routes_default_to_empty_and_v2_reader_stays_frozen ... ok
test route_commands_json_and_one_step_undo_recover_exact_model_and_canonical_source ... ok
test route_records_share_model_admission_for_source_json_and_bundles ... ok
test route_source_json_and_bundle_roundtrips_preserve_order_defaults_and_edge_aliases ... ok
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.73s
Running tests\routing_geometry.rs (.local\target-gnullvm\debug\deps\routing_geometry-640bafaf2e3d1fb1.exe)
running 18 tests
test authored_pins_keep_traversal_order_even_when_reversing_and_repeated ... ok
test automatic_label_fraction_survives_its_first_authored_drag_without_a_jump ... ok
test blocked_pin_is_retained_and_warned_without_nan_or_diagonal_fallback ... ok
test bottom_standard_ports_are_approached_from_below ... ok
test collapse_suspends_only_promoted_endpoints_and_never_changes_stored_route ... ok
test compressed_grid_search_finds_multi_turn_exit_from_a_narrow_corridor ... ok
test deterministic_under_input_and_route_list_permutations ... ok
test excessive_search_grid_falls_back_with_an_explicit_warning_and_preserved_endpoints ... ok
test exhausted_search_budget_survives_label_and_pin_previews ... ok
test functional_endpoints_preserve_real_ports_and_normals_while_detouring ... ok
test interpolation_projection_empty_and_repeated_points_are_well_defined ... ok
test label_geometry_and_bounds_are_shared_exact_and_unicode_safe ... ok
test nested_endpoint_enclosure_is_traversable_but_its_header_and_siblings_are_not ... ok
test nonport_relations_try_clear_alternate_sides_and_label_only_supported_roles ... ok
test routing_100_nodes_150_edges_has_bounded_work_and_reports_actual_time ... ok
test single_edge_preview_matches_settled_geometry_and_preserves_other_routes ... ok
test single_pin_above_an_oa_interaction_makes_a_detour_without_a_retraced_spur ... ok
test workshop_automatic_labels_are_readable_without_mutating_authored_routes ... ok
test result: ok. 18 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 32.40s
Running tests\routing_labels.rs (.local\target-gnullvm\debug\deps\routing_labels-9815c14b9074e8c6.exe)
running 2 tests
test authored_overlap_is_exact_and_reset_only_repositions_automatic_text ... ok
test demo_architecture_labels_do_not_cover_earlier_or_later_connection_strokes ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s
Running tests\semantic_artifact_absence_oracle.rs (.local\target-gnullvm\debug\deps\semantic_artifact_absence_oracle-1a3d73f91af62a41.exe)
running 2 tests
test moved_away_source_artifact_counts_as_absent_from_reviewed_owner ... ok
test target_only_artifact_take_preserves_without_fabricated_source_identity ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.07s
Running tests\semantic_attachments_gui_oracle.rs (.local\target-gnullvm\debug\deps\semantic_attachments_gui_oracle-aa43e037c3033729.exe)
running 4 tests
test attachment_candidate_and_direct_record_keep_conflict_by_actual_slot_in_either_order ... ok
test attachment_candidate_changes_existing_parent_or_endpoint_without_attached_record_trace ... ok
test convergent_owner_attachment_candidates_agree_and_keep_cannot_override_them ... ok
test incident_absence_take_refuses_but_explicit_candidate_endpoint_is_reviewable ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.53s
Running tests\source6_view_contract.rs (.local\target-gnullvm\debug\deps\source6_view_contract-f91bdc53472d7a21.exe)
running 8 tests
test source6_category_and_saved_selection_reidentify_delete_preserve_empty_filters ... ok
test source6_category_transition_requires_mapped_members_and_reviews_exact_set ... ok
test source6_edge_availability_uses_actual_shared_projection_fold_and_placement_rules ... ok
test source6_new_historical_facts_are_rejected_under_source5_even_without_live_categories ... ok
test source6_projection_filters_keep_placements_and_label_modes_are_presentation_only ... ok
test source6_traceability_default_keeps_both_layers_and_indexed_projection_matches ... ok
test source6_view_defaults_cannot_be_smuggled_under_old_json_headers ... ok
test source6_views_round_trip_strict_fields_and_reference_aliases ... ok
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.48s
Running tests\source7_contract.rs (.local\target-gnullvm\debug\deps\source7_contract-29c604533629d07b.exe)
running 16 tests
test source7_allocation_removal_requires_independent_channel_repair_and_keeps_values ... ok
test source7_assembly_purposes_do_not_invent_precedence_or_global_coverage ... ok
test source7_context_lifecycle_source_history_and_closed_admission ... ok
test source7_context_resource_limits_are_per_request_and_count_authored_paths ... ok
test source7_operation_allocation_delete_repairs_both_call_and_separate_reply_channels ... ok
test source7_operation_inherited_exact_allocation_is_not_a_same_item_substitute ... ok
test source7_operation_reverse_unoriented_call_and_reply_use_actual_binding ... ok
test source7_operation_transmission_matrix_rejects_mismatch_and_warns_unspecified ... ok
test source7_ordinary_old_calls_keep_bytes_and_explicit_null_is_not_old_admission ... ok
test source7_parameterless_operations_have_exact_protocol_identity_and_deletion_intent ... ok
test source7_repeated_nested_qualified_precedence_and_cache_are_distinct ... ok
test source7_reply_derives_call_signature_and_void_return_channel_still_carries_operation ... ok
test source7_selected_operation_requires_channel_lifelines_and_proven_direction ... ok
test source7_semantic_facets_retain_typed_context_and_operation_references ... ok
test source7_source_bundle_migration_is_token_only_and_new_link_stays_with_caller ... ok
test source7_transition_preserves_qualified_paths_and_requires_reviewed_operation_omission ... ok
test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.44s
Running tests\source_files.rs (.local\target-gnullvm\debug\deps\source_files-c259adb8020b7e75.exe)
running 8 tests
test aggregate_budgets_and_portable_paths_are_checked_before_loading_excess_data ... ok
test discovery_never_refreshes_drafts_and_preserves_detached_buffers ... ok
test forged_compiled_model_or_index_cannot_be_saved ... ok
test invalid_and_missing_includes_keep_editable_text_and_located_diagnostics ... ok
test loading_keeps_original_no_uuid_bytes_and_saving_stabilizes_exactly_once ... ok
test new_destinations_require_explicit_missing_expectations_and_reject_collisions ... ok
test physical_hard_link_aliases_are_rejected ... ok
test unchanged_dependency_edits_and_deletions_block_save_before_any_write ... ok
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.42s
Running tests\source_identity_updates.rs (.local\target-gnullvm\debug\deps\source_identity_updates-ed289dca0ae67049.exe)
running 3 tests
test identity_and_alias_edit_keep_authored_file_and_reference_rationale ... ok
test identity_swap_and_reorder_keep_both_declarations_and_item_comments_with_origin ... ok
test provenance_cannot_merge_records_or_cross_record_classes ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.58s
Running tests\source_nested_updates.rs (.local\target-gnullvm\debug\deps\source_nested_updates-af2536c4b0fc948c.exe)
running 12 tests
test additions_nest_in_existing_and_new_owners_while_authored_flat_records_stay_flat ... ok
test compact_same_file_reparent_and_unnest_preserve_explicit_parent_comments ... ok
test crlf_moved_and_new_children_preserve_authored_and_destination_line_endings ... ok
test cross_file_move_carries_attached_comments_and_subtree_but_leaves_gap_notes ... ok
test deep_structural_writeback_runs_on_a_small_thread_stack ... ok
test deleted_owner_identity_reused_by_new_owner_does_not_keep_old_lexical_ownership ... ok
test deleting_owner_retains_annotations_and_extracts_independently_moved_descendant ... ok
test independent_descendant_move_can_reverse_old_containment_without_overlapping_edits ... ok
test moving_a_child_keeps_the_owners_opening_line_comment_with_its_owner ... ok
test nested_scalar_edits_touch_only_authored_tokens ... ok
test nested_typed_reference_list_updates_keep_item_rationale_while_port_moves ... ok
test nested_uuid_alias_swap_and_cross_file_move_follow_command_provenance ... ok
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 18.71s
Running tests\source_project.rs (.local\target-gnullvm\debug\deps\source_project-70a23d8ae64722e2.exe)
running 33 tests
test added_list_items_empty_lists_and_literal_changes_preserve_existing_annotations ... ok
test advisory_lint_locations_refer_to_raw_drafts_before_identity_stabilization ... ok
test alias_updates_touch_only_header_and_reference_tokens_even_with_comments_after_at ... ok
test canonical_export_groups_semantic_roots_ports_and_placements_and_is_deterministic ... ok
test complete_demo_preserves_behavior_artifacts_traces_and_every_placement ... ok
test constructor_tag_changes_retain_shared_nested_fields_and_removed_field_comments ... ok
test cross_file_typed_ports_global_forward_references_and_stable_ids ... ok
test duplicate_alias_and_identity_report_both_files_including_project_identity ... ok
test duplicate_include_edges_count_toward_admission_and_ordered_references_are_aggregate ... ok
test exported_case_colliding_root_aliases_are_portable_and_large_root_sets_are_bounded ... ok
test failed_update_preserves_candidate_and_rejects_stale_index ... ok
test generated_id_insertion_handles_adjacent_header_tokens_and_remains_exactly_indexed ... ok
test graphical_move_updates_only_its_owned_view_document ... ok
test include_inspection_returns_located_failure_without_partial_discovery_and_is_bounded ... ok
test include_inspection_reuses_strict_entry_fragment_syntax_and_real_spans ... ok
test includes_are_once_only_and_cycles_missing_and_unreachable_files_are_located ... ok
test invalid_cross_file_route_references_and_geometry_locate_the_authored_view ... ok
test json_bundle_rejects_duplicate_file_keys_and_unknown_fields ... ok
test kind_change_removes_field_syntax_but_keeps_its_comments_and_other_fields ... ok
test model_updates_rewrite_cross_file_alias_uses_preserve_ownership_and_untouched_comments ... ok
test moving_declarations_between_files_changes_no_semantics_or_ids ... ok
test nested_message_value_edits_preserve_field_comments_and_reordering_uses_field_identity ... ok
test new_children_inherit_owner_file_new_roots_add_include_and_deletion_keeps_files ... ok
test omitted_defaults_stay_omitted_and_new_fields_do_not_reformat_surviving_fields ... ok
test portable_paths_reject_escapes_devices_urls_and_case_collisions ... ok
test project_admission_is_aggregate_and_precedes_global_resolution ... ok
test reference_list_reordering_carries_item_comments_and_alias_spelling_with_identity ... ok
test removed_list_items_and_declarations_keep_comments_as_enclosing_annotations ... ok
test route_edits_keep_diagram_file_ownership_and_comments_with_edge_identity ... ok
test scalar_header_guard_and_project_edits_preserve_exact_crlf_trivia_and_escape_spelling ... ok
test scalar_record_constructor_changes_keep_comments_inside_removed_values ... ok
test single_string_and_legacy_apis_remain_explicit_and_filesystem_free ... ok
test source_errors_keep_exact_fragment_unicode_positions ... ok
test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.13s
Running tests\state_diagrams.rs (.local\target-gnullvm\debug\deps\state_diagrams-c385a34d3448c847.exe)
running 13 tests
test contexts_restrict_membership_without_changing_legacy_hidden_placements ... ok
test cross_machine_reparent_requires_atomic_placement_and_route_repair ... ok
test empty_and_partial_views_are_read_only_and_omit_unrelated_edges ... ok
test folding_retains_authored_routes_without_false_self_transitions ... ok
test grouped_moves_translate_hidden_descendants_and_pins_only_in_one_view ... ok
test initial_transition_attaches_to_the_compact_symbol_and_preview_keeps_settled_geometry ... ok
test layout_reserves_internal_rows_and_state_routes_retain_hard_pins ... ok
test moving_a_region_does_not_translate_pins_attached_to_a_stationary_state_boundary ... ok
test real_state_symbols_boundaries_internal_rows_and_self_loops_share_geometry ... ok
test reconnect_keeps_identity_and_validates_replacement_without_double_counting ... ok
test remapping_and_machine_deletion_include_dedicated_views_and_dependents ... ok
test source_updates_preserve_context_identity_and_unrelated_authored_bytes ... ok
test strict_context_wire_source_and_admission_contract ... ok
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.61s
Running tests\workflows.rs (.local\target-gnullvm\debug\deps\workflows-cf933e047345cb8a.exe)
running 28 tests
test artifacts_preserve_arbitrary_uri_and_revision_without_fetch ... ok
test automatic_transition_does_not_accept_arbitrary_target_kinds ... ok
test batch_is_one_undo_and_noop_does_not_change_revision ... ok
test bidirectional_transition_creates_reuses_and_updates_one_history_transaction ... ok
test both_side_transition_conflicts_require_explicit_field_resolution ... ok
test create_occurrence_attaches_once_and_repeats_exchange_by_distinct_ids ... ok
test deleting_source_cascades_owned_records_but_keeps_other_layer_counterpart ... ok
test demo_has_both_layers_complete_contracts_and_no_checks ... ok
test demo_is_valid_and_preserves_uuid_and_alias_through_json ... ok
test every_demo_identity_can_be_remapped_and_deleted_without_dangling_references ... ok
test explicit_dependencies_map_chain_order_and_repeated_occurrences ... ok
test failed_batch_preserves_model_history_revision_and_redo ... ok
test identity_aliases_and_map_keys_share_global_namespace ... ok
test invalid_geometry_and_new_payload_fields_are_rejected ... ok
test items_ports_interfaces_and_exchange_allocation_are_typed ... ok
test many_traces_need_explicit_counterpart_and_layout_does_not_cause_drift ... ok
test nested_projection_encloses_children_and_moves_only_selected_diagram ... ok
test nested_work_is_independent_of_leaf_allocation ... ok
test parent_and_endpoint_queries_match_creation_rules ... ok
test parent_cycles_cross_layer_ownership_and_multiple_performers_reject ... ok
test participant_transition_requires_boundary_decision_and_stale_plans_reject ... ok
test reidentify_updates_containment_sequences_traces_artifacts_and_views_atomically ... ok
test reidentifying_data_types_and_function_ports_updates_every_typed_reference ... ok
test relation_deletion_prunes_owned_occurrences_and_undo_restores_order ... ok
test rename_and_collision_insertion_preserve_existing_aliases ... ok
test scenario_lifelines_and_occurrences_require_same_context ... ok
test shared_roles_remain_valid_without_an_invented_unique_performer ... ok
test state_regions_initial_final_and_typed_actions_validate ... ok
test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 10.16s
Doc-tests oa_core
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
@@ -0,0 +1,270 @@
{
"scope": "Small exact private outline/query integration evidence; excludes executable binaries and duplicate full input copies",
"records": [
{
"path": "artifacts1-status.json",
"bytes": 299,
"sha256": "6c162b92780232b5b3bfd24159cfef52d3bb4fb786485572f091ec2383735053"
},
{
"path": "artifacts1-stderr.log",
"bytes": 61,
"sha256": "d8b07b9fdfbce4832604bee2b69736dbb7054a3433d972cb15ad8c8fdc7a65c6"
},
{
"path": "artifacts1-stdout.log",
"bytes": 35777,
"sha256": "5b4441c8f4862d0bad438bbc8b8dddd3d4628586283c0add445248b4a12d85be"
},
{
"path": "clippy-tests2-status.json",
"bytes": 299,
"sha256": "04910578164f5dce73f8348caccd0590ac9f24150e2b331c554b9c287f2dc191"
},
{
"path": "clippy-tests2.log",
"bytes": 151,
"sha256": "78c52948b2dd53aca55947ccd1039fec7e054f0d8e61de56b9bd54960e883f61"
},
{
"path": "clippy1-status.json",
"bytes": 291,
"sha256": "60818516ec45371a8f4766b4936e11d7b53552f1d1e423846d5c02b55a9acea6"
},
{
"path": "clippy1.log",
"bytes": 151,
"sha256": "5d3c946198a0870c7245b8ebd8eecef6bff21765f6d98a72221dd1dded3e233e"
},
{
"path": "compiler1-status.json",
"bytes": 191,
"sha256": "865fbfc81fa2e58b5b8d6a9d666c18dfb6515f129a026f9cc5df2db6a94b01d9"
},
{
"path": "compiler1-stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "compiler1-stdout.log",
"bytes": 197,
"sha256": "cdaaa400be47332d69e678836251d4635b5ff2ecd34aa962b69d71f8961d274b"
},
{
"path": "core1-status.json",
"bytes": 264,
"sha256": "fcd9fae539fa0f82ce0906576971e0b16aec709155363dc1f0a4a201b986edb9"
},
{
"path": "core1.log",
"bytes": 48639,
"sha256": "4556049fbfc4ccecc118cad85afb2b1f92af10bfd787ed416ec2aa4389b7bf24"
},
{
"path": "final-readback.json",
"bytes": 1775,
"sha256": "29a07e2be5b608d4950b6728398d8f64c0c5c7cb38a014c8dde821ee4b18a390"
},
{
"path": "fingerprints/oa-core-781c6973417b169c/lib-oa_core",
"bytes": 16,
"sha256": "32d7fadb58b89d0877ab923522a0bbb715ac42c34526de01cd3cec0be61df760"
},
{
"path": "fingerprints/oa-core-781c6973417b169c/lib-oa_core.json",
"bytes": 776,
"sha256": "7664e5d9695d989d99873c6937409b188ee00489f6a808051d8fbafdaf826baa"
},
{
"path": "fingerprints/serde_json-b48005beba7e4267/lib-serde_json",
"bytes": 16,
"sha256": "9202101a31af6f8d24edceacbb8300c10dddd94fb496cbf6451c8860133ce784"
},
{
"path": "fingerprints/serde_json-b48005beba7e4267/lib-serde_json.json",
"bytes": 826,
"sha256": "310bedb04f5f35eef3a04e8019f0a204cc0f30b94ca808cb4d702cd7c6403737"
},
{
"path": "inputs-supplement.json",
"bytes": 388,
"sha256": "480e04d38ec1fda35727cc0b6f2f2837964484c90cffc0199bfe5bcef4236745"
},
{
"path": "inputs.json",
"bytes": 61752,
"sha256": "e0dd3e617c1c365e1d315b498ce032f375b734341d2eb87d6dc89867b636196e"
},
{
"path": "language_outline_tests-pre-encoding-fix.rs",
"bytes": 14922,
"sha256": "f64bd89959554cd5842609c031d442f3d9e27b73a216dd936715284c9fe9fb97"
},
{
"path": "literal-byte-readback.json",
"bytes": 1291,
"sha256": "0030e88a1a74e2bbf25c1bb3b7dad6dc25ce0477762f8cb71a5034344573d577"
},
{
"path": "outline1-status.json",
"bytes": 312,
"sha256": "3efbfd96f6b5921fa2079b8732d3c32705528989051629b357fb389b4a20933c"
},
{
"path": "outline1.log",
"bytes": 1593,
"sha256": "2582a9e5894d4caee7d092e6b0aa15bd02f49261a6beebaaca91d94affae9230"
},
{
"path": "outline2-inputs.json",
"bytes": 399,
"sha256": "5eeddbcef8643a75b1582575089405f717bae429c9bf3bf7614a846c712d45ec"
},
{
"path": "outline2-status.json",
"bytes": 312,
"sha256": "434a9410460a7c4bf1dedf948a76015b0b0cc63ae19843b834fd02df44ed6d1c"
},
{
"path": "outline2.log",
"bytes": 1593,
"sha256": "0e045f4287675661fde873950bce2387584b377ee747b663fa41ec7ffacd1bc7"
},
{
"path": "query-artifacts3.json",
"bytes": 206,
"sha256": "25298a1f6b40fd0e60e4bcbda610c81dc851ec37e4d0d58c00099ca1b4128018"
},
{
"path": "query-binding1-failure.json",
"bytes": 905,
"sha256": "b41e3478707a7b3aeb91ee9fd62ca3c2ee45401aff615fd202ffed7fc13c43b1"
},
{
"path": "query-bindings.json",
"bytes": 6727,
"sha256": "158f1c1797abb634f74b2cbc8f09656871d999bfb6aaa9220feacb443bc48889"
},
{
"path": "query-compile1-status.json",
"bytes": 987,
"sha256": "a3f9acff4713d9491cbaf7d66180d36e19fa44f8617d6449f9d7f8b4c5a8a383"
},
{
"path": "query-compile1-stderr.log",
"bytes": 1857,
"sha256": "82b4baefdbb06c4b744cb750268c02dd0d540c0ae77dbd36359403b03dfbf5d0"
},
{
"path": "query-compile1-stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "query-compile2-status.json",
"bytes": 997,
"sha256": "a64df6b29650a5b9a4d990e1c6ef65a22c8b0068b0e2fa151f912116521b7884"
},
{
"path": "query-compile2-stderr.log",
"bytes": 2819,
"sha256": "b0206bb2a0be17e6e6c27934566d145425bcf99cb3cc22f7f15143a5733d44fc"
},
{
"path": "query-compile2-stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "query-compile3-status.json",
"bytes": 1009,
"sha256": "8bff40eed5dbf499ea41119cc2696fe998a7071ac5ce15fecf447d6a86eb127b"
},
{
"path": "query-compile3-stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "query-compile3-stdout.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "query-source-reconstruction.json",
"bytes": 673,
"sha256": "7692eaf4ed52e0de5f95d1ea26b0b3c3d91b8b89cda7a0c0198394a0403ea03e"
},
{
"path": "query-tests3-status.json",
"bytes": 332,
"sha256": "e2edbb9cdb986ba5215a53830393e2c11f5d8e428a81ebbaede0e06bb395db9d"
},
{
"path": "query-tests3-stderr.log",
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "query-tests3-stdout.log",
"bytes": 1785,
"sha256": "faec6eb5a3be074a755dfb0ce0bf7b34d2358ff543e0999ee51a27d7a8bcabc9"
},
{
"path": "query-type-correction.json",
"bytes": 414,
"sha256": "eb3675d734354dd8dcb2682b77276d4f2d08790fa98c20c045b0286959ecfcf7"
},
{
"path": "run-gates.ps1",
"bytes": 1231,
"sha256": "070c986b1ca9de6c01750597d68478201736093b70bba76812752cafb522e867"
},
{
"path": "run-query-resume.ps1",
"bytes": 5572,
"sha256": "07c707cfe4c143af8a64a5ba88de24c866d9a9929f23206f39e21df589c0977b"
},
{
"path": "run-query-typed.ps1",
"bytes": 3119,
"sha256": "92cde88b43382b6b7557bf341d7168f98e3838d3d2f3bd25e802780d400cb05c"
},
{
"path": "run-query-utf8.ps1",
"bytes": 3107,
"sha256": "ebb7b16ed431df7df6885a5aff6dbbe55db5b01cc899821e1a4af665ed2d3c18"
},
{
"path": "run-query.ps1",
"bytes": 4240,
"sha256": "c112d1a496ed9d39e202f7704548863af45e532dfe89c675bb84b2569201b1ec"
},
{
"path": "run-utf8-outline-gates.ps1",
"bytes": 1505,
"sha256": "742695aa1b1aadebfb475306fdcbfbb31af5a7f5dd4920e7c5c49df757d89962"
},
{
"path": "source_symbols-v2-utf8-typed.rs",
"bytes": 54554,
"sha256": "fe37cd55b95c892c05aec6c37a113154cab7646dcfc333646fa8218345919751"
},
{
"path": "source_symbols-v2-utf8.rs",
"bytes": 54542,
"sha256": "86666c8390f0c63ec75b045366494a80d0ecde82924f2bac312afd01675aee56"
},
{
"path": "source_symbols-v2.rs",
"bytes": 54637,
"sha256": "8f3f20a7e72c870cfd1ad46f0aa8b8998ffc1ebf3357911957ed4995758e7520"
},
{
"path": "utf8-reconstruction-correction.json",
"bytes": 776,
"sha256": "3140aab739ad4351f8538b8169b3fe972b975138cc95c6e12be82a0d5f76c7a3"
}
]
}
@@ -0,0 +1,51 @@
{
"status": "PASS",
"unchangedOriginalInputs": 321,
"expectedFixtureCorrection": [
{
"path": "crates/oa-core/src/language_outline_tests.rs",
"beforeSha256": "f64bd89959554cd5842609c031d442f3d9e27b73a216dd936715284c9fe9fb97",
"finalSha256": "4c79a01e8aea243dd9ef66ce71b9fae263d0e79c319a46c51223679897e8b9df"
}
],
"documentationSupplementUnchanged": true,
"languageSha256": "34cbb144a111e6f0ddadfca7d40636a8e3323fe65ea8920fd2402f0352b41f57",
"outputs": {
"outline2.log": {
"bytes": 1593,
"sha256": "0e045f4287675661fde873950bce2387584b377ee747b663fa41ec7ffacd1bc7"
},
"outline2-status.json": {
"bytes": 312,
"sha256": "434a9410460a7c4bf1dedf948a76015b0b0cc63ae19843b834fd02df44ed6d1c"
},
"clippy-tests2.log": {
"bytes": 151,
"sha256": "78c52948b2dd53aca55947ccd1039fec7e054f0d8e61de56b9bd54960e883f61"
},
"clippy-tests2-status.json": {
"bytes": 299,
"sha256": "04910578164f5dce73f8348caccd0590ac9f24150e2b331c554b9c287f2dc191"
},
"query-compile3-status.json": {
"bytes": 1009,
"sha256": "8bff40eed5dbf499ea41119cc2696fe998a7071ac5ce15fecf447d6a86eb127b"
},
"query-tests3-status.json": {
"bytes": 332,
"sha256": "e2edbb9cdb986ba5215a53830393e2c11f5d8e428a81ebbaede0e06bb395db9d"
},
"query-tests3-stdout.log": {
"bytes": 1785,
"sha256": "faec6eb5a3be074a755dfb0ce0bf7b34d2358ff543e0999ee51a27d7a8bcabc9"
},
"query-bindings.json": {
"bytes": 6727,
"sha256": "158f1c1797abb634f74b2cbc8f09656871d999bfb6aaa9220feacb443bc48889"
},
"literal-byte-readback.json": {
"bytes": 1291,
"sha256": "0030e88a1a74e2bbf25c1bb3b7dad6dc25ce0477762f8cb71a5034344573d577"
}
}
}
@@ -0,0 +1 @@
{"rustc":4368751908343638535,"features":"[]","declared_features":"[]","target":9792512432450288461,"profile":12077771321704829354,"path":10192304750368139731,"deps":[[4012234191921133045,"thiserror",false,6221096245441968322],[5330460842384404171,"serde_json",false,10762123116135201565],[6557439603276904804,"serde",false,8207651326488808113],[9723370144619655183,"tempfile",false,6264596951560906265],[11781824977070132858,"same_file",false,3903024514762273217],[14063412941180217548,"uuid",false,16344938119731331185],[14493392674156086091,"build_script_build",false,13821171186339835210]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\oa-core-781c6973417b169c\\dep-lib-oa_core","checksum":false}}],"rustflags":[],"config":1025291897514690248,"compile_kind":0}
@@ -0,0 +1 @@
{"rustc":4368751908343638535,"features":"[\"default\", \"std\"]","declared_features":"[\"alloc\", \"arbitrary_precision\", \"default\", \"float_roundtrip\", \"indexmap\", \"preserve_order\", \"raw_value\", \"std\", \"unbounded_depth\"]","target":9592559880233824070,"profile":8378823585564974145,"path":9516600172453656966,"deps":[[5330460842384404171,"build_script_build",false,10302394721460756435],[5532778797167691009,"itoa",false,14930288972773478100],[11029742160753049355,"serde_core",false,12627368256302415275],[12613788554453945248,"memchr",false,17882262603682400281],[16226529040278277557,"zmij",false,18174765404489670566]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\serde_json-b48005beba7e4267\\dep-lib-serde_json","checksum":false}}],"rustflags":[],"config":1025291897514690248,"compile_kind":0}
@@ -0,0 +1,8 @@
{
"scope": "Supplement discovered by include_str audit during full-core compilation, after focused outline gate. Not retroactively part of the original pre-gate manifest.",
"path": "docs/language.rst",
"bytes": 130753,
"sha256": "ac6b1d982c55f246de2f3c844b24b874599a3c20cfbd7ed22efe4561ac622b83",
"matchesBaseGitBlobExactly": true,
"matchesBaseAfterCRLFNormalization": true
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,386 @@
//! Prepared outline tests. Explicit compatibility tests additionally exercise
//! the existing parsers/analyze; the outline entry itself never calls them.
use super::*;
fn limits() -> OutlineLimits {
OutlineLimits {
max_source_bytes: 1024 * 1024,
max_tokens: 100_000,
max_declarations: 1_000,
}
}
fn declaration<'a>(result: &'a Outline<'_>, alias: &str) -> &'a OutlineDeclaration {
result
.declarations
.iter()
.find(|d| d.declaration.alias == alias)
.unwrap()
}
fn text(source: &str, span: Span) -> &str {
&source[span.start..span.end]
}
#[test]
fn outline_roles_preserve_unicode_crlf_and_exact_escaped_uuid_literal() {
let source = "// 検査 🚒\r\noa_actor responder \"救助\" id \"\\u00300000000-0000-0000-0000-000000000001\" {}\r\nsource @ // 使用\r\n responder;";
let before = source.as_bytes().to_vec();
let result = outline(source, limits()).unwrap();
assert_eq!(result.source.as_bytes(), before);
assert_eq!(result.source.as_ptr(), source.as_ptr());
let d = declaration(&result, "responder");
assert_eq!(text(source, d.kind_span), "oa_actor");
assert_eq!(text(source, d.alias_span), "responder");
assert_eq!(
text(source, d.id_literal_span.unwrap()),
"\"\\u00300000000-0000-0000-0000-000000000001\""
);
assert_eq!(d.declaration.id, Some(Id::from_u128(1)));
assert_eq!(d.declaration.span.start, source.find("oa_actor").unwrap());
assert_eq!(d.declaration.span.end, source.find("{}\r\n").unwrap() + 2);
let mut end = 0;
for token in &result.tokens {
assert_eq!(token.span.start, end);
assert!(token.span.start < token.span.end);
assert!(source.is_char_boundary(token.span.start));
assert!(source.is_char_boundary(token.span.end));
end = token.span.end;
}
assert_eq!(end, source.len());
assert!(!result.has_lexical_errors);
assert!(!result.has_unmatched_braces);
}
#[test]
fn closed_id_at_eof_is_inside_the_declaration_extent() {
for source in [
"oa_actor a \"Actor\" id \"00000000-0000-0000-0000-000000000001\"",
"node placed id \"00000000-0000-0000-0000-000000000001\"",
] {
let result = outline(source, limits()).unwrap();
let d = &result.declarations[0];
let literal = d.id_literal_span.unwrap();
assert_eq!(d.declaration.id, Some(Id::from_u128(1)));
assert_eq!(d.declaration.span.end, source.len());
assert!(d.declaration.span.start <= literal.start);
assert!(literal.end <= d.declaration.span.end);
}
for source in ["oa_actor a \"Actor\"", "oa_actor a \"Actor\" id"] {
let result = outline(source, limits()).unwrap();
let d = &result.declarations[0];
assert_eq!(d.declaration.span.end, source.len());
assert_eq!(d.declaration.id, None);
assert_eq!(d.id_literal_span, None);
}
}
#[test]
fn missing_bad_and_historical_ids_never_allocate_authored_identity() {
let source = "oa_actor missing \"No ID\" {}\noa_actor bad \"Bad ID\" id \"not-a-uuid\" {}\noa_actor historical \"00000000-0000-0000-0000-000000000001\" { history uuid \"00000000-0000-0000-0000-000000000001\"; }";
let first = outline(source, limits()).unwrap();
let second = outline(source, limits()).unwrap();
assert_eq!(first, second);
assert!(
first
.declarations
.iter()
.all(|d| d.declaration.id.is_none())
);
assert_eq!(declaration(&first, "missing").id_literal_span, None);
assert_eq!(declaration(&first, "historical").id_literal_span, None);
assert_eq!(
text(source, declaration(&first, "bad").id_literal_span.unwrap()),
"\"not-a-uuid\""
);
// Balanced tokens are not a successful syntax/semantic validation claim.
assert!(!first.has_lexical_errors);
assert!(!first.has_unmatched_braces);
}
#[test]
fn invalid_full_scan_keeps_closed_children_and_reports_lexical_body_facts() {
let source = "oa_entity outer \"Outer\" {\n oa_actor ready \"Ready\" { description \"} stays text\"; }\n oa_actor pending \"Pending\" { description \"unfinished 🌊";
let result = outline(source, limits()).unwrap();
assert_eq!(result.source, source);
assert_eq!(result.tokens.last().unwrap().span.end, source.len());
assert!(result.has_lexical_errors);
assert!(result.has_unmatched_braces);
let ready = declaration(&result, "ready");
assert_eq!(
text(source, ready.declaration.span),
"oa_actor ready \"Ready\" { description \"} stays text\"; }"
);
assert_eq!(
declaration(&result, "outer").declaration.span.end,
source.len()
);
assert_eq!(
declaration(&result, "pending").declaration.span.end,
source.len()
);
let unmatched_close = outline("}\n// brace in comment {\n", limits()).unwrap();
assert!(unmatched_close.has_unmatched_braces);
assert!(!unmatched_close.has_lexical_errors);
}
#[test]
fn missing_body_syntax_is_unchecked_even_when_known_error_flags_are_clear() {
let source = "oa_actor a \"A\" id \"00000000-0000-0000-0000-000000000001\"";
let result = outline(source, limits()).unwrap();
assert_eq!(result.declarations.len(), 1);
assert!(!result.has_lexical_errors);
assert!(!result.has_unmatched_braces);
// There is deliberately no `valid` flag: the known-complete fact is scanning
// these bytes, not the missing body becoming legal or the draft being applied.
assert_eq!(result.source, source);
}
#[test]
fn keyword_alias_and_collisions_keep_every_source_ordered_header() {
let source = "project root_model \"Model\" {\n oa_actor oa_activity \"First\" id \"00000000-0000-0000-0000-000000000001\" {}\n oa_actor oa_activity \"Second\" id \"00000000-0000-0000-0000-000000000001\" {}\n diagram view_one \"View\" {}\n node placement { diagram @view_one; }\n}";
let result = outline(source, limits()).unwrap();
assert_eq!(result.declarations.len(), 5);
let duplicates: Vec<_> = result
.declarations
.iter()
.filter(|d| d.declaration.alias == "oa_activity")
.collect();
assert_eq!(duplicates.len(), 2);
assert!(duplicates[0].alias_span.start < duplicates[1].alias_span.start);
assert_eq!(duplicates[0].declaration.id, duplicates[1].declaration.id);
assert!(
result
.tokens
.iter()
.any(|t| t.span == duplicates[0].alias_span && t.class == TokenClass::Keyword)
);
assert_eq!(
text(source, declaration(&result, "placement").kind_span),
"node"
);
assert_eq!(declaration(&result, "placement").declaration.id, None);
}
#[test]
fn bounds_refuse_before_returning_a_partial_outline() {
let source = "oa_actor a \"A\" {}\noa_actor b \"B\" {}";
let admitted = outline(source, limits()).unwrap();
let exact = OutlineLimits {
max_source_bytes: source.len(),
max_tokens: admitted.tokens.len(),
max_declarations: 2,
};
assert_eq!(outline(source, exact).unwrap(), admitted);
for resource in [
OutlineResource::SourceBytes,
OutlineResource::Tokens,
OutlineResource::Declarations,
] {
let mut lower = exact;
match resource {
OutlineResource::SourceBytes => lower.max_source_bytes -= 1,
OutlineResource::Tokens => lower.max_tokens -= 1,
OutlineResource::Declarations => lower.max_declarations -= 1,
}
let error = outline(source, lower).unwrap_err();
assert_eq!(error.resource, resource);
assert!(error.observed_at_least > error.limit);
assert!(source.is_char_boundary(error.offset));
if resource == OutlineResource::Declarations {
assert_eq!(error.offset, source.find("oa_actor b").unwrap());
}
}
let empty = outline(
"",
OutlineLimits {
max_source_bytes: 0,
max_tokens: 0,
max_declarations: 0,
},
)
.unwrap();
assert!(empty.tokens.is_empty() && empty.declarations.is_empty());
let unicode = "// 🌊\r\noa_actor a \"A\" {}";
let error = outline(
unicode,
OutlineLimits {
max_source_bytes: 4,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::SourceBytes);
assert_eq!(error.offset, 0);
let error = outline(
unicode,
OutlineLimits {
max_tokens: 1,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::Tokens);
assert_eq!(error.offset, unicode.find('\n').unwrap());
}
#[test]
fn outline_ranges_follow_current_bytes_without_identity_stabilization() {
let old = "oa_actor a \"A\" {}\nsource @a;";
let current = format!("// 航海 🚒\r\n{old}");
let old_outline = outline(old, limits()).unwrap();
let current_outline = outline(&current, limits()).unwrap();
let shift = current.len() - old.len();
let old_role = &old_outline.declarations[0];
let current_role = &current_outline.declarations[0];
assert_eq!(
current_role.alias_span.start,
old_role.alias_span.start + shift
);
assert_eq!(
current_role.kind_span.start,
old_role.kind_span.start + shift
);
assert_eq!(
current_role.declaration.span.end,
old_role.declaration.span.end + shift
);
assert_eq!(current_outline.source, current);
assert_eq!(old_outline.source, old);
assert_eq!(current_role.declaration.id, None);
assert!(!current_outline.source.contains(" id "));
// Workspace revision/stale-handle rejection belongs to the query/adapter,
// not a claim that an old owned span can be applied to any other string.
}
#[test]
fn deeply_nested_bounds_use_the_same_iterative_walk_and_declaration_budget() {
let mut source = String::new();
for index in 0..600 {
source.push_str(&format!("oa_activity work_{index} \"Work\" {{\n"));
}
source.push_str(&"}\n".repeat(600));
let result = outline(&source, limits()).unwrap();
assert_eq!(result.declarations.len(), 600);
assert!(!result.has_unmatched_braces);
assert_eq!(
result.declarations[0].declaration.span.end,
source.len() - 1
);
let error = outline(
&source,
OutlineLimits {
max_declarations: 599,
..limits()
},
)
.unwrap_err();
assert_eq!(error.resource, OutlineResource::Declarations);
assert_eq!(error.observed_at_least, 600);
assert_eq!(error.offset, source.find("oa_activity work_599").unwrap());
}
#[test]
fn noncanonical_uuid_spellings_have_no_outline_or_analysis_identity() {
for raw in [
"00000000000000000000000000000001",
"{00000000-0000-0000-0000-000000000001}",
"urn:uuid:00000000-0000-0000-0000-000000000001",
] {
assert!(
Id::parse_str(raw).is_ok(),
"The UUID crate alone is too permissive"
);
assert!(!has_uuid_header_shape(raw));
let literal = format!("\"{raw}\"");
let modern = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let before = modern.clone();
let result = outline(&modern, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, None);
assert_eq!(text(&modern, d.id_literal_span.unwrap()), literal);
assert_eq!(modern, before);
let errors = parse(&modern).unwrap_err();
assert!(
errors
.iter()
.any(|error| error.message.contains("8-4-4-4-12")
&& error.span.start == modern.find(&literal).unwrap())
);
// Intentional compatibility correction: old analyze yielded Some(Id(1))
// here despite lint rejecting the header. It now shares outline's None.
let analysis = analyze(&modern);
assert_eq!(
analysis
.declarations
.iter()
.find(|d| d.alias == "model")
.unwrap()
.id,
None
);
assert!(
analysis
.diagnostics
.iter()
.any(|error| error.message.contains("8-4-4-4-12"))
);
let legacy_source = format!("arcadia 1; project \"Legacy\" id {literal} {{}}");
let legacy_errors = legacy::parse(&legacy_source).unwrap_err();
assert!(
legacy_errors
.iter()
.any(|error| error.message.contains("8-4-4-4-12"))
);
}
}
#[test]
fn uppercase_and_json_escaped_header_ids_survive_both_parsers_and_outline() {
let expected = Id::from_u128(0xabcdef);
let canonical = expected.to_string();
let uppercase = canonical.to_uppercase();
assert_ne!(uppercase, canonical);
for raw in [uppercase.clone(), format!("\\u0030{}", &uppercase[1..])] {
let literal = format!("\"{raw}\"");
let decoded: String = serde_json::from_str(&literal).unwrap();
assert!(has_uuid_header_shape(&decoded));
let modern = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let result = outline(&modern, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, Some(expected));
assert_eq!(text(&modern, d.id_literal_span.unwrap()), literal);
assert_eq!(result.source.as_bytes(), modern.as_bytes());
assert_eq!(parse(&modern).unwrap().id, expected);
let analysis = analyze(&modern);
assert_eq!(analysis.declarations[0].id, Some(expected));
assert!(
!analysis
.diagnostics
.iter()
.any(|error| error.severity == crate::validation::Severity::Error)
);
let legacy_source = format!("arcadia 1; project \"Legacy\" id {literal} {{}}");
assert_eq!(legacy::parse(&legacy_source).unwrap().id, expected);
}
}
#[test]
fn header_shape_still_requires_valid_hexadecimal_uuid_data() {
let raw = "00000000-0000-0000-0000-00000000000Z";
assert!(has_uuid_header_shape(raw));
assert!(Id::parse_str(raw).is_err());
let literal = format!("\"{raw}\"");
let source = format!("arcadia 7; project model \"Model\" id {literal} {{}}");
let result = outline(&source, limits()).unwrap();
let d = declaration(&result, "model");
assert_eq!(d.declaration.id, None);
assert_eq!(text(&source, d.id_literal_span.unwrap()), literal);
assert!(
parse(&source)
.unwrap_err()
.iter()
.any(|error| error.message == "Invalid UUID identity.")
);
assert_eq!(analyze(&source).declarations[0].id, None);
}
@@ -0,0 +1,44 @@
{
"status": "PASS",
"method": "Explicit original UTF-8 hex patterns and raw read_bytes, independent of locale text decoding",
"patterns": [
{
"name": "rescue",
"utf8Hex": "e69591e58aa9",
"verified": true
},
{
"name": "fire_engine",
"utf8Hex": "f09f9a92",
"verified": true
},
{
"name": "comment",
"utf8Hex": "e6b3a8e9878a",
"verified": true
},
{
"name": "inspection",
"utf8Hex": "e6a49ce69fbb",
"verified": true
},
{
"name": "ocean",
"utf8Hex": "f09f8c8a",
"verified": true
},
{
"name": "voyage",
"utf8Hex": "e888aae6b5b7",
"verified": true
}
],
"originalRescueCharacterLiteralCount": 4,
"candidateRescueCharacterLiteralCount": 4,
"querySha256": "86666c8390f0c63ec75b045366494a80d0ecde82924f2bac312afd01675aee56",
"outlineTestsSha256": "4c79a01e8aea243dd9ef66ce71b9fae263d0e79c319a46c51223679897e8b9df",
"priorVerifierFailures": [
"Initial expectation used e98788 instead of original e9878a in comment fixture",
"Next expectation assumed three char-literal uses; direct original raw-byte readback establishes four. Both original and corrected candidate contain four. Only verifier expectations changed."
]
}
@@ -0,0 +1,17 @@
{
"started": "2026-09-11T16:17:39.9144342Z",
"finished": "2026-09-11T16:23:09.9455930Z",
"exitCode": 0,
"args": [
"test",
"--locked",
"--offline",
"-p",
"oa-core",
"--lib",
"language::outline_tests::",
"--",
"--test-threads=1"
],
"buildJobs": 1
}
@@ -0,0 +1,20 @@
Compiling oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\crates\oa-core)
Finished `test` profile [unoptimized] target(s) in 5m 25s
Running unittests src\lib.rs (.local\target-gnullvm\debug\deps\oa_core-e594d1d7e7cdca87.exe)
running 12 tests
test language::outline_tests::bounds_refuse_before_returning_a_partial_outline ... ok
test language::outline_tests::closed_id_at_eof_is_inside_the_declaration_extent ... ok
test language::outline_tests::deeply_nested_bounds_use_the_same_iterative_walk_and_declaration_budget ... ok
test language::outline_tests::header_shape_still_requires_valid_hexadecimal_uuid_data ... ok
test language::outline_tests::invalid_full_scan_keeps_closed_children_and_reports_lexical_body_facts ... ok
test language::outline_tests::keyword_alias_and_collisions_keep_every_source_ordered_header ... ok
test language::outline_tests::missing_bad_and_historical_ids_never_allocate_authored_identity ... ok
test language::outline_tests::missing_body_syntax_is_unchecked_even_when_known_error_flags_are_clear ... ok
test language::outline_tests::noncanonical_uuid_spellings_have_no_outline_or_analysis_identity ... ok
test language::outline_tests::outline_ranges_follow_current_bytes_without_identity_stabilization ... ok
test language::outline_tests::outline_roles_preserve_unicode_crlf_and_exact_escaped_uuid_literal ... ok
test language::outline_tests::uppercase_and_json_escaped_header_ids_survive_both_parsers_and_outline ... ok
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 42 filtered out; finished in 1.44s
@@ -0,0 +1,10 @@
[
{
"Path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\crates\\oa-core\\src\\language.rs",
"Hash": "34CBB144A111E6F0DDADFCA7D40636A8E3323FE65EA8920FD2402F0352B41F57"
},
{
"Path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\crates\\oa-core\\src\\language_outline_tests.rs",
"Hash": "4C79A01E8AEA243DD9EF66CE71B9FAE263D0E79C319A46C51223679897E8B9DF"
}
]
@@ -0,0 +1,17 @@
{
"started": "2026-09-11T17:17:43.3562368Z",
"finished": "2026-09-11T17:18:18.6301449Z",
"exitCode": 0,
"args": [
"test",
"--locked",
"--offline",
"-p",
"oa-core",
"--lib",
"language::outline_tests::",
"--",
"--test-threads=1"
],
"buildJobs": 1
}
@@ -0,0 +1,20 @@
Compiling oa-core v0.2.0 (C:\Users\User\Documents\Git\ARCADIA-Studio\crates\oa-core)
Finished `test` profile [unoptimized] target(s) in 34.77s
Running unittests src\lib.rs (.local\target-gnullvm\debug\deps\oa_core-e594d1d7e7cdca87.exe)
running 12 tests
test language::outline_tests::bounds_refuse_before_returning_a_partial_outline ... ok
test language::outline_tests::closed_id_at_eof_is_inside_the_declaration_extent ... ok
test language::outline_tests::deeply_nested_bounds_use_the_same_iterative_walk_and_declaration_budget ... ok
test language::outline_tests::header_shape_still_requires_valid_hexadecimal_uuid_data ... ok
test language::outline_tests::invalid_full_scan_keeps_closed_children_and_reports_lexical_body_facts ... ok
test language::outline_tests::keyword_alias_and_collisions_keep_every_source_ordered_header ... ok
test language::outline_tests::missing_bad_and_historical_ids_never_allocate_authored_identity ... ok
test language::outline_tests::missing_body_syntax_is_unchecked_even_when_known_error_flags_are_clear ... ok
test language::outline_tests::noncanonical_uuid_spellings_have_no_outline_or_analysis_identity ... ok
test language::outline_tests::outline_ranges_follow_current_bytes_without_identity_stabilization ... ok
test language::outline_tests::outline_roles_preserve_unicode_crlf_and_exact_escaped_uuid_literal ... ok
test language::outline_tests::uppercase_and_json_escaped_header_ids_survive_both_parsers_and_outline ... ok
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 42 filtered out; finished in 0.11s
@@ -0,0 +1,5 @@
{
"sourceSha256": "FE37CD55B95C892C05AEC6C37A113154CAB7646DCFC333646FA8218345919751",
"binarySha256": "A20FD5147CC1953A13491050B289FAFC4049FBCD88D41B1BAC5D379FED2DAD63",
"binaryBytes": 8076800
}
@@ -0,0 +1,12 @@
{
"scope": "Private artifact-binding helper failure before query rustc/test; all core gates and original artifacts1 Cargo build already passed",
"helper": "run-query.ps1",
"helperSha256": "c112d1a496ed9d39e202f7704548863af45e532dfe89c675bb84b2569201b1ec",
"observedExitCode": 1,
"observedLine": 34,
"exception": "Exception calling Substring with 1 argument(s): startIndex cannot be larger than length of string. (Parameter startIndex)",
"cause": "Cargo reports top-level liboa_core.rlib without the hash suffix assumed by the helper",
"recovery": "Read existing successful Cargo JSON; bind top-level rlib to one byte-identical hashed dependency rlib using SHA256 plus exact byte readback; preserve matching fingerprint. No repeated Cargo/core gates.",
"resumedHelper": "run-query-resume.ps1",
"resumedHelperSha256": "07c707cfe4c143af8a64a5ba88de24c866d9a9929f23206f39e21df589c0977b"
}
@@ -0,0 +1,137 @@
[
{
"crate": "oa_core",
"rlib": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\liboa_core.rlib",
"bytes": 100082308,
"sha256": "43C8673DDBAE26D32D0557C7DB5E9F2AABA0B41F19AD1488A58461FE86BD5BDD",
"cargoArtifact": {
"reason": "compiler-artifact",
"package_id": "path+file:///C:/Users/User/Documents/Git/ARCADIA-Studio/crates/oa-core#0.2.0",
"manifest_path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\crates\\oa-core\\Cargo.toml",
"target": {
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "oa_core",
"src_path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\crates\\oa-core\\src\\lib.rs",
"edition": "2024",
"doc": true,
"doctest": true,
"test": true
},
"profile": {
"opt_level": "0",
"debuginfo": 0,
"debug_assertions": true,
"overflow_checks": true,
"test": false
},
"features": [],
"filenames": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\liboa_core.rlib",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\liboa_core-781c6973417b169c.rmeta"
],
"executable": null,
"fresh": true
},
"matchedDependencyRlib": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\liboa_core-781c6973417b169c.rlib",
"candidateHashes": [
{
"path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\liboa_core-095667392272c35c.rlib",
"sha256": "48872B220BC4450C172978F891D028F37B06822C05321C290A5AD2274A049E55"
},
{
"path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\liboa_core-3e81c616fea1d901.rlib",
"sha256": "5018A1FD7286ED9DFEDCBBF5B68B399AD5D143F2A9AAAED3078CFC934C9589C4"
},
{
"path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\liboa_core-6c8da57367eec642.rlib",
"sha256": "E49B23D858AC5EC1F5A4B9E2EFA78A4549CE6BC2C3936F8D76DB3B42E4A8D315"
},
{
"path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\liboa_core-781c6973417b169c.rlib",
"sha256": "43C8673DDBAE26D32D0557C7DB5E9F2AABA0B41F19AD1488A58461FE86BD5BDD"
},
{
"path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\liboa_core-fa08f4e46e1897c2.rlib",
"sha256": "A6084C3388E39C06B94EB9C13B4489A8AC974FB06907E86CC657CEEBE295401B"
}
],
"fingerprints": [
{
"original": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\.fingerprint\\oa-core-781c6973417b169c\\lib-oa_core",
"copy": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\fingerprints\\oa-core-781c6973417b169c\\lib-oa_core",
"sha256": "32D7FADB58B89D0877AB923522A0BBB715AC42C34526DE01CD3CEC0BE61DF760"
},
{
"original": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\.fingerprint\\oa-core-781c6973417b169c\\lib-oa_core.json",
"copy": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\fingerprints\\oa-core-781c6973417b169c\\lib-oa_core.json",
"sha256": "7664E5D9695D989D99873C6937409B188EE00489F6A808051D8FBAFDAF826BAA"
}
]
},
{
"crate": "serde_json",
"rlib": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rlib",
"bytes": 2698846,
"sha256": "441E8532A8AB31BB414A7FA1357354C27A692B3818CD9A219CF2D6DE32608589",
"cargoArtifact": {
"reason": "compiler-artifact",
"package_id": "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.151",
"manifest_path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_json-1.0.151\\Cargo.toml",
"target": {
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "serde_json",
"src_path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\toolchain\\cargo\\registry\\src\\index.crates.io-1949cf8c6b5b557f\\serde_json-1.0.151\\src\\lib.rs",
"edition": "2021",
"doc": true,
"doctest": true,
"test": true
},
"profile": {
"opt_level": "0",
"debuginfo": 0,
"debug_assertions": true,
"overflow_checks": true,
"test": false
},
"features": [
"default",
"std"
],
"filenames": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rlib",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rmeta"
],
"executable": null,
"fresh": true
},
"matchedDependencyRlib": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rlib",
"candidateHashes": [
{
"path": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rlib",
"sha256": "441E8532A8AB31BB414A7FA1357354C27A692B3818CD9A219CF2D6DE32608589"
}
],
"fingerprints": [
{
"original": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\.fingerprint\\serde_json-b48005beba7e4267\\lib-serde_json",
"copy": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\fingerprints\\serde_json-b48005beba7e4267\\lib-serde_json",
"sha256": "9202101A31AF6F8D24EDCEACBB8300C10DDDD94FB496CBF6451C8860133CE784"
},
{
"original": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\.fingerprint\\serde_json-b48005beba7e4267\\lib-serde_json.json",
"copy": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\fingerprints\\serde_json-b48005beba7e4267\\lib-serde_json.json",
"sha256": "310BEDB04F5F35EEF3A04E8019F0A204CC0F30B94CA808CB4D702CD7C6403737"
}
]
}
]
@@ -0,0 +1,25 @@
{
"started": "2026-09-11T17:11:13.8444785Z",
"finished": "2026-09-11T17:11:14.3049366Z",
"exitCode": 1,
"executable": "rustc",
"args": [
"--edition=2024",
"--crate-name",
"source_symbols_v2",
"--test",
"-Dwarnings",
"-C",
"linker=clang.exe",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\source_symbols-v2.rs",
"--extern",
"oa_core=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\liboa_core.rlib",
"--extern",
"serde_json=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rlib",
"-L",
"dependency=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps",
"-o",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\source-symbols-v2-tests.exe"
],
"buildJobs": 1
}
@@ -0,0 +1,39 @@
error: unknown start of token: \u{2022}
--> C:\Users\User\Documents\Git\ARCADIA-Studio\.local\text-navigation-integration-20260911\source_symbols-v2.rs:811:50
|
811 | let unicode_inside = fixture.text.find('æ•‘').unwrap() + 1;
| ^
|
help: Unicode character '•' (Bullet) looks like '.' (Period), but it is not
|
811 - let unicode_inside = fixture.text.find('æ•‘').unwrap() + 1;
811 + let unicode_inside = fixture.text.find('æ.‘').unwrap() + 1;
|
error: unknown start of token: \u{2018}
--> C:\Users\User\Documents\Git\ARCADIA-Studio\.local\text-navigation-integration-20260911\source_symbols-v2.rs:811:51
|
811 | let unicode_inside = fixture.text.find('æ•‘').unwrap() + 1;
| ^
|
help: Unicode character '‘' (Left Single Quotation Mark) looks like ''' (Single Quote), but it is not
|
811 - let unicode_inside = fixture.text.find('æ•‘').unwrap() + 1;
811 + let unicode_inside = fixture.text.find('æ•'').unwrap() + 1;
|
error[E0762]: unterminated character literal
--> C:\Users\User\Documents\Git\ARCADIA-Studio\.local\text-navigation-integration-20260911\source_symbols-v2.rs:811:52
|
811 | let unicode_inside = fixture.text.find('æ•‘').unwrap() + 1;
| ^^^^^^^^^^^^^^^^
|
help: if you meant to write a string literal, use double quotes
|
811 - let unicode_inside = fixture.text.find('æ•‘').unwrap() + 1;
811 + let unicode_inside = fixture.text.find("æ•‘").unwrap() + 1;
|
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0762`.
@@ -0,0 +1,25 @@
{
"started": "2026-09-11T17:14:29.0879039Z",
"finished": "2026-09-11T17:14:31.5558783Z",
"exitCode": 1,
"executable": "rustc",
"args": [
"--edition=2024",
"--crate-name",
"source_symbols_v2",
"--test",
"-Dwarnings",
"-C",
"linker=clang.exe",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\source_symbols-v2-utf8.rs",
"--extern",
"oa_core=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\liboa_core.rlib",
"--extern",
"serde_json=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rlib",
"-L",
"dependency=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps",
"-o",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\source-symbols-v2-utf8-tests.exe"
],
"buildJobs": 1
}
@@ -0,0 +1,42 @@
error[E0271]: expected `as_slice` to return `&[_; 0]`, but it returns `&[usize]`
--> C:\Users\User\Documents\Git\ARCADIA-Studio\.local\text-navigation-integration-20260911\source_symbols-v2-utf8.rs:543:81
|
543 | Definitions { index: self, indices: self.aliases.get(alias).map_or(&[], Vec::as_slice).iter(), domain }
| ------ ^^^^^^^^^^^^^ expected `&[_; 0]`, found `&[usize]`
| |
| required by a bound introduced by this call
|
= note: expected reference `&[_; 0]`
found reference `&[usize]`
note: required by a bound in `Option::<T>::map_or`
--> /rustc/48a229ceaefd4985c50990b14116b6d856af0985/library\core\src\option.rs:1222:4
error[E0271]: expected `as_slice` to return `&[_; 0]`, but it returns `&[usize]`
--> C:\Users\User\Documents\Git\ARCADIA-Studio\.local\text-navigation-integration-20260911\source_symbols-v2-utf8.rs:547:82
|
547 | Definitions { index: self, indices: self.identities.get(&id).map_or(&[], Vec::as_slice).iter(), domain }
| ------ ^^^^^^^^^^^^^ expected `&[_; 0]`, found `&[usize]`
| |
| required by a bound introduced by this call
|
= note: expected reference `&[_; 0]`
found reference `&[usize]`
note: required by a bound in `Option::<T>::map_or`
--> /rustc/48a229ceaefd4985c50990b14116b6d856af0985/library\core\src\option.rs:1222:4
error[E0271]: expected `as_slice` to return `&[_; 0]`, but it returns `&[usize]`
--> C:\Users\User\Documents\Git\ARCADIA-Studio\.local\text-navigation-integration-20260911\source_symbols-v2-utf8.rs:551:77
|
551 | References { index: self, indices: self.uses.get(alias).map_or(&[], Vec::as_slice).iter(), domain }
| ------ ^^^^^^^^^^^^^ expected `&[_; 0]`, found `&[usize]`
| |
| required by a bound introduced by this call
|
= note: expected reference `&[_; 0]`
found reference `&[usize]`
note: required by a bound in `Option::<T>::map_or`
--> /rustc/48a229ceaefd4985c50990b14116b6d856af0985/library\core\src\option.rs:1222:4
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0271`.
@@ -0,0 +1,25 @@
{
"started": "2026-09-11T17:16:42.8222070Z",
"finished": "2026-09-11T17:16:47.1533244Z",
"exitCode": 0,
"executable": "rustc",
"args": [
"--edition=2024",
"--crate-name",
"source_symbols_v2",
"--test",
"-Dwarnings",
"-C",
"linker=clang.exe",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\source_symbols-v2-utf8-typed.rs",
"--extern",
"oa_core=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\liboa_core.rlib",
"--extern",
"serde_json=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps\\libserde_json-b48005beba7e4267.rlib",
"-L",
"dependency=C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\deps",
"-o",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\source-symbols-v2-utf8-typed-tests.exe"
],
"buildJobs": 1
}
@@ -0,0 +1,12 @@
{
"baselineSha256": "cf82e34544ce508e446787b6335aefe97e146ea5e7cca0a9788deb9097f8f7bb",
"patchSha256": "f38b2d5bab3ca6ab66b8bd865f3b01562299fb961c48c8172d39e1d35d90e329",
"exactPatchedSha256": "3f313e44fad033b042699a47d2432d0a3a725c37ab9a6213b6dfcafd4b04d7b2",
"candidateSha256": "8f3f20a7e72c870cfd1ad46f0aa8b8998ffc1ebf3357911957ed4995758e7520",
"onlyPostPatchChange": {
"old": "/// strings; they cannot scale beyond the admitted input bytes.",
"new": "/// strings. Scratch storage is proportional to admitted input bytes and file\n/// count, including Unicode expansion and collection overhead."
},
"testAttributes": 20,
"execution": "pending"
}
@@ -0,0 +1,10 @@
{
"started": "2026-09-11T17:16:47.2718656Z",
"finished": "2026-09-11T17:16:47.3866620Z",
"exitCode": 0,
"executable": "C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-integration-20260911\\source-symbols-v2-utf8-typed-tests.exe",
"args": [
"--test-threads=1"
],
"buildJobs": 1
}
@@ -0,0 +1,25 @@
running 20 tests
test tests::admitted_unicode_path_budget_keeps_original_policy_after_single_fold ... ok
test tests::comment_separated_reference_keeps_crlf_unicode_and_disjoint_hit_spans ... ok
test tests::declaration_order_and_duplicate_roles_refuse_instead_of_corrupting_hit_search ... ok
test tests::detached_uuid_clone_disables_anchor_even_for_included_query ... ok
test tests::duplicate_aliases_are_candidates_without_false_reference_attribution ... ok
test tests::every_budget_admits_boundary_and_returns_no_index_one_below ... ok
test tests::header_metadata_must_match_current_token_boundaries_and_authored_id ... ok
test tests::incomplete_draft_is_lexical_and_error_token_does_not_leak_references ... ok
test tests::legal_keyword_classified_alias_is_not_discarded ... ok
test tests::missing_ids_produce_only_current_snapshot_locations_without_stabilization ... ok
test tests::nested_declaration_extents_do_not_turn_body_text_into_definition_hits ... ok
test tests::noncanonical_header_identity_cannot_enter_through_query_metadata ... ok
test tests::path_identity_rejects_normalization_and_case_collisions ... ok
test tests::query_header_admission_preserves_uppercase_and_json_escape_bytes ... ok
test tests::repeated_live_uses_are_distinct_and_strings_comments_history_are_excluded ... ok
test tests::reused_alias_cannot_steal_old_identity_and_old_locations_are_stale ... ok
test tests::scope_provenance_and_detached_alias_collision_are_explicit ... ok
test tests::stopped_outline_is_not_a_successful_empty_query ... ok
test tests::truncated_or_gapped_tokens_refuse_even_when_project_scope_is_partial ... ok
test tests::unicode_path_collisions_match_core_lowercase_policy ... ok
test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s
@@ -0,0 +1,9 @@
{
"baselineCandidateSha256": "86666c8390f0c63ec75b045366494a80d0ecde82924f2bac312afd01675aee56",
"candidateSha256": "fe37cd55b95c892c05aec6c37a113154cab7646dcfc333646fa8218345919751",
"correction": "Exactly three empty-array references coerced to empty slices in map_or defaults",
"occurrences": 3,
"apiChange": false,
"cause": "Actual query-compile2 E0271 at lines543/547/551",
"tests": "pending"
}
@@ -0,0 +1,20 @@
$ErrorActionPreference = 'Stop'
. ./.local/toolchain/env.ps1
$env:CARGO_BUILD_JOBS = '1'
$evidenceRoot = Join-Path (Get-Location) '.local/text-navigation-integration-20260911'
$gates = @(
@{name='outline1'; args=@('test','--locked','--offline','-p','oa-core','--lib','language::outline_tests::','--','--test-threads=1')},
@{name='core1'; args=@('test','--locked','--offline','-p','oa-core','--','--test-threads=1')},
@{name='clippy1'; args=@('clippy','--locked','--offline','-p','oa-core','--all-targets','--','-D','warnings')}
)
foreach ($gate in $gates) {
$logPath = Join-Path $evidenceRoot ($gate.name + '.log')
$statusPath = Join-Path $evidenceRoot ($gate.name + '-status.json')
if ((Test-Path -LiteralPath $logPath) -or (Test-Path -LiteralPath $statusPath)) { throw "Refusing to overwrite $($gate.name)" }
$started = [DateTime]::UtcNow.ToString('o')
$gateArgs = $gate.args
& cargo @gateArgs 2>&1 | Tee-Object -FilePath $logPath
$gateExit = $LASTEXITCODE
[ordered]@{started=$started;finished=[DateTime]::UtcNow.ToString('o');exitCode=$gateExit;args=$gateArgs;buildJobs=1} | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $statusPath
if ($gateExit -ne 0) { exit $gateExit }
}
@@ -0,0 +1,74 @@
$ErrorActionPreference = 'Stop'
. ./.local/toolchain/env.ps1
$env:CARGO_BUILD_JOBS = '1'
$evidenceRoot = Join-Path (Get-Location) '.local/text-navigation-integration-20260911'
foreach ($gateName in @('outline1','core1','clippy1')) {
$prior = Get-Content -Raw -LiteralPath (Join-Path $evidenceRoot "$gateName-status.json") | ConvertFrom-Json
if ($prior.exitCode -ne 0) { throw "Required prior gate failed: $gateName" }
}
function Invoke-RecordedNative {
param([string]$Name,[string]$Executable,[string[]]$Arguments)
$stdout = Join-Path $evidenceRoot "$Name-stdout.log"
$stderr = Join-Path $evidenceRoot "$Name-stderr.log"
$status = Join-Path $evidenceRoot "$Name-status.json"
if ((Test-Path $stdout) -or (Test-Path $stderr) -or (Test-Path $status)) { throw "Refusing overwrite $Name" }
$started = [DateTime]::UtcNow.ToString('o')
& $Executable @Arguments 1> $stdout 2> $stderr
$code = $LASTEXITCODE
[ordered]@{started=$started;finished=[DateTime]::UtcNow.ToString('o');exitCode=$code;executable=$Executable;args=$Arguments;buildJobs=1} | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $status
Get-Content -LiteralPath $stderr
if ($Name -ne 'artifacts1') { Get-Content -LiteralPath $stdout }
if ($code -ne 0) { exit $code }
}
$artifactStatus = Get-Content -Raw -LiteralPath (Join-Path $evidenceRoot 'artifacts1-status.json') | ConvertFrom-Json
if ($artifactStatus.exitCode -ne 0) { throw 'Original artifact build did not pass' }
$dependencyDirectories = @()
$messages = Get-Content -LiteralPath (Join-Path $evidenceRoot 'artifacts1-stdout.log') | ForEach-Object { $_ | ConvertFrom-Json }
$bindings = @{}
$bindingRecords = @()
foreach ($crate in @('oa_core','serde_json')) {
$artifacts = @($messages | Where-Object { $_.reason -eq 'compiler-artifact' -and $_.target.name -eq $crate -and $_.target.kind -contains 'lib' })
if ($artifacts.Count -ne 1) { throw "Expected exactly one Cargo lib artifact for $crate; got $($artifacts.Count)" }
$rlibs = @($artifacts[0].filenames | Where-Object { $_.EndsWith('.rlib') })
if ($rlibs.Count -ne 1) { throw "Expected one rlib for $crate" }
$rlib = $rlibs[0]
$artifactHash = (Get-FileHash -LiteralPath $rlib).Hash
$artifactBase = [IO.Path]::GetFileNameWithoutExtension($rlib)
if ($artifactBase.StartsWith('lib' + $crate + '-')) {
$dependencyRlib = $rlib
$matchEvidence = @([ordered]@{path=$rlib;sha256=$artifactHash})
} else {
$dependencyRoot = Join-Path (Split-Path $rlib) 'deps'
$matchEvidence = @(Get-ChildItem -LiteralPath $dependencyRoot -Filter "lib$crate-*.rlib" | ForEach-Object {
[pscustomobject]@{path=$_.FullName;sha256=(Get-FileHash -LiteralPath $_.FullName).Hash}
})
$matchesByHash = @($matchEvidence | Where-Object { $_.sha256 -eq $artifactHash })
if ($matchesByHash.Count -ne 1) { throw "Expected exactly one byte-hash-matching dependency rlib for $crate; got $($matchesByHash.Count)" }
$dependencyRlib = $matchesByHash[0].path
if (-not [Linq.Enumerable]::SequenceEqual([byte[]][IO.File]::ReadAllBytes($rlib),[byte[]][IO.File]::ReadAllBytes($dependencyRlib))) { throw 'Hash-matched rlib byte readback differs' }
}
$dependencyDirectories += Split-Path $dependencyRlib
$suffix = [IO.Path]::GetFileNameWithoutExtension($dependencyRlib).Substring(('lib' + $crate + '-').Length)
$packageName = if ($crate -eq 'oa_core') { 'oa-core' } else { $crate }
$fingerprintRoot = Join-Path $env:CARGO_TARGET_DIR "debug/.fingerprint/$packageName-$suffix"
$fingerprints = @()
foreach ($name in @("lib-$crate", "lib-$crate.json")) {
$fp = Join-Path $fingerprintRoot $name
if (-not (Test-Path -LiteralPath $fp -PathType Leaf)) { throw "Missing exact fingerprint $fp" }
$destination = Join-Path $evidenceRoot "fingerprints/$packageName-$suffix/$name"
New-Item -ItemType Directory -Path (Split-Path $destination) -Force | Out-Null
Copy-Item -LiteralPath $fp -Destination $destination
$fingerprints += [ordered]@{original=$fp;copy=$destination;sha256=(Get-FileHash -LiteralPath $fp).Hash}
}
$bindings[$crate] = $rlib
$bindingRecords += [ordered]@{crate=$crate;rlib=$rlib;bytes=(Get-Item -LiteralPath $rlib).Length;sha256=(Get-FileHash -LiteralPath $rlib).Hash;cargoArtifact=$artifacts[0];matchedDependencyRlib=$dependencyRlib;candidateHashes=$matchEvidence;fingerprints=$fingerprints}
}
$bindingRecords | ConvertTo-Json -Depth 12 | Set-Content -LiteralPath (Join-Path $evidenceRoot 'query-bindings.json')
$source = Join-Path $evidenceRoot 'source_symbols-v2.rs'
$binary = Join-Path $evidenceRoot 'source-symbols-v2-tests.exe'
$uniqueDependencyDirectories = @($dependencyDirectories | Sort-Object -Unique)
if ($uniqueDependencyDirectories.Count -ne 1) { throw 'Artifact dependency directories differ' }
$dependencies = $uniqueDependencyDirectories[0]
Invoke-RecordedNative 'query-compile1' 'rustc' @('--edition=2024','--crate-name','source_symbols_v2','--test','-Dwarnings','-C','linker=clang.exe',$source,'--extern',"oa_core=$($bindings['oa_core'])",'--extern',"serde_json=$($bindings['serde_json'])",'-L',"dependency=$dependencies",'-o',$binary)
Invoke-RecordedNative 'query-tests1' $binary @('--test-threads=1')
[ordered]@{sourceSha256=(Get-FileHash -LiteralPath $source).Hash;binarySha256=(Get-FileHash -LiteralPath $binary).Hash;binaryBytes=(Get-Item -LiteralPath $binary).Length} | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $evidenceRoot 'query-artifacts.json')
@@ -0,0 +1,43 @@
$ErrorActionPreference = 'Stop'
. ./.local/toolchain/env.ps1
$env:CARGO_BUILD_JOBS = '1'
$evidenceRoot = Join-Path (Get-Location) '.local/text-navigation-integration-20260911'
foreach ($gateName in @('outline1','core1','clippy1')) {
$prior = Get-Content -Raw -LiteralPath (Join-Path $evidenceRoot "$gateName-status.json") | ConvertFrom-Json
if ($prior.exitCode -ne 0) { throw "Required prior gate failed: $gateName" }
}
function Invoke-RecordedNative {
param([string]$Name,[string]$Executable,[string[]]$Arguments)
$stdout = Join-Path $evidenceRoot "$Name-stdout.log"
$stderr = Join-Path $evidenceRoot "$Name-stderr.log"
$status = Join-Path $evidenceRoot "$Name-status.json"
if ((Test-Path $stdout) -or (Test-Path $stderr) -or (Test-Path $status)) { throw "Refusing overwrite $Name" }
$started = [DateTime]::UtcNow.ToString('o')
& $Executable @Arguments 1> $stdout 2> $stderr
$code = $LASTEXITCODE
[ordered]@{started=$started;finished=[DateTime]::UtcNow.ToString('o');exitCode=$code;executable=$Executable;args=$Arguments;buildJobs=1} | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $status
Get-Content -LiteralPath $stderr
if ($Name -ne 'artifacts1') { Get-Content -LiteralPath $stdout }
if ($code -ne 0) { exit $code }
}
$records = Get-Content -Raw -LiteralPath (Join-Path $evidenceRoot 'query-bindings.json') | ConvertFrom-Json
$bindings = @{}
$dependencyDirectories = @()
foreach ($r in $records) {
if ((Get-FileHash -LiteralPath $r.rlib).Hash -ne $r.sha256) { throw 'Bound artifact changed' }
if ((Get-FileHash -LiteralPath $r.matchedDependencyRlib).Hash -ne $r.sha256) { throw 'Matched dependency artifact changed' }
foreach ($fp in $r.fingerprints) {
if ((Get-FileHash -LiteralPath $fp.original).Hash -ne $fp.sha256 -or (Get-FileHash -LiteralPath $fp.copy).Hash -ne $fp.sha256) { throw 'Bound fingerprint changed' }
}
$bindings[$r.crate] = $r.rlib
$dependencyDirectories += Split-Path $r.matchedDependencyRlib
}
$uniqueDirectories = @($dependencyDirectories | Sort-Object -Unique)
if ($uniqueDirectories.Count -ne 1) { throw 'Dependency directory mismatch' }
$dependencies = $uniqueDirectories[0]
$source = Join-Path $evidenceRoot 'source_symbols-v2-utf8-typed.rs'
if ((Get-FileHash -LiteralPath $source).Hash -ne 'FE37CD55B95C892C05AEC6C37A113154CAB7646DCFC333646FA8218345919751') { throw 'Query source changed' }
$binary = Join-Path $evidenceRoot 'source-symbols-v2-utf8-typed-tests.exe'
Invoke-RecordedNative 'query-compile3' 'rustc' @('--edition=2024','--crate-name','source_symbols_v2','--test','-Dwarnings','-C','linker=clang.exe',$source,'--extern',"oa_core=$($bindings['oa_core'])",'--extern',"serde_json=$($bindings['serde_json'])",'-L',"dependency=$dependencies",'-o',$binary)
Invoke-RecordedNative 'query-tests3' $binary @('--test-threads=1')
[ordered]@{sourceSha256=(Get-FileHash -LiteralPath $source).Hash;binarySha256=(Get-FileHash -LiteralPath $binary).Hash;binaryBytes=(Get-Item -LiteralPath $binary).Length} | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $evidenceRoot 'query-artifacts3.json')
@@ -0,0 +1,43 @@
$ErrorActionPreference = 'Stop'
. ./.local/toolchain/env.ps1
$env:CARGO_BUILD_JOBS = '1'
$evidenceRoot = Join-Path (Get-Location) '.local/text-navigation-integration-20260911'
foreach ($gateName in @('outline1','core1','clippy1')) {
$prior = Get-Content -Raw -LiteralPath (Join-Path $evidenceRoot "$gateName-status.json") | ConvertFrom-Json
if ($prior.exitCode -ne 0) { throw "Required prior gate failed: $gateName" }
}
function Invoke-RecordedNative {
param([string]$Name,[string]$Executable,[string[]]$Arguments)
$stdout = Join-Path $evidenceRoot "$Name-stdout.log"
$stderr = Join-Path $evidenceRoot "$Name-stderr.log"
$status = Join-Path $evidenceRoot "$Name-status.json"
if ((Test-Path $stdout) -or (Test-Path $stderr) -or (Test-Path $status)) { throw "Refusing overwrite $Name" }
$started = [DateTime]::UtcNow.ToString('o')
& $Executable @Arguments 1> $stdout 2> $stderr
$code = $LASTEXITCODE
[ordered]@{started=$started;finished=[DateTime]::UtcNow.ToString('o');exitCode=$code;executable=$Executable;args=$Arguments;buildJobs=1} | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $status
Get-Content -LiteralPath $stderr
if ($Name -ne 'artifacts1') { Get-Content -LiteralPath $stdout }
if ($code -ne 0) { exit $code }
}
$records = Get-Content -Raw -LiteralPath (Join-Path $evidenceRoot 'query-bindings.json') | ConvertFrom-Json
$bindings = @{}
$dependencyDirectories = @()
foreach ($r in $records) {
if ((Get-FileHash -LiteralPath $r.rlib).Hash -ne $r.sha256) { throw 'Bound artifact changed' }
if ((Get-FileHash -LiteralPath $r.matchedDependencyRlib).Hash -ne $r.sha256) { throw 'Matched dependency artifact changed' }
foreach ($fp in $r.fingerprints) {
if ((Get-FileHash -LiteralPath $fp.original).Hash -ne $fp.sha256 -or (Get-FileHash -LiteralPath $fp.copy).Hash -ne $fp.sha256) { throw 'Bound fingerprint changed' }
}
$bindings[$r.crate] = $r.rlib
$dependencyDirectories += Split-Path $r.matchedDependencyRlib
}
$uniqueDirectories = @($dependencyDirectories | Sort-Object -Unique)
if ($uniqueDirectories.Count -ne 1) { throw 'Dependency directory mismatch' }
$dependencies = $uniqueDirectories[0]
$source = Join-Path $evidenceRoot 'source_symbols-v2-utf8.rs'
if ((Get-FileHash -LiteralPath $source).Hash -ne '86666C8390F0C63EC75B045366494A80D0ECDE82924F2BAC312AFD01675AEE56') { throw 'Query source changed' }
$binary = Join-Path $evidenceRoot 'source-symbols-v2-utf8-tests.exe'
Invoke-RecordedNative 'query-compile2' 'rustc' @('--edition=2024','--crate-name','source_symbols_v2','--test','-Dwarnings','-C','linker=clang.exe',$source,'--extern',"oa_core=$($bindings['oa_core'])",'--extern',"serde_json=$($bindings['serde_json'])",'-L',"dependency=$dependencies",'-o',$binary)
Invoke-RecordedNative 'query-tests2' $binary @('--test-threads=1')
[ordered]@{sourceSha256=(Get-FileHash -LiteralPath $source).Hash;binarySha256=(Get-FileHash -LiteralPath $binary).Hash;binaryBytes=(Get-Item -LiteralPath $binary).Length} | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $evidenceRoot 'query-artifacts2.json')
@@ -0,0 +1,56 @@
$ErrorActionPreference = 'Stop'
. ./.local/toolchain/env.ps1
$env:CARGO_BUILD_JOBS = '1'
$evidenceRoot = Join-Path (Get-Location) '.local/text-navigation-integration-20260911'
foreach ($gateName in @('outline1','core1','clippy1')) {
$prior = Get-Content -Raw -LiteralPath (Join-Path $evidenceRoot "$gateName-status.json") | ConvertFrom-Json
if ($prior.exitCode -ne 0) { throw "Required prior gate failed: $gateName" }
}
function Invoke-RecordedNative {
param([string]$Name,[string]$Executable,[string[]]$Arguments)
$stdout = Join-Path $evidenceRoot "$Name-stdout.log"
$stderr = Join-Path $evidenceRoot "$Name-stderr.log"
$status = Join-Path $evidenceRoot "$Name-status.json"
if ((Test-Path $stdout) -or (Test-Path $stderr) -or (Test-Path $status)) { throw "Refusing overwrite $Name" }
$started = [DateTime]::UtcNow.ToString('o')
& $Executable @Arguments 1> $stdout 2> $stderr
$code = $LASTEXITCODE
[ordered]@{started=$started;finished=[DateTime]::UtcNow.ToString('o');exitCode=$code;executable=$Executable;args=$Arguments;buildJobs=1} | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $status
Get-Content -LiteralPath $stderr
if ($Name -ne 'artifacts1') { Get-Content -LiteralPath $stdout }
if ($code -ne 0) { exit $code }
}
Invoke-RecordedNative 'compiler1' 'rustc' @('-vV')
Invoke-RecordedNative 'artifacts1' 'cargo' @('build','--locked','--offline','-p','oa-core','--lib','--message-format=json')
$messages = Get-Content -LiteralPath (Join-Path $evidenceRoot 'artifacts1-stdout.log') | ForEach-Object { $_ | ConvertFrom-Json }
$bindings = @{}
$bindingRecords = @()
foreach ($crate in @('oa_core','serde_json')) {
$artifacts = @($messages | Where-Object { $_.reason -eq 'compiler-artifact' -and $_.target.name -eq $crate -and $_.target.kind -contains 'lib' })
if ($artifacts.Count -ne 1) { throw "Expected exactly one Cargo lib artifact for $crate; got $($artifacts.Count)" }
$rlibs = @($artifacts[0].filenames | Where-Object { $_.EndsWith('.rlib') })
if ($rlibs.Count -ne 1) { throw "Expected one rlib for $crate" }
$rlib = $rlibs[0]
$suffix = [IO.Path]::GetFileNameWithoutExtension($rlib).Substring(('lib' + $crate + '-').Length)
$packageName = if ($crate -eq 'oa_core') { 'oa-core' } else { $crate }
$fingerprintRoot = Join-Path $env:CARGO_TARGET_DIR "debug/.fingerprint/$packageName-$suffix"
$fingerprints = @()
foreach ($name in @("lib-$crate", "lib-$crate.json")) {
$fp = Join-Path $fingerprintRoot $name
if (-not (Test-Path -LiteralPath $fp -PathType Leaf)) { throw "Missing exact fingerprint $fp" }
$destination = Join-Path $evidenceRoot "fingerprints/$packageName-$suffix/$name"
New-Item -ItemType Directory -Path (Split-Path $destination) -Force | Out-Null
Copy-Item -LiteralPath $fp -Destination $destination
$fingerprints += [ordered]@{original=$fp;copy=$destination;sha256=(Get-FileHash -LiteralPath $fp).Hash}
}
$bindings[$crate] = $rlib
$bindingRecords += [ordered]@{crate=$crate;rlib=$rlib;bytes=(Get-Item -LiteralPath $rlib).Length;sha256=(Get-FileHash -LiteralPath $rlib).Hash;cargoArtifact=$artifacts[0];fingerprints=$fingerprints}
}
$bindingRecords | ConvertTo-Json -Depth 12 | Set-Content -LiteralPath (Join-Path $evidenceRoot 'query-bindings.json')
$source = Join-Path $evidenceRoot 'source_symbols-v2.rs'
$binary = Join-Path $evidenceRoot 'source-symbols-v2-tests.exe'
$dependencies = Split-Path $bindings['oa_core']
if ((Split-Path $bindings['serde_json']) -ne $dependencies) { throw 'Artifact dependency directories differ' }
Invoke-RecordedNative 'query-compile1' 'rustc' @('--edition=2024','--crate-name','source_symbols_v2','--test','-Dwarnings','-C','linker=clang.exe',$source,'--extern',"oa_core=$($bindings['oa_core'])",'--extern',"serde_json=$($bindings['serde_json'])",'-L',"dependency=$dependencies",'-o',$binary)
Invoke-RecordedNative 'query-tests1' $binary @('--test-threads=1')
[ordered]@{sourceSha256=(Get-FileHash -LiteralPath $source).Hash;binarySha256=(Get-FileHash -LiteralPath $binary).Hash;binaryBytes=(Get-Item -LiteralPath $binary).Length} | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $evidenceRoot 'query-artifacts.json')
@@ -0,0 +1,22 @@
$ErrorActionPreference = 'Stop'
. ./.local/toolchain/env.ps1
$env:CARGO_BUILD_JOBS = '1'
$evidenceRoot = Join-Path (Get-Location) '.local/text-navigation-integration-20260911'
$sourcePaths = @('crates/oa-core/src/language.rs','crates/oa-core/src/language_outline_tests.rs')
if (Test-Path (Join-Path $evidenceRoot 'outline2-inputs.json')) { throw 'Refusing input receipt overwrite' }
Get-FileHash -LiteralPath $sourcePaths | Select-Object Path,Hash | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $evidenceRoot 'outline2-inputs.json')
$gates = @(
@{name='outline2'; args=@('test','--locked','--offline','-p','oa-core','--lib','language::outline_tests::','--','--test-threads=1')},
@{name='clippy-tests2'; args=@('clippy','--locked','--offline','-p','oa-core','--lib','--tests','--','-D','warnings')}
)
foreach ($gate in $gates) {
$logPath = Join-Path $evidenceRoot ($gate.name + '.log')
$statusPath = Join-Path $evidenceRoot ($gate.name + '-status.json')
if ((Test-Path -LiteralPath $logPath) -or (Test-Path -LiteralPath $statusPath)) { throw "Refusing to overwrite $($gate.name)" }
$started = [DateTime]::UtcNow.ToString('o')
$gateArgs = $gate.args
& cargo @gateArgs 2>&1 | Tee-Object -FilePath $logPath
$gateExit = $LASTEXITCODE
[ordered]@{started=$started;finished=[DateTime]::UtcNow.ToString('o');exitCode=$gateExit;args=$gateArgs;buildJobs=1} | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $statusPath
if ($gateExit -ne 0) { exit $gateExit }
}
@@ -0,0 +1,9 @@
{
"cause": "Initial reconstruction used Windows cp1252 default instead of explicit UTF-8",
"productionLanguageByteEqualityToUtf8Patch": true,
"oldOutlineTestsSha256": "f64bd89959554cd5842609c031d442f3d9e27b73a216dd936715284c9fe9fb97",
"correctedOutlineTestsPreFormatSha256": "27f4a02f01c3e182da7e49556bcec602e01fb5060026e919d1a05116ca255805",
"failedQueryCandidateSha256": "8f3f20a7e72c870cfd1ad46f0aa8b8998ffc1ebf3357911957ed4995758e7520",
"correctedQueryCandidateSha256": "86666c8390f0c63ec75b045366494a80d0ecde82924f2bac312afd01675aee56",
"scope": "Four Unicode outline test fixture lines and private query literals; production language implementation unchanged. Preserve original successful broader evidence; repeat affected exact-Unicode tests and lint."
}
@@ -0,0 +1,61 @@
# Navigation native preparation
Prepared 2026-09-11 by Codex-9e8r6t /root/linux_readiness for Gitea #6. These are input fixtures and read-only oracle results, **not native navigation acceptance**. No GUI, compiler, server or WSL was launched.
## Inputs
- `valid-baseline/project.arcadia`: immutable v7 entry with four files, UTF-8 without BOM and CRLF throughout. `valid-work` is an exact separate copy for GUI use. Two OA activities live in Unicode folder `救援`; `links.arcadia` contains one interaction with source `@assess` and target `@confirm`.
- `ambiguous-open/project.arcadia`: duplicate `assess` declaration with its own UUID, preserving `confirm`. Copy this directory to a new trial directory before opening or repairing it. Expected draft lookup: two `assess` definitions and one lexical use, explicit row choice; no accepted-model success is assumed.
- `missing-include-open/project.arcadia`: valid fixture plus `include "missing/not-loaded.arcadia";`; the target is intentionally absent. Copy before a repair trial. Expected loaded-source query scope is partial, with one loaded declaration/use for each alias; navigation must not fetch/create the missing file.
- `release1-baseline` and `release1-work`: exact copies of all 37 files in `examples/release1`, including its 30 reachable Arcadia files. This is a realistic walkthrough, **not the separate 100-module performance fixture**.
The valid fixture uses stable UUIDs `9e8f0000-0000-4000-8000-000000000001` through `...0004` for project, assess, confirm and handoff respectively. The duplicate has `...0005`. Expected aliases, excluded prose/comment occurrences, exact byte spans and one-based line/UTF-8 byte-column positions are in `expected-locations.json`; those expectations were calculated directly from authored bytes, independently of the application lexer.
Useful valid locations:
| Kind | Path | Line:byte-column | Alias bytes `[start,end)` |
| --- | --- | --- | --- |
| Declaration assess | 救援/assess.arcadia | 2:13 | 59..65 |
| Declaration confirm | 救援/confirm.arcadia | 1:13 | 12..19 |
| Live assess use | links.arcadia | 2:52 | 137..143 |
| Live confirm use | links.arcadia | 2:68 | 153..160 |
There are five excluded `@assess` occurrences across descriptions/comments. The quoted Unicode text before live references exercises byte columns that differ from character columns. A use's selection excludes its `@` marker. No scalar-column or normalized-newline position is substituted.
## Native procedure for root
1. Launch the separately identified new GUI using its established private environment. Open `valid-work/project.arcadia` through the real picker. Open `links.arcadia`, put the caret on the live assess use (not the description), press F12, inspect the exact declaration selection and viewport, then Alt+Left to return. Repeat with confirm. Buttons should also work; shortcut handling requires editor focus.
2. From the assess declaration, Shift+F12 should show exactly one declaration and one lexical use. Prose/comment occurrences must not appear. Inspect Unicode path, locations, scope and any selected source bytes. Opening a unique validated included declaration may navigate directly.
3. Edit a source draft without Apply, query again and observe explicit choice/draft status. Change an indexed source after a result is shown and verify stale results cannot jump; rerun. Check Back after changing its origin draft restores the current cursor rather than an obsolete selection. Preserve raw screenshots/logs and do not count planned behavior as a pass.
4. Run separate Open repair trials on fresh copies of the two invalid fixtures. Observe real application admission and loaded-file state before asserting result counts. The negative oracle proves loader rejection, not that the GUI reaches a particular repair panel.
5. For unchanged-model/source acceptance, use a fresh valid work copy or explicitly revert every intentional draft edit before Save. Compare the immutable baseline against the actual saved directory using the oracle below. Do not compare an intentionally edited draft checkpoint and call its expected mismatch a product defect.
6. The release1 copy supports a realistic modular trial. A measured 100-module trial remains separate work; no performance result is claimed here.
## Oracle evidence and reproduction
Existing executable: `../staged-source-oracle-20260911/staged-source-authoring-contract.exe`, SHA256 `967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c`. It loads both projects, compares complete decoded Project/identities and exact reachable SourceBundle, and compares all physical `.arcadia` files. Its `same` command exposes no full-model JSON output; the full-model equality claim comes from those assertions, not an exported model artifact.
From repository root, with the existing compatible runtime on a process-local PATH:
```powershell
$navRepo = (Get-Location).Path
$navInputs = Join-Path $navRepo '.local/text-navigation-native-20260911-preparation'
$navOracle = Join-Path $navRepo '.local/staged-source-oracle-20260911/staged-source-authoring-contract.exe'
$env:PATH = "$navRepo\.local\toolchain\llvm-mingw-20260826-ucrt-x86_64\bin;$env:SystemRoot\System32;$env:SystemRoot"
& $navOracle same "$navInputs\valid-baseline\project.arcadia" "$navInputs\valid-work\project.arcadia"
# Preserve stdout, stderr and the actual $LASTEXITCODE for each new checkpoint.
```
`check.py` is the completed, one-shot preparation check and refuses to overwrite its result records. `prepare.py` likewise refuses existing authored paths; do not rerun either helper over these preserved inputs. Reuse the direct oracle command with fresh log/result names for native checkpoints.
Actual preparation results:
- `valid-same`: exit 0, complete model/identity and 4 reachable/4 disk files equal.
- `release1-same`: exit 0, complete model/identity and 30 reachable/30 disk files equal.
- `ambiguous-rejected`: exit 101, expected `duplicate_declaration` loader error.
- `missing-include-rejected`: exit 101, expected `missing_include` loader error.
- Initial helper failed before any oracle process because Python environment key `SystemRoot` was absent in that spelling. Corrected to a case-insensitive Windows key lookup; `helper-initial-failure.json` records the scope. No fixture/executable correction was necessary.
- All 90 fixture files, 592459 bytes, match `fixture-manifest.json` after execution. `check-summary.json` records commands, exits, timing and runtime hash. Timing is oracle execution only, not GUI or navigation performance.
Manifest SHA256: `edd4157fc31823f4494dee91862728b87f12ef51c49b8d1fd86a954bc9ecc1ed`.
Expected-locations SHA256: `81574d2c9c0aec1657a293af52a469506ccddfa2914e820c61af619d5622837f`.
@@ -0,0 +1,4 @@
interaction handoff "Assessment handoff" id "9e8f0000-0000-4000-8000-000000000004" {
description "救援 @assess is prose"; source @assess; target @confirm;
// Another comment @assess is excluded.
}
@@ -0,0 +1,7 @@
arcadia 7;
project navigation_trial "Navigation — 救援" id "9e8f0000-0000-4000-8000-000000000001" {
description "Prose @assess must not be a lexical use.";
include "救援/assess.arcadia";
include "救援/confirm.arcadia";
include "links.arcadia";
}
@@ -0,0 +1,4 @@
// Comment @assess must not be a lexical use.
oa_activity assess "Assess 救援 request" id "9e8f0000-0000-4000-8000-000000000002" {
description "Keep @assess as prose, not a use.";
}
@@ -0,0 +1,2 @@
oa_activity confirm "Confirm 救援 response" id "9e8f0000-0000-4000-8000-000000000003" {}
oa_activity assess "Duplicate draft assessment" id "9e8f0000-0000-4000-8000-000000000005" {}
@@ -0,0 +1,14 @@
{
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\staged-source-oracle-20260911\\staged-source-authoring-contract.exe",
"same",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\ambiguous-open\\project.arcadia",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\ambiguous-open\\project.arcadia"
],
"oracle_sha256": "967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c",
"exit": 101,
"expected_success": false,
"expectation_met": true,
"seconds": 0.031000000000858563,
"finished_utc": "2026-09-11T17:45:35.367737+00:00"
}
@@ -0,0 +1,4 @@
thread 'main' (7504) panicked at harness/staged-source-authoring-contract.rs:76:5:
Loader errors: [SourceDiagnostic { path: "救援/confirm.arcadia", diagnostic: Diagnostic { severity: Error, code: "duplicate_declaration", object_id: None, field: None, line: 2, column: 1, message: "Duplicate alias 'assess'.", span: Span { start: 92, end: 184 } }, related: [SourceLocation { path: "救援/assess.arcadia", span: Span { start: 47, end: 190 } }] }]
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
@@ -0,0 +1,62 @@
{
"results": [
{
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\staged-source-oracle-20260911\\staged-source-authoring-contract.exe",
"same",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\valid-baseline\\project.arcadia",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\valid-work\\project.arcadia"
],
"oracle_sha256": "967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c",
"exit": 0,
"expected_success": true,
"expectation_met": true,
"seconds": 0.07799999999951979,
"finished_utc": "2026-09-11T17:45:34.947690+00:00"
},
{
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\staged-source-oracle-20260911\\staged-source-authoring-contract.exe",
"same",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\release1-baseline\\project.arcadia",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\release1-work\\project.arcadia"
],
"oracle_sha256": "967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c",
"exit": 0,
"expected_success": true,
"expectation_met": true,
"seconds": 0.39099999999962165,
"finished_utc": "2026-09-11T17:45:35.339540+00:00"
},
{
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\staged-source-oracle-20260911\\staged-source-authoring-contract.exe",
"same",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\ambiguous-open\\project.arcadia",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\ambiguous-open\\project.arcadia"
],
"oracle_sha256": "967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c",
"exit": 101,
"expected_success": false,
"expectation_met": true,
"seconds": 0.031000000000858563,
"finished_utc": "2026-09-11T17:45:35.367737+00:00"
},
{
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\staged-source-oracle-20260911\\staged-source-authoring-contract.exe",
"same",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\missing-include-open\\project.arcadia",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\missing-include-open\\project.arcadia"
],
"oracle_sha256": "967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c",
"exit": 101,
"expected_success": false,
"expectation_met": true,
"seconds": 0.030999999999039574,
"finished_utc": "2026-09-11T17:45:35.401779+00:00"
}
],
"all_fixture_bytes_unchanged": true,
"runtime_sha256": "f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4"
}
@@ -0,0 +1,43 @@
from pathlib import Path
import hashlib
import json
import os
import subprocess
import time
from datetime import datetime, timezone
root = Path(__file__).resolve().parent
repo = root.parent.parent
oracle = repo / '.local/staged-source-oracle-20260911/staged-source-authoring-contract.exe'
expected_hash = '967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c'
assert hashlib.sha256(oracle.read_bytes()).hexdigest() == expected_hash
runtime = repo / '.local/toolchain/llvm-mingw-20260826-ucrt-x86_64/bin'
assert (runtime / 'libunwind.dll').is_file()
env = os.environ.copy()
system_root = next(value for key, value in env.items() if key.lower() == 'systemroot')
env['PATH'] = str(runtime) + ';' + system_root + '/System32;' + system_root
env['RUST_BACKTRACE'] = '0'
results = []
for label, left, right, expected_success in [
('valid-same', 'valid-baseline', 'valid-work', True),
('release1-same', 'release1-baseline', 'release1-work', True),
('ambiguous-rejected', 'ambiguous-open', 'ambiguous-open', False),
('missing-include-rejected', 'missing-include-open', 'missing-include-open', False),
]:
args = [str(oracle), 'same', str(root / left / 'project.arcadia'), str(root / right / 'project.arcadia')]
assert not (root / (label + '-result.json')).exists()
started = time.monotonic()
process = subprocess.run(args, cwd=root, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=45)
(root / (label + '.stdout.log')).write_bytes(process.stdout)
(root / (label + '.stderr.log')).write_bytes(process.stderr)
result = {'command': args, 'oracle_sha256': expected_hash, 'exit': process.returncode,
'expected_success': expected_success, 'expectation_met': (process.returncode == 0) == expected_success,
'seconds': time.monotonic() - started, 'finished_utc': datetime.now(timezone.utc).isoformat()}
(root / (label + '-result.json')).write_text(json.dumps(result, indent=2) + '\n', encoding='utf-8')
results.append(result)
print(label, process.returncode, process.stdout.decode('utf-8', errors='replace').strip())
manifest = json.loads((root / 'fixture-manifest.json').read_text(encoding='utf-8'))
assert all(hashlib.sha256((root / entry['path']).read_bytes()).hexdigest() == entry['sha256'] for entry in manifest)
(root / 'check-summary.json').write_text(json.dumps({'results': results, 'all_fixture_bytes_unchanged': True,
'runtime_sha256': hashlib.sha256((runtime / 'libunwind.dll').read_bytes()).hexdigest()}, indent=2) + '\n', encoding='utf-8')
assert all(result['expectation_met'] for result in results)
@@ -0,0 +1,385 @@
{
"encoding": "UTF-8 without BOM; every authored fixture newline CRLF",
"valid_totals": {
"assess": {
"declarations": 1,
"lexical_uses": 1
},
"confirm": {
"declarations": 1,
"lexical_uses": 1
}
},
"ambiguous_totals": {
"assess": {
"declarations": 2,
"lexical_uses": 1
}
},
"locations": [
{
"fixture": "valid-baseline",
"path": "links.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
111,
117
],
"byte_offset": 111,
"line_1based": 2,
"utf8_byte_column_1based": 26
},
{
"fixture": "valid-baseline",
"path": "links.arcadia",
"alias": "assess",
"kind": "lexical-use",
"span": [
137,
143
],
"byte_offset": 137,
"line_1based": 2,
"utf8_byte_column_1based": 52
},
{
"fixture": "valid-baseline",
"path": "links.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
187,
193
],
"byte_offset": 187,
"line_1based": 3,
"utf8_byte_column_1based": 25
},
{
"fixture": "valid-baseline",
"path": "links.arcadia",
"alias": "confirm",
"kind": "lexical-use",
"span": [
153,
160
],
"byte_offset": 153,
"line_1based": 2,
"utf8_byte_column_1based": 68
},
{
"fixture": "valid-baseline",
"path": "project.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
130,
136
],
"byte_offset": 130,
"line_1based": 3,
"utf8_byte_column_1based": 25
},
{
"fixture": "valid-baseline",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
12,
18
],
"byte_offset": 12,
"line_1based": 1,
"utf8_byte_column_1based": 13
},
{
"fixture": "valid-baseline",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "declaration",
"span": [
59,
65
],
"byte_offset": 59,
"line_1based": 2,
"utf8_byte_column_1based": 13
},
{
"fixture": "valid-baseline",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
158,
164
],
"byte_offset": 158,
"line_1based": 3,
"utf8_byte_column_1based": 24
},
{
"fixture": "valid-baseline",
"path": "救援/confirm.arcadia",
"alias": "confirm",
"kind": "declaration",
"span": [
12,
19
],
"byte_offset": 12,
"line_1based": 1,
"utf8_byte_column_1based": 13
},
{
"fixture": "ambiguous-open",
"path": "links.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
111,
117
],
"byte_offset": 111,
"line_1based": 2,
"utf8_byte_column_1based": 26
},
{
"fixture": "ambiguous-open",
"path": "links.arcadia",
"alias": "assess",
"kind": "lexical-use",
"span": [
137,
143
],
"byte_offset": 137,
"line_1based": 2,
"utf8_byte_column_1based": 52
},
{
"fixture": "ambiguous-open",
"path": "links.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
187,
193
],
"byte_offset": 187,
"line_1based": 3,
"utf8_byte_column_1based": 25
},
{
"fixture": "ambiguous-open",
"path": "links.arcadia",
"alias": "confirm",
"kind": "lexical-use",
"span": [
153,
160
],
"byte_offset": 153,
"line_1based": 2,
"utf8_byte_column_1based": 68
},
{
"fixture": "ambiguous-open",
"path": "project.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
130,
136
],
"byte_offset": 130,
"line_1based": 3,
"utf8_byte_column_1based": 25
},
{
"fixture": "ambiguous-open",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
12,
18
],
"byte_offset": 12,
"line_1based": 1,
"utf8_byte_column_1based": 13
},
{
"fixture": "ambiguous-open",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "declaration",
"span": [
59,
65
],
"byte_offset": 59,
"line_1based": 2,
"utf8_byte_column_1based": 13
},
{
"fixture": "ambiguous-open",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
158,
164
],
"byte_offset": 158,
"line_1based": 3,
"utf8_byte_column_1based": 24
},
{
"fixture": "ambiguous-open",
"path": "救援/confirm.arcadia",
"alias": "assess",
"kind": "declaration",
"span": [
104,
110
],
"byte_offset": 104,
"line_1based": 2,
"utf8_byte_column_1based": 13
},
{
"fixture": "ambiguous-open",
"path": "救援/confirm.arcadia",
"alias": "confirm",
"kind": "declaration",
"span": [
12,
19
],
"byte_offset": 12,
"line_1based": 1,
"utf8_byte_column_1based": 13
},
{
"fixture": "missing-include-open",
"path": "links.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
111,
117
],
"byte_offset": 111,
"line_1based": 2,
"utf8_byte_column_1based": 26
},
{
"fixture": "missing-include-open",
"path": "links.arcadia",
"alias": "assess",
"kind": "lexical-use",
"span": [
137,
143
],
"byte_offset": 137,
"line_1based": 2,
"utf8_byte_column_1based": 52
},
{
"fixture": "missing-include-open",
"path": "links.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
187,
193
],
"byte_offset": 187,
"line_1based": 3,
"utf8_byte_column_1based": 25
},
{
"fixture": "missing-include-open",
"path": "links.arcadia",
"alias": "confirm",
"kind": "lexical-use",
"span": [
153,
160
],
"byte_offset": 153,
"line_1based": 2,
"utf8_byte_column_1based": 68
},
{
"fixture": "missing-include-open",
"path": "project.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
130,
136
],
"byte_offset": 130,
"line_1based": 3,
"utf8_byte_column_1based": 25
},
{
"fixture": "missing-include-open",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
12,
18
],
"byte_offset": 12,
"line_1based": 1,
"utf8_byte_column_1based": 13
},
{
"fixture": "missing-include-open",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "declaration",
"span": [
59,
65
],
"byte_offset": 59,
"line_1based": 2,
"utf8_byte_column_1based": 13
},
{
"fixture": "missing-include-open",
"path": "救援/assess.arcadia",
"alias": "assess",
"kind": "excluded-comment-or-string",
"span": [
158,
164
],
"byte_offset": 158,
"line_1based": 3,
"utf8_byte_column_1based": 24
},
{
"fixture": "missing-include-open",
"path": "救援/confirm.arcadia",
"alias": "confirm",
"kind": "declaration",
"span": [
12,
19
],
"byte_offset": 12,
"line_1based": 1,
"utf8_byte_column_1based": 13
}
]
}
@@ -0,0 +1,452 @@
[
{
"path": "valid-baseline/links.arcadia",
"bytes": 211,
"sha256": "d3229ecf6300804103eb7f85bd5891c022f6f6c194dbdbbdcb54e9550338dc3b"
},
{
"path": "valid-baseline/project.arcadia",
"bytes": 277,
"sha256": "79e26836c048a35aaf98b21ff006ae8ac931160abd9913b9e67b542303215414"
},
{
"path": "valid-baseline/救援/assess.arcadia",
"bytes": 192,
"sha256": "d99593537e67b2dfd293623f467ffbd46af4ea259dffae55d1fe9995c86e6992"
},
{
"path": "valid-baseline/救援/confirm.arcadia",
"bytes": 92,
"sha256": "591b32db3b1282825750d002d9293cfc450d55252506623302ce36c949fe9919"
},
{
"path": "valid-work/links.arcadia",
"bytes": 211,
"sha256": "d3229ecf6300804103eb7f85bd5891c022f6f6c194dbdbbdcb54e9550338dc3b"
},
{
"path": "valid-work/project.arcadia",
"bytes": 277,
"sha256": "79e26836c048a35aaf98b21ff006ae8ac931160abd9913b9e67b542303215414"
},
{
"path": "valid-work/救援/assess.arcadia",
"bytes": 192,
"sha256": "d99593537e67b2dfd293623f467ffbd46af4ea259dffae55d1fe9995c86e6992"
},
{
"path": "valid-work/救援/confirm.arcadia",
"bytes": 92,
"sha256": "591b32db3b1282825750d002d9293cfc450d55252506623302ce36c949fe9919"
},
{
"path": "ambiguous-open/links.arcadia",
"bytes": 211,
"sha256": "d3229ecf6300804103eb7f85bd5891c022f6f6c194dbdbbdcb54e9550338dc3b"
},
{
"path": "ambiguous-open/project.arcadia",
"bytes": 277,
"sha256": "79e26836c048a35aaf98b21ff006ae8ac931160abd9913b9e67b542303215414"
},
{
"path": "ambiguous-open/救援/assess.arcadia",
"bytes": 192,
"sha256": "d99593537e67b2dfd293623f467ffbd46af4ea259dffae55d1fe9995c86e6992"
},
{
"path": "ambiguous-open/救援/confirm.arcadia",
"bytes": 186,
"sha256": "ba3e222bdc7dfa94e4f1b16df091447835da6b5bea8a72701e12e077e77319a6"
},
{
"path": "missing-include-open/links.arcadia",
"bytes": 211,
"sha256": "d3229ecf6300804103eb7f85bd5891c022f6f6c194dbdbbdcb54e9550338dc3b"
},
{
"path": "missing-include-open/project.arcadia",
"bytes": 320,
"sha256": "573357995f0a68fef39aa3eef3125e2271242d1ce01607c129624399b77e682e"
},
{
"path": "missing-include-open/救援/assess.arcadia",
"bytes": 192,
"sha256": "d99593537e67b2dfd293623f467ffbd46af4ea259dffae55d1fe9995c86e6992"
},
{
"path": "missing-include-open/救援/confirm.arcadia",
"bytes": 92,
"sha256": "591b32db3b1282825750d002d9293cfc450d55252506623302ce36c949fe9919"
},
{
"path": "release1-baseline/evidence/repair-check.md",
"bytes": 1419,
"sha256": "f4db17bdca4ecbb1bf0caef01b2da5f1f7f798ab3152b648ce6dd8696a6a68e5"
},
{
"path": "release1-baseline/expected-diagnostics.json",
"bytes": 288,
"sha256": "3700393d76b940cfc076bf52861bd7b1f43370f8eabce3594531bd0bf1fc851e"
},
{
"path": "release1-baseline/model.json",
"bytes": 134520,
"sha256": "ef0ef4006c3e09d5db6e1b621256b3f7d6642f3a7b09cc34607cfbcca830c727"
},
{
"path": "release1-baseline/model.rs",
"bytes": 28762,
"sha256": "15f30f6bde655808fe754665c26d560e36f2a9bad340f346b09137d0d05045f5"
},
{
"path": "release1-baseline/oa/activities/activity_oa_restore_work.arcadia",
"bytes": 1307,
"sha256": "83e73d0a013d5c3e1a4af0d9139ab0cfa362d25a846671fc2dac59181061a9d4"
},
{
"path": "release1-baseline/oa/behavior/process_oa_assessment_procedure.arcadia",
"bytes": 697,
"sha256": "172c32c044ef4b5bc58a1f4635cc81f48dabb4014479b47dce7b25fedf2dbd0d"
},
{
"path": "release1-baseline/oa/behavior/process_oa_field_procedure.arcadia",
"bytes": 1781,
"sha256": "d2552dc5383e2e91cb302a790364e197f663c2edc013a2ab1978789825c9c324"
},
{
"path": "release1-baseline/oa/behavior/process_oa_response.arcadia",
"bytes": 3225,
"sha256": "cf86f46fa5c5d70592ef43f1bc1cb4d968efd8add384ba88036bef6b88aa4abc"
},
{
"path": "release1-baseline/oa/behavior/scenario_oa_conversation.arcadia",
"bytes": 1795,
"sha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
},
{
"path": "release1-baseline/oa/behavior/scenario_oa_full_scenario.arcadia",
"bytes": 1261,
"sha256": "00a1edf2c9707a0eb62ac070c2d02467874f2c9c1f273cc6ddb53d6d65999a1c"
},
{
"path": "release1-baseline/oa/behavior/state_machine_oa_monitor.arcadia",
"bytes": 2022,
"sha256": "447c9ad1359f4a31ecf975ad07c0b08d8e7e03191fb0858e2fc56f377b223cd5"
},
{
"path": "release1-baseline/oa/capabilities.arcadia",
"bytes": 781,
"sha256": "fc8012e5554350b12e1cb80080f8feab80d933c9b33c0f2a7bb500cb7d609936"
},
{
"path": "release1-baseline/oa/model.arcadia",
"bytes": 661,
"sha256": "f7cf914766ea73ec53b85e32d117ea9a9dba52d3e038246863541ae7069b1a15"
},
{
"path": "release1-baseline/oa/participants.arcadia",
"bytes": 1834,
"sha256": "951764c14179f27c10e315acf2ea37d1fff54c77b8441e23addd239e8c715ce3"
},
{
"path": "release1-baseline/oa/types.arcadia",
"bytes": 788,
"sha256": "9d0396fb82dd5733edd8d1cf52f968ca84906927c704f9cf0944a7fae215cf49"
},
{
"path": "release1-baseline/project.arcadia",
"bytes": 1958,
"sha256": "b2674e6bf77cfe0f6f0ba79c81d2e96d92f39c02ca2c6266d80e91723bfb9fda"
},
{
"path": "release1-baseline/README.md",
"bytes": 11137,
"sha256": "113cfb1cf38a98b51bff60442d86a35d636a3d80ef206bece7d53d0aae67f2d5"
},
{
"path": "release1-baseline/sa/behavior/process_sa_assessment_procedure.arcadia",
"bytes": 706,
"sha256": "73928ced61c06cbc08728d7956676a50fd4c05aa5b7f1ff4f29ce27a0b0f2088"
},
{
"path": "release1-baseline/sa/behavior/process_sa_field_procedure.arcadia",
"bytes": 1790,
"sha256": "886d462af83110cbfa55dd232a667ea1446761234471357cbb878794e98e8768"
},
{
"path": "release1-baseline/sa/behavior/process_sa_response.arcadia",
"bytes": 3234,
"sha256": "041785fc22842423822431bd5e6e8d16094ebd0716965e7c765fb8c1d7549e8a"
},
{
"path": "release1-baseline/sa/behavior/scenario_sa_conversation.arcadia",
"bytes": 2127,
"sha256": "97276f5757ee9aa12a0dbd9d3ccd58174b3091162bb8bcce357cec20a45f5d85"
},
{
"path": "release1-baseline/sa/behavior/scenario_sa_full_scenario.arcadia",
"bytes": 1256,
"sha256": "e12fc406b99d60a2f7768aaa0b25ba560e8605f0b8e37f3a7cdd3b8443562b74"
},
{
"path": "release1-baseline/sa/behavior/state_machine_sa_monitor.arcadia",
"bytes": 2022,
"sha256": "05ce29af99424c491c47fe2450dc6f5f8ce995511c01ec7e17bb5855be3c9736"
},
{
"path": "release1-baseline/sa/capabilities.arcadia",
"bytes": 781,
"sha256": "b6912fb3ece439912345fa71724acd462e716a1e5a88203a1058a5c3b2c20a4f"
},
{
"path": "release1-baseline/sa/functions/function_sa_audit_thresholds.arcadia",
"bytes": 297,
"sha256": "e5a04325d52183956dca814dd90f4e56c96c6b7db0f4f202f203ecb49c3e0f4f"
},
{
"path": "release1-baseline/sa/functions/function_sa_restore_work.arcadia",
"bytes": 2576,
"sha256": "fddeb67308051325041fee641fe758ddf43345b7c47b66d433616ad07fdccdd6"
},
{
"path": "release1-baseline/sa/model.arcadia",
"bytes": 661,
"sha256": "d431509251acb859fbb98733b6d18add952495e10a78703fbe8f31e40bc083c4"
},
{
"path": "release1-baseline/sa/participants.arcadia",
"bytes": 4012,
"sha256": "780d2eb08b217b67b55febb3d34846f727b8ee9018df6c5741748647e36b2ff8"
},
{
"path": "release1-baseline/sa/types.arcadia",
"bytes": 1227,
"sha256": "101fc0fbd99f1101514aa7b6da4f8e535aae0bb94c9e2b9e7e6c151135b28660"
},
{
"path": "release1-baseline/traceability.arcadia",
"bytes": 29506,
"sha256": "48a96f543456c9b5a5798fc795594e4119147fe45f11a6f109f141b7f514560f"
},
{
"path": "release1-baseline/transition-before.json",
"bytes": 35801,
"sha256": "2253e6434f741687e22327c37d520ed15c043bc36025498650bc2366bb6a874d"
},
{
"path": "release1-baseline/transition-request.json",
"bytes": 4276,
"sha256": "43b9a22e5f95ad3bc0ebd2478ead0e14406854abc989ae94ded9367b013d812a"
},
{
"path": "release1-baseline/views/diagram_oa_allocation_view.arcadia",
"bytes": 2176,
"sha256": "dfc0eb61e0e2aa5bda45524571fbfa3494f44ce19696f3e15e07438074a07bc7"
},
{
"path": "release1-baseline/views/diagram_sa_allocation_view.arcadia",
"bytes": 2173,
"sha256": "b78b43a26a82efb8fbd5374b09c329fa341f57b29f635d397b9ef8aede71d389"
},
{
"path": "release1-baseline/views/diagram_sa_capability_view.arcadia",
"bytes": 1620,
"sha256": "75e8dc9fb30f25d6f8fd3c6b595593ab4f98958a25798f961e336e0fac557649"
},
{
"path": "release1-baseline/views/diagram_sa_service_view.arcadia",
"bytes": 2209,
"sha256": "b08c84f3ea633e7c78dfdad3272f75415f6256cf3614b6d99bfd4f0269076c9b"
},
{
"path": "release1-baseline/views/diagram_sa_state_view.arcadia",
"bytes": 1931,
"sha256": "5f42f4c605e57b817d8400ed21f2b14bfc4e1592aebe941ff113767504c2b869"
},
{
"path": "release1-work/evidence/repair-check.md",
"bytes": 1419,
"sha256": "f4db17bdca4ecbb1bf0caef01b2da5f1f7f798ab3152b648ce6dd8696a6a68e5"
},
{
"path": "release1-work/expected-diagnostics.json",
"bytes": 288,
"sha256": "3700393d76b940cfc076bf52861bd7b1f43370f8eabce3594531bd0bf1fc851e"
},
{
"path": "release1-work/model.json",
"bytes": 134520,
"sha256": "ef0ef4006c3e09d5db6e1b621256b3f7d6642f3a7b09cc34607cfbcca830c727"
},
{
"path": "release1-work/model.rs",
"bytes": 28762,
"sha256": "15f30f6bde655808fe754665c26d560e36f2a9bad340f346b09137d0d05045f5"
},
{
"path": "release1-work/oa/activities/activity_oa_restore_work.arcadia",
"bytes": 1307,
"sha256": "83e73d0a013d5c3e1a4af0d9139ab0cfa362d25a846671fc2dac59181061a9d4"
},
{
"path": "release1-work/oa/behavior/process_oa_assessment_procedure.arcadia",
"bytes": 697,
"sha256": "172c32c044ef4b5bc58a1f4635cc81f48dabb4014479b47dce7b25fedf2dbd0d"
},
{
"path": "release1-work/oa/behavior/process_oa_field_procedure.arcadia",
"bytes": 1781,
"sha256": "d2552dc5383e2e91cb302a790364e197f663c2edc013a2ab1978789825c9c324"
},
{
"path": "release1-work/oa/behavior/process_oa_response.arcadia",
"bytes": 3225,
"sha256": "cf86f46fa5c5d70592ef43f1bc1cb4d968efd8add384ba88036bef6b88aa4abc"
},
{
"path": "release1-work/oa/behavior/scenario_oa_conversation.arcadia",
"bytes": 1795,
"sha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6"
},
{
"path": "release1-work/oa/behavior/scenario_oa_full_scenario.arcadia",
"bytes": 1261,
"sha256": "00a1edf2c9707a0eb62ac070c2d02467874f2c9c1f273cc6ddb53d6d65999a1c"
},
{
"path": "release1-work/oa/behavior/state_machine_oa_monitor.arcadia",
"bytes": 2022,
"sha256": "447c9ad1359f4a31ecf975ad07c0b08d8e7e03191fb0858e2fc56f377b223cd5"
},
{
"path": "release1-work/oa/capabilities.arcadia",
"bytes": 781,
"sha256": "fc8012e5554350b12e1cb80080f8feab80d933c9b33c0f2a7bb500cb7d609936"
},
{
"path": "release1-work/oa/model.arcadia",
"bytes": 661,
"sha256": "f7cf914766ea73ec53b85e32d117ea9a9dba52d3e038246863541ae7069b1a15"
},
{
"path": "release1-work/oa/participants.arcadia",
"bytes": 1834,
"sha256": "951764c14179f27c10e315acf2ea37d1fff54c77b8441e23addd239e8c715ce3"
},
{
"path": "release1-work/oa/types.arcadia",
"bytes": 788,
"sha256": "9d0396fb82dd5733edd8d1cf52f968ca84906927c704f9cf0944a7fae215cf49"
},
{
"path": "release1-work/project.arcadia",
"bytes": 1958,
"sha256": "b2674e6bf77cfe0f6f0ba79c81d2e96d92f39c02ca2c6266d80e91723bfb9fda"
},
{
"path": "release1-work/README.md",
"bytes": 11137,
"sha256": "113cfb1cf38a98b51bff60442d86a35d636a3d80ef206bece7d53d0aae67f2d5"
},
{
"path": "release1-work/sa/behavior/process_sa_assessment_procedure.arcadia",
"bytes": 706,
"sha256": "73928ced61c06cbc08728d7956676a50fd4c05aa5b7f1ff4f29ce27a0b0f2088"
},
{
"path": "release1-work/sa/behavior/process_sa_field_procedure.arcadia",
"bytes": 1790,
"sha256": "886d462af83110cbfa55dd232a667ea1446761234471357cbb878794e98e8768"
},
{
"path": "release1-work/sa/behavior/process_sa_response.arcadia",
"bytes": 3234,
"sha256": "041785fc22842423822431bd5e6e8d16094ebd0716965e7c765fb8c1d7549e8a"
},
{
"path": "release1-work/sa/behavior/scenario_sa_conversation.arcadia",
"bytes": 2127,
"sha256": "97276f5757ee9aa12a0dbd9d3ccd58174b3091162bb8bcce357cec20a45f5d85"
},
{
"path": "release1-work/sa/behavior/scenario_sa_full_scenario.arcadia",
"bytes": 1256,
"sha256": "e12fc406b99d60a2f7768aaa0b25ba560e8605f0b8e37f3a7cdd3b8443562b74"
},
{
"path": "release1-work/sa/behavior/state_machine_sa_monitor.arcadia",
"bytes": 2022,
"sha256": "05ce29af99424c491c47fe2450dc6f5f8ce995511c01ec7e17bb5855be3c9736"
},
{
"path": "release1-work/sa/capabilities.arcadia",
"bytes": 781,
"sha256": "b6912fb3ece439912345fa71724acd462e716a1e5a88203a1058a5c3b2c20a4f"
},
{
"path": "release1-work/sa/functions/function_sa_audit_thresholds.arcadia",
"bytes": 297,
"sha256": "e5a04325d52183956dca814dd90f4e56c96c6b7db0f4f202f203ecb49c3e0f4f"
},
{
"path": "release1-work/sa/functions/function_sa_restore_work.arcadia",
"bytes": 2576,
"sha256": "fddeb67308051325041fee641fe758ddf43345b7c47b66d433616ad07fdccdd6"
},
{
"path": "release1-work/sa/model.arcadia",
"bytes": 661,
"sha256": "d431509251acb859fbb98733b6d18add952495e10a78703fbe8f31e40bc083c4"
},
{
"path": "release1-work/sa/participants.arcadia",
"bytes": 4012,
"sha256": "780d2eb08b217b67b55febb3d34846f727b8ee9018df6c5741748647e36b2ff8"
},
{
"path": "release1-work/sa/types.arcadia",
"bytes": 1227,
"sha256": "101fc0fbd99f1101514aa7b6da4f8e535aae0bb94c9e2b9e7e6c151135b28660"
},
{
"path": "release1-work/traceability.arcadia",
"bytes": 29506,
"sha256": "48a96f543456c9b5a5798fc795594e4119147fe45f11a6f109f141b7f514560f"
},
{
"path": "release1-work/transition-before.json",
"bytes": 35801,
"sha256": "2253e6434f741687e22327c37d520ed15c043bc36025498650bc2366bb6a874d"
},
{
"path": "release1-work/transition-request.json",
"bytes": 4276,
"sha256": "43b9a22e5f95ad3bc0ebd2478ead0e14406854abc989ae94ded9367b013d812a"
},
{
"path": "release1-work/views/diagram_oa_allocation_view.arcadia",
"bytes": 2176,
"sha256": "dfc0eb61e0e2aa5bda45524571fbfa3494f44ce19696f3e15e07438074a07bc7"
},
{
"path": "release1-work/views/diagram_sa_allocation_view.arcadia",
"bytes": 2173,
"sha256": "b78b43a26a82efb8fbd5374b09c329fa341f57b29f635d397b9ef8aede71d389"
},
{
"path": "release1-work/views/diagram_sa_capability_view.arcadia",
"bytes": 1620,
"sha256": "75e8dc9fb30f25d6f8fd3c6b595593ab4f98958a25798f961e336e0fac557649"
},
{
"path": "release1-work/views/diagram_sa_service_view.arcadia",
"bytes": 2209,
"sha256": "b08c84f3ea633e7c78dfdad3272f75415f6256cf3614b6d99bfd4f0269076c9b"
},
{
"path": "release1-work/views/diagram_sa_state_view.arcadia",
"bytes": 1931,
"sha256": "5f42f4c605e57b817d8400ed21f2b14bfc4e1592aebe941ff113767504c2b869"
}
]
@@ -0,0 +1,6 @@
{
"scope": "check.py before any oracle process",
"exception": "KeyError: SystemRoot",
"exit": 1,
"correction": "Use case-insensitive Windows environment-key lookup; no fixture or oracle change."
}
@@ -0,0 +1,4 @@
interaction handoff "Assessment handoff" id "9e8f0000-0000-4000-8000-000000000004" {
description "救援 @assess is prose"; source @assess; target @confirm;
// Another comment @assess is excluded.
}
@@ -0,0 +1,8 @@
arcadia 7;
project navigation_trial "Navigation — 救援" id "9e8f0000-0000-4000-8000-000000000001" {
description "Prose @assess must not be a lexical use.";
include "救援/assess.arcadia";
include "救援/confirm.arcadia";
include "links.arcadia";
include "missing/not-loaded.arcadia";
}
@@ -0,0 +1,4 @@
// Comment @assess must not be a lexical use.
oa_activity assess "Assess 救援 request" id "9e8f0000-0000-4000-8000-000000000002" {
description "Keep @assess as prose, not a use.";
}
@@ -0,0 +1 @@
oa_activity confirm "Confirm 救援 response" id "9e8f0000-0000-4000-8000-000000000003" {}
@@ -0,0 +1,14 @@
{
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\staged-source-oracle-20260911\\staged-source-authoring-contract.exe",
"same",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\missing-include-open\\project.arcadia",
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\text-navigation-native-20260911-preparation\\missing-include-open\\project.arcadia"
],
"oracle_sha256": "967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c",
"exit": 101,
"expected_success": false,
"expectation_met": true,
"seconds": 0.030999999999039574,
"finished_utc": "2026-09-11T17:45:35.401779+00:00"
}

Some files were not shown because too many files have changed in this diff Show More