@@ -67,11 +67,23 @@ export async function readDescendantSubagentFallbackReply(params: {
6767 entry . endedAt >= params . runStartedAt &&
6868 entry . childSessionKey . trim ( ) . length > 0 ,
6969 )
70- . toSorted ( ( a , b ) => ( b . endedAt ?? 0 ) - ( a . endedAt ?? 0 ) ) ;
70+ . toSorted ( ( a , b ) => {
71+ const diff = ( b . endedAt ?? 0 ) - ( a . endedAt ?? 0 ) ;
72+ // Secondary tie-breaker: when endedAt timestamps are equal, prefer the
73+ // run that was created later (higher createdAt → more recent attempt).
74+ if ( diff !== 0 ) {
75+ return diff ;
76+ }
77+ return ( b . createdAt ?? 0 ) - ( a . createdAt ?? 0 ) ;
78+ } ) ;
7179 if ( descendants . length === 0 ) {
7280 return undefined ;
7381 }
7482
83+ // Build a map of childSessionKey → latest run. Because `descendants` is
84+ // sorted descending by endedAt (with createdAt as tie-breaker), the first
85+ // occurrence for each child key is guaranteed to be the newest run.
86+ // Skipping duplicates via `has()` is therefore correct.
7587 const latestByChild = new Map < string , ( typeof descendants ) [ number ] > ( ) ;
7688 for ( const entry of descendants ) {
7789 const childKey = entry . childSessionKey . trim ( ) ;
@@ -81,9 +93,9 @@ export async function readDescendantSubagentFallbackReply(params: {
8193 latestByChild . set ( childKey , entry ) ;
8294 }
8395
84- const latestRuns = [ ... latestByChild . values ( ) ] . toSorted (
85- ( a , b ) => ( b . endedAt ?? 0 ) - ( a . endedAt ?? 0 ) ,
86- ) ;
96+ // Map preserves insertion order which mirrors the descending endedAt sort
97+ // above, so no additional sort is needed.
98+ const latestRuns = [ ... latestByChild . values ( ) ] ;
8799 for ( const entry of latestRuns ) {
88100 let reply = ( await readLatestAssistantReply ( { sessionKey : entry . childSessionKey } ) ) ?. trim ( ) ;
89101 // Fall back to the registry's frozen result text when the session transcript
@@ -94,6 +106,12 @@ export async function readDescendantSubagentFallbackReply(params: {
94106 if ( ! reply || reply . toUpperCase ( ) === SILENT_REPLY_TOKEN . toUpperCase ( ) ) {
95107 continue ;
96108 }
109+ // Skip interim acknowledgements that don't carry real content — these are
110+ // status messages like "on it" or "working on it" that the subagent emitted
111+ // before producing its actual result.
112+ if ( isLikelyInterimCronMessage ( reply ) ) {
113+ continue ;
114+ }
97115 // Fallback mode should surface the freshest settled descendant result only.
98116 // Older descendant summaries are easily stale/obsolete and can pollute
99117 // current-status reminders when multiple subagents were used in one workflow.
0 commit comments