@@ -42,11 +42,11 @@ pub enum Error {
4242 /// A `CellId` or `RelationshipId` was not found in the sheet.
4343 InvalidId ,
4444
45- /// No valid method assignment exists (overconstrained).
45+ /// No valid method assignment exists, or staged prerequisite provenance conflicts
46+ /// with the final selected plan.
4647 Conflict {
47- /// A subset-minimal group of relationships that together admit no valid
48- /// method assignment: removing any member of the group makes the remainder
49- /// feasible. Every entry is `ErrorSite::Relationship`.
48+ /// Relationships, methods, and cells involved in an impossible assignment or
49+ /// an incompatible staged prerequisite reuse.
5050 sites : Vec < ErrorSite > ,
5151 } ,
5252
@@ -59,6 +59,15 @@ pub enum Error {
5959 sites : Vec < ErrorSite > ,
6060 } ,
6161
62+ /// The seed dependency graph contains a non-self cycle.
63+ SeedCycle {
64+ /// The cycle's members in deterministic traversal order, starting at the first
65+ /// revisited `Cell` and alternating through the sibling `Relationship`s that
66+ /// force the cycle. The closing relationship appears last; the starting cell is
67+ /// not repeated at the end.
68+ sites : Vec < ErrorSite > ,
69+ } ,
70+
6271 /// A method's function returned an error during execution.
6372 MethodFailed {
6473 /// The underlying error the method's function (or a requirement's/conditional's
@@ -91,13 +100,14 @@ pub enum Error {
91100 } ,
92101
93102 /// A method's own `outputs` list names a cell more than once, or two methods in
94- /// the same relationship have identical `outputs` sets.
95- DuplicateMethodOutputs {
103+ /// the same relationship have identical or nested `outputs` sets. Overlapping
104+ /// output sets are allowed when neither set nests the other.
105+ InvalidMethodOutputs {
96106 /// `sites[0]` is the method (by index within the `Vec` passed to
97107 /// `add_relationship`) whose output set collided. For a method's own outputs
98108 /// repeating a cell, further entries are the repeated cell(s). For two methods
99- /// sharing an output set , `sites[1]` is the earlier method's index and further
100- /// entries are the shared output cell(s).
109+ /// with identical or nested output sets , `sites[1]` is the earlier method's
110+ /// index and further entries are the duplicate or nested subset cell(s).
101111 sites : Vec < ErrorSite > ,
102112 } ,
103113
@@ -169,16 +179,17 @@ impl std::fmt::Display for Error {
169179 Error :: InvalidId => write ! ( f, "invalid cell or relationship id" ) ,
170180 Error :: Conflict { .. } => write ! ( f, "no valid method assignment (overconstrained)" ) ,
171181 Error :: Cycle { .. } => write ! ( f, "selected methods form a cycle" ) ,
182+ Error :: SeedCycle { .. } => write ! ( f, "seed dependency cycle" ) ,
172183 Error :: MethodFailed { error, .. } => write ! ( f, "method execution failed: {error}" ) ,
173184 Error :: InvalidMethod { .. } => write ! ( f, "method is structurally invalid" ) ,
174185 Error :: MismatchedMethodCells { .. } => write ! (
175186 f,
176187 "methods in a relationship must reference the same set of cells"
177188 ) ,
178- Error :: DuplicateMethodOutputs { .. } => write ! (
189+ Error :: InvalidMethodOutputs { .. } => write ! (
179190 f,
180191 "a method's outputs must be duplicate-free, and no two methods in a \
181- relationship may share an outputs set "
192+ relationship may have identical or nested output sets "
182193 ) ,
183194 Error :: InvalidConditional { .. } => write ! ( f, "conditional is structurally invalid" ) ,
184195 Error :: InvalidOutput => write ! ( f, "output is structurally invalid" ) ,
@@ -218,10 +229,11 @@ impl Error {
218229 | Error :: MethodFailed { sites, .. }
219230 | Error :: InvalidMethod { sites }
220231 | Error :: MismatchedMethodCells { sites }
221- | Error :: DuplicateMethodOutputs { sites }
232+ | Error :: InvalidMethodOutputs { sites }
222233 | Error :: InvalidCellKind { sites }
223234 | Error :: Conflict { sites }
224235 | Error :: Cycle { sites }
236+ | Error :: SeedCycle { sites }
225237 | Error :: DependencyCycle { sites }
226238 | Error :: InvalidConditional { sites } => sites,
227239 _ => & [ ] ,
@@ -324,6 +336,7 @@ mod tests {
324336 assert ! ( std:: error:: Error :: source( & Error :: InvalidId ) . is_none( ) ) ;
325337 assert ! ( std:: error:: Error :: source( & Error :: Conflict { sites: vec![ ] } ) . is_none( ) ) ;
326338 assert ! ( std:: error:: Error :: source( & Error :: Cycle { sites: vec![ ] } ) . is_none( ) ) ;
339+ assert ! ( std:: error:: Error :: source( & Error :: SeedCycle { sites: vec![ ] } ) . is_none( ) ) ;
327340 assert ! ( std:: error:: Error :: source( & Error :: InvalidMethod { sites: vec![ ] } ) . is_none( ) ) ;
328341 assert ! (
329342 std:: error:: Error :: source( & Error :: TypeMismatch {
@@ -337,7 +350,7 @@ mod tests {
337350 std:: error:: Error :: source( & Error :: MismatchedMethodCells { sites: vec![ ] } ) . is_none( )
338351 ) ;
339352 assert ! (
340- std:: error:: Error :: source( & Error :: DuplicateMethodOutputs { sites: vec![ ] } ) . is_none( )
353+ std:: error:: Error :: source( & Error :: InvalidMethodOutputs { sites: vec![ ] } ) . is_none( )
341354 ) ;
342355 }
343356
@@ -365,9 +378,9 @@ mod tests {
365378 }
366379
367380 #[ test]
368- fn duplicate_method_outputs_display_contains_outputs ( ) {
381+ fn invalid_method_outputs_display_contains_outputs ( ) {
369382 assert ! (
370- Error :: DuplicateMethodOutputs { sites: vec![ ] }
383+ Error :: InvalidMethodOutputs { sites: vec![ ] }
371384 . to_string( )
372385 . contains( "outputs" )
373386 ) ;
@@ -442,6 +455,15 @@ mod tests {
442455 ) ;
443456 }
444457
458+ #[ test]
459+ fn seed_cycle_display_mentions_seed_dependency_cycle ( ) {
460+ assert ! (
461+ Error :: SeedCycle { sites: vec![ ] }
462+ . to_string( )
463+ . contains( "seed dependency cycle" )
464+ ) ;
465+ }
466+
445467 #[ test]
446468 fn dependency_cycle_has_no_source ( ) {
447469 assert ! ( std:: error:: Error :: source( & Error :: DependencyCycle { sites: vec![ ] } ) . is_none( ) ) ;
@@ -454,6 +476,13 @@ mod tests {
454476 assert_eq ! ( e. sites( ) , & [ site] ) ;
455477 }
456478
479+ #[ test]
480+ fn seed_cycle_exposes_its_sites ( ) {
481+ let site = ErrorSite :: Cell ( CellId :: default ( ) ) ;
482+ let e = Error :: SeedCycle { sites : vec ! [ site] } ;
483+ assert_eq ! ( e. sites( ) , & [ site] ) ;
484+ }
485+
457486 #[ test]
458487 fn error_site_variants_are_distinct ( ) {
459488 let a = ErrorSite :: MethodIndex ( 0 ) ;
0 commit comments