@@ -577,27 +577,33 @@ private function build_workspace_disk_report(): array {
577577 */
578578 private function summarize_workspace_worktrees ( array $ worktrees , ?array $ cleanup ): array {
579579 $ summary = array (
580- 'total ' => count ($ worktrees ),
581- 'primaries ' => 0 ,
582- 'worktrees ' => 0 ,
583- 'artifacts ' => 0 ,
584- 'external ' => 0 ,
585- 'dirty ' => 0 ,
586- 'protected_dirty ' => 0 ,
587- 'protected_unpushed ' => 0 ,
588- 'missing_metadata ' => 0 ,
589- 'stale_primaries ' => 0 ,
590- 'primary_freshness_by_status ' => array (),
591- 'primary_freshness_attention ' => array (),
592- 'base_branch_worktree_count ' => 0 ,
593- 'base_branch_worktrees ' => array (),
594- 'by_liveness ' => array (
580+ 'total ' => count ($ worktrees ),
581+ 'primaries ' => 0 ,
582+ 'worktrees ' => 0 ,
583+ 'artifacts ' => 0 ,
584+ 'external ' => 0 ,
585+ 'dirty ' => 0 ,
586+ 'inventory_known_dirty ' => 0 ,
587+ 'protected_dirty ' => 0 ,
588+ 'protected_unpushed ' => 0 ,
589+ 'protected_dirty_inventory_known ' => 0 ,
590+ 'protected_unpushed_inventory_known ' => 0 ,
591+ 'protected_dirty_fresh_probed ' => 0 ,
592+ 'protected_unpushed_fresh_probed ' => 0 ,
593+ 'protected_count_probe_source ' => 'none ' ,
594+ 'missing_metadata ' => 0 ,
595+ 'stale_primaries ' => 0 ,
596+ 'primary_freshness_by_status ' => array (),
597+ 'primary_freshness_attention ' => array (),
598+ 'base_branch_worktree_count ' => 0 ,
599+ 'base_branch_worktrees ' => array (),
600+ 'by_liveness ' => array (
595601 WorktreeContextInjector::LIVENESS_LIVE => 0 ,
596602 WorktreeContextInjector::LIVENESS_STOPPED => 0 ,
597603 WorktreeContextInjector::LIVENESS_STALE => 0 ,
598604 WorktreeContextInjector::LIVENESS_UNKNOWN => 0 ,
599605 ),
600- 'duplicate_task_groups ' => 0 ,
606+ 'duplicate_task_groups ' => 0 ,
601607 );
602608
603609 foreach ( $ worktrees as $ row ) {
@@ -632,6 +638,7 @@ private function summarize_workspace_worktrees( array $worktrees, ?array $cleanu
632638
633639 if ( (int ) ( $ row ['dirty ' ] ?? 0 ) > 0 ) {
634640 ++$ summary ['dirty ' ];
641+ ++$ summary ['inventory_known_dirty ' ];
635642 }
636643
637644 if ( ! empty ($ row ['missing_metadata ' ]) ) {
@@ -657,11 +664,23 @@ private function summarize_workspace_worktrees( array $worktrees, ?array $cleanu
657664 $ summary ['duplicates ' ] = $ duplicates ;
658665
659666 if ( null !== $ cleanup ) {
660- $ by_reason = (array ) ( $ cleanup ['summary ' ]['skipped_by_reason ' ] ?? array () );
661- $ summary ['protected_dirty ' ] = (int ) ( $ by_reason ['dirty_worktree ' ] ?? 0 );
662- $ summary ['protected_unpushed ' ] = (int ) ( $ by_reason ['unpushed_commits ' ] ?? 0 );
663- $ summary ['missing_metadata ' ] = (int ) ( $ by_reason ['missing_metadata ' ] ?? 0 );
664- $ summary ['external ' ] = max ($ summary ['external ' ], (int ) ( $ by_reason ['external_worktree ' ] ?? 0 ));
667+ $ by_reason = (array ) ( $ cleanup ['summary ' ]['skipped_by_reason ' ] ?? array () );
668+ $ dirty_blockers = (int ) ( $ by_reason ['dirty_worktree ' ] ?? 0 );
669+ $ unpushed_blockers = (int ) ( $ by_reason ['unpushed_commits ' ] ?? 0 );
670+ $ summary ['protected_dirty ' ] = $ dirty_blockers ;
671+ $ summary ['protected_unpushed ' ] = $ unpushed_blockers ;
672+ $ summary ['missing_metadata ' ] = (int ) ( $ by_reason ['missing_metadata ' ] ?? 0 );
673+ $ summary ['external ' ] = max ($ summary ['external ' ], (int ) ( $ by_reason ['external_worktree ' ] ?? 0 ));
674+
675+ $ probe_source = ! empty ($ cleanup ['inventory_only ' ]) ? 'inventory_known ' : 'fresh_probe ' ;
676+ $ summary ['protected_count_probe_source ' ] = $ probe_source ;
677+ if ( 'fresh_probe ' === $ probe_source ) {
678+ $ summary ['protected_dirty_fresh_probed ' ] = $ dirty_blockers ;
679+ $ summary ['protected_unpushed_fresh_probed ' ] = $ unpushed_blockers ;
680+ } else {
681+ $ summary ['protected_dirty_inventory_known ' ] = $ dirty_blockers ;
682+ $ summary ['protected_unpushed_inventory_known ' ] = $ unpushed_blockers ;
683+ }
665684 }
666685
667686 return $ summary ;
@@ -702,15 +721,32 @@ private function summarize_workspace_cleanup( ?array $cleanup, ?array $error, ar
702721 }
703722 unset($ candidate );
704723 usort ($ candidates , fn ( $ a , $ b ) => (int ) ( $ b ['size_bytes ' ] ?? 0 ) <=> (int ) ( $ a ['size_bytes ' ] ?? 0 ));
724+ $ summary = (array ) ( $ cleanup ['summary ' ] ?? array () );
725+ $ skipped_reason = (array ) ( $ summary ['skipped_by_reason ' ] ?? array () );
726+ $ probe_source = ! empty ($ cleanup ['inventory_only ' ]) ? 'inventory_known ' : 'fresh_probe ' ;
727+ $ empty_blockers = array (
728+ 'dirty_worktree ' => 0 ,
729+ 'unpushed_commits ' => 0 ,
730+ );
731+ $ blocker_counts = array (
732+ 'inventory_known ' => $ empty_blockers ,
733+ 'fresh_probe ' => $ empty_blockers ,
734+ );
735+ $ blocker_counts [ $ probe_source ] = array (
736+ 'dirty_worktree ' => (int ) ( $ skipped_reason ['dirty_worktree ' ] ?? 0 ),
737+ 'unpushed_commits ' => (int ) ( $ skipped_reason ['unpushed_commits ' ] ?? 0 ),
738+ );
705739 return array (
706740 'included ' => true ,
707741 'dry_run ' => true ,
708742 'skip_github ' => true ,
709743 'inventory_only ' => ! empty ($ cleanup ['inventory_only ' ]),
710- 'summary ' => $ cleanup ['summary ' ] ?? array (),
744+ 'blocker_probe_source ' => $ probe_source ,
745+ 'blocker_counts ' => $ blocker_counts ,
746+ 'summary ' => $ summary ,
711747 'biggest_candidates ' => array_slice ($ candidates , 0 , 10 ),
712- 'skipped_by_reason ' => $ cleanup [ ' summary ' ][ ' skipped_by_reason ' ] ?? array () ,
713- 'candidates_by_signal ' => $ cleanup [ ' summary ' ] ['candidates_by_signal ' ] ?? array (),
748+ 'skipped_by_reason ' => $ skipped_reason ,
749+ 'candidates_by_signal ' => $ summary ['candidates_by_signal ' ] ?? array (),
714750 );
715751 }
716752
@@ -732,6 +768,9 @@ private function build_workspace_fast_stats( array $worktrees, ?array $cleanup,
732768 'cleanup_eligible_unprobed_count ' => count ($ cleanup_candidates ),
733769 'valid_clean_count ' => 0 ,
734770 'valid_dirty_count ' => 0 ,
771+ 'inventory_known_dirty_count ' => 0 ,
772+ 'inventory_known_blocker_count ' => 0 ,
773+ 'fresh_probed_blocker_count ' => 0 ,
735774 'invalid_broken_orphan_count ' => 0 ,
736775 'unmanaged_skipped_count ' => 0 ,
737776 'dirty_probe_skipped_count ' => 0 ,
@@ -774,12 +813,18 @@ private function build_workspace_fast_stats( array $worktrees, ?array $cleanup,
774813
775814 if ( (int ) $ dirty > 0 ) {
776815 ++$ counts ['valid_dirty_count ' ];
816+ ++$ counts ['inventory_known_dirty_count ' ];
777817 } else {
778818 ++$ counts ['valid_clean_count ' ];
779819 }
780820 }
781821
782822 $ blocked_dirty = (int ) ( $ cleanup_summary ['skipped_by_reason ' ]['dirty_worktree ' ] ?? 0 ) + (int ) ( $ cleanup_summary ['skipped_by_reason ' ]['unpushed_commits ' ] ?? 0 );
823+ if ( ! empty ($ cleanup ['inventory_only ' ]) ) {
824+ $ counts ['inventory_known_blocker_count ' ] = $ blocked_dirty ;
825+ } else {
826+ $ counts ['fresh_probed_blocker_count ' ] = $ blocked_dirty ;
827+ }
783828 if ( $ blocked_dirty > $ counts ['valid_dirty_count ' ] ) {
784829 $ counts ['valid_dirty_count ' ] = $ blocked_dirty ;
785830 }
0 commit comments