@@ -565,29 +565,20 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
565565 }
566566
567567 /**
568- * Validate that all expected entries in the branch were visited.
569- * Throws HistoryDivergedError if there are unvisited entries .
568+ * Validate that every direct entry in this scope was visited. Nested scopes
569+ * validate their own entries when they execute .
570570 */
571571 validateComplete ( ) : void {
572- const prefix = locationToKey ( this . storage , this . currentLocation ) ;
573-
574- for ( const key of this . storage . history . entries . keys ( ) ) {
575- // Check if this key is under our current location prefix
576- // Handle root prefix (empty string) specially - all keys are under root
577- const isUnderPrefix =
578- prefix === ""
579- ? true // Root: all keys are children
580- : key . startsWith ( `${ prefix } /` ) || key === prefix ;
572+ for ( const [ key , entry ] of this . storage . history . entries ) {
573+ const isDirectChild =
574+ entry . location . length === this . currentLocation . length + 1 &&
575+ isLocationPrefix ( this . currentLocation , entry . location ) ;
581576
582- if ( isUnderPrefix ) {
583- if ( ! this . visitedKeys . has ( key ) ) {
584- // Entry exists in history but wasn't visited
585- // This means workflow code may have changed
586- throw new HistoryDivergedError (
587- `Entry "${ key } " exists in history but was not visited. ` +
588- `Workflow code may have changed. Use ctx.removed() to handle migrations.` ,
589- ) ;
590- }
577+ if ( isDirectChild && ! this . visitedKeys . has ( key ) ) {
578+ throw new HistoryDivergedError (
579+ `Entry "${ key } " exists in history but was not visited. ` +
580+ "Workflow code may have changed. Use ctx.removed() to handle migrations." ,
581+ ) ;
591582 }
592583 }
593584 }
@@ -791,6 +782,13 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
791782
792783 // Check for duplicate name in current execution
793784 this . checkDuplicateName ( config . name ) ;
785+ const parentKey = locationToKey ( this . storage , this . currentLocation ) ;
786+ const candidateKey = parentKey
787+ ? `${ parentKey } /${ config . name } `
788+ : config . name ;
789+ if ( ! this . storage . history . entries . has ( candidateKey ) ) {
790+ this . validateComplete ( ) ;
791+ }
794792
795793 const location = appendName (
796794 this . storage ,
@@ -2558,6 +2556,14 @@ export class WorkflowContextImpl implements WorkflowContextInterface {
25582556
25592557 // Mark this entry as visited for validateComplete
25602558 this . markVisited ( key ) ;
2559+ if ( originalType === "message" ) {
2560+ const generatedKeyPrefix = `${ key } :` ;
2561+ for ( const existingKey of this . storage . history . entries . keys ( ) ) {
2562+ if ( existingKey . startsWith ( generatedKeyPrefix ) ) {
2563+ this . markVisited ( existingKey ) ;
2564+ }
2565+ }
2566+ }
25612567
25622568 this . stopRollbackIfMissing ( existing ) ;
25632569
0 commit comments