@@ -6951,6 +6951,7 @@ private function build_active_no_signal_evidence_row( array $row, array &$github
69516951 'default_ref ' => null ,
69526952 'commits_outside_default ' => null ,
69536953 'upstream_equivalence ' => null ,
6954+ 'probe_timings_ms ' => array (),
69546955 'suggested_action ' => 'insufficient_signal ' ,
69556956 'reason ' => 'not enough evidence gathered ' ,
69566957 );
@@ -6961,44 +6962,44 @@ private function build_active_no_signal_evidence_row( array $row, array &$github
69616962 return $ out ;
69626963 }
69636964
6964- $ dirty = $ this ->probe_worktree_dirty_count ( $ path , self ::CLEANUP_GIT_PROBE_TIMEOUT );
6965+ $ dirty = $ this ->time_worktree_probe ( $ out [ ' probe_timings_ms ' ], ' dirty_count ' , fn () => $ this -> probe_worktree_dirty_count ( $ path , self ::CLEANUP_GIT_PROBE_TIMEOUT ) );
69656966 if ( is_wp_error ( $ dirty ) ) {
69666967 $ out ['dirty_error ' ] = $ dirty ->get_error_message ();
69676968 } else {
69686969 $ out ['dirty ' ] = (int ) $ dirty ;
69696970 }
69706971
6971- $ unpushed = $ this ->count_unpushed_commits ( $ path , self ::CLEANUP_GIT_PROBE_TIMEOUT );
6972+ $ unpushed = $ this ->time_worktree_probe ( $ out [ ' probe_timings_ms ' ], ' unpushed_count ' , fn () => $ this -> count_unpushed_commits ( $ path , self ::CLEANUP_GIT_PROBE_TIMEOUT ) );
69726973 if ( is_wp_error ( $ unpushed ) ) {
69736974 $ out ['unpushed_error ' ] = $ unpushed ->get_error_message ();
69746975 } else {
69756976 $ out ['unpushed ' ] = (int ) $ unpushed ;
69766977 }
69776978
69786979 $ remote_ref = 'refs/remotes/origin/ ' . $ branch ;
6979- $ remote = $ this ->run_git ( $ primary_path , sprintf ( 'rev-parse --verify --quiet %s ' , escapeshellarg ( $ remote_ref ) ), self ::CLEANUP_GIT_PROBE_TIMEOUT );
6980+ $ remote = $ this ->time_worktree_probe ( $ out [ ' probe_timings_ms ' ], ' remote_tracking ' , fn () => $ this -> run_git ( $ primary_path , sprintf ( 'rev-parse --verify --quiet %s ' , escapeshellarg ( $ remote_ref ) ), self ::CLEANUP_GIT_PROBE_TIMEOUT ) );
69806981 $ out ['remote_tracking ' ] = ! is_wp_error ( $ remote ) && ! $ this ->is_git_timeout_error ( $ remote );
69816982
6982- $ default_ref = $ this ->resolve_remote_default_ref ( $ primary_path , self ::CLEANUP_GIT_PROBE_TIMEOUT );
6983+ $ default_ref = $ this ->time_worktree_probe ( $ out [ ' probe_timings_ms ' ], ' default_ref ' , fn () => $ this -> resolve_remote_default_ref ( $ primary_path , self ::CLEANUP_GIT_PROBE_TIMEOUT ) );
69836984 if ( is_string ( $ default_ref ) && '' !== $ default_ref ) {
69846985 $ out ['default_ref ' ] = $ default_ref ;
6985- $ outside = $ this ->run_git (
6986+ $ outside = $ this ->time_worktree_probe ( $ out [ ' probe_timings_ms ' ], ' commits_outside_default ' , fn () => $ this -> run_git (
69866987 $ primary_path ,
69876988 sprintf ( 'rev-list --count %s..%s ' , escapeshellarg ( $ default_ref ), escapeshellarg ( 'refs/heads/ ' . $ branch ) ),
69886989 self ::CLEANUP_GIT_PROBE_TIMEOUT
6989- );
6990+ ) ) ;
69906991 if ( ! is_wp_error ( $ outside ) && ! $ this ->is_git_timeout_error ( $ outside ) ) {
69916992 $ out ['commits_outside_default ' ] = (int ) trim ( (string ) ( $ outside ['output ' ] ?? '' ) );
69926993 }
69936994
69946995 if ( (int ) ( $ out ['dirty ' ] ?? 0 ) > 0 || (int ) ( $ out ['unpushed ' ] ?? 0 ) > 0 ) {
6995- $ out ['upstream_equivalence ' ] = $ this ->build_dirty_unpushed_upstream_equivalence_evidence ( $ primary_path , $ path , $ default_ref );
6996+ $ out ['upstream_equivalence ' ] = $ this ->time_worktree_probe ( $ out [ ' probe_timings_ms ' ], ' upstream_equivalence ' , fn () => $ this -> build_dirty_unpushed_upstream_equivalence_evidence ( $ primary_path , $ path , $ default_ref ) );
69966997 }
69976998 }
69986999
6999- $ slug = $ this ->resolve_github_slug ( $ primary_path );
7000+ $ slug = $ this ->time_worktree_probe ( $ out [ ' probe_timings_ms ' ], ' github_slug ' , fn () => $ this -> resolve_github_slug ( $ primary_path ) );
70007001 if ( null !== $ slug ) {
7001- $ pr = $ this ->find_pr_for_branch_direct ( $ slug , $ branch , $ github_cache , false );
7002+ $ pr = $ this ->time_worktree_probe ( $ out [ ' probe_timings_ms ' ], ' github_pr_lookup ' , fn () => $ this -> find_pr_for_branch_direct ( $ slug , $ branch , $ github_cache , false ) );
70027003 if ( is_wp_error ( $ pr ) ) {
70037004 $ out ['pr_error ' ] = $ pr ->get_error_message ();
70047005 } elseif ( is_array ( $ pr ) ) {
@@ -7012,6 +7013,21 @@ private function build_active_no_signal_evidence_row( array $row, array &$github
70127013 return $ out ;
70137014 }
70147015
7016+ /**
7017+ * Time one worktree probe and record elapsed milliseconds by label.
7018+ *
7019+ * @param array<string,int> $timings Timing accumulator.
7020+ * @param string $label Probe label.
7021+ * @param callable $callback Probe callback.
7022+ * @return mixed
7023+ */
7024+ private function time_worktree_probe ( array &$ timings , string $ label , callable $ callback ): mixed {
7025+ $ started = microtime ( true );
7026+ $ result = $ callback ();
7027+ $ timings [ $ label ] = (int ) round ( ( microtime ( true ) - $ started ) * 1000 );
7028+ return $ result ;
7029+ }
7030+
70157031 /**
70167032 * Build diagnostic evidence for dirty/unpushed worktrees against remote default.
70177033 *
@@ -7049,9 +7065,10 @@ private function build_dirty_unpushed_upstream_equivalence_evidence( string $pri
70497065 'unknown ' => 0 ,
70507066 'samples ' => array (),
70517067 ),
7068+ 'probe_timings_ms ' => array (),
70527069 );
70537070
7054- $ cherry = $ this ->run_git ( $ wt_path , sprintf ( 'cherry %s HEAD ' , escapeshellarg ( $ default_ref ) ), self ::CLEANUP_GIT_PROBE_TIMEOUT );
7071+ $ cherry = $ this ->time_worktree_probe ( $ evidence [ ' probe_timings_ms ' ], ' git_cherry ' , fn () => $ this -> run_git ( $ wt_path , sprintf ( 'cherry %s HEAD ' , escapeshellarg ( $ default_ref ) ), self ::CLEANUP_GIT_PROBE_TIMEOUT ) );
70557072 if ( ! is_wp_error ( $ cherry ) && ! $ this ->is_git_timeout_error ( $ cherry ) ) {
70567073 $ lines = array_values ( array_filter ( array_map ( 'trim ' , explode ( "\n" , (string ) ( $ cherry ['output ' ] ?? '' ) ) ) ) );
70577074 foreach ( $ lines as $ line ) {
@@ -7066,13 +7083,13 @@ private function build_dirty_unpushed_upstream_equivalence_evidence( string $pri
70667083 $ evidence ['unpushed_patch_equivalent ' ] = 0 === (int ) $ evidence ['unpushed_cherry ' ]['unmatched ' ] && 0 === (int ) $ evidence ['unpushed_cherry ' ]['unknown ' ];
70677084 }
70687085
7069- $ tracked = $ this ->run_git ( $ wt_path , 'diff --name-only HEAD ' , self ::CLEANUP_GIT_PROBE_TIMEOUT );
7086+ $ tracked = $ this ->time_worktree_probe ( $ evidence [ ' probe_timings_ms ' ], ' tracked_dirty_paths ' , fn () => $ this -> run_git ( $ wt_path , 'diff --name-only HEAD ' , self ::CLEANUP_GIT_PROBE_TIMEOUT ) );
70707087 $ paths = array ();
70717088 if ( ! is_wp_error ( $ tracked ) && ! $ this ->is_git_timeout_error ( $ tracked ) ) {
70727089 $ paths = array_merge ( $ paths , array_values ( array_filter ( array_map ( 'trim ' , explode ( "\n" , (string ) ( $ tracked ['output ' ] ?? '' ) ) ) ) ) );
70737090 }
70747091
7075- $ untracked = $ this ->run_git ( $ wt_path , 'ls-files --others --exclude-standard ' , self ::CLEANUP_GIT_PROBE_TIMEOUT );
7092+ $ untracked = $ this ->time_worktree_probe ( $ evidence [ ' probe_timings_ms ' ], ' untracked_paths ' , fn () => $ this -> run_git ( $ wt_path , 'ls-files --others --exclude-standard ' , self ::CLEANUP_GIT_PROBE_TIMEOUT ) );
70767093 if ( ! is_wp_error ( $ untracked ) && ! $ this ->is_git_timeout_error ( $ untracked ) ) {
70777094 foreach ( array_values ( array_filter ( array_map ( 'trim ' , explode ( "\n" , (string ) ( $ untracked ['output ' ] ?? '' ) ) ) ) ) as $ path ) {
70787095 $ paths [] = $ path ;
@@ -7086,6 +7103,7 @@ private function build_dirty_unpushed_upstream_equivalence_evidence( string $pri
70867103 $ evidence ['dirty_paths ' ]['inspected ' ] = count ( $ inspect_paths );
70877104 $ evidence ['path_inspection_truncated ' ] = count ( $ paths ) > count ( $ inspect_paths );
70887105
7106+ $ classification_started = microtime ( true );
70897107 foreach ( $ inspect_paths as $ path ) {
70907108 $ classification = $ this ->classify_dirty_path_against_default ( $ primary_path , $ wt_path , $ default_ref , $ path );
70917109 $ bucket = $ classification ['bucket ' ];
@@ -7104,6 +7122,7 @@ private function build_dirty_unpushed_upstream_equivalence_evidence( string $pri
71047122 $ evidence ['dirty_paths ' ]['samples ' ][] = $ classification ;
71057123 }
71067124 }
7125+ $ evidence ['probe_timings_ms ' ]['dirty_path_classification ' ] = (int ) round ( ( microtime ( true ) - $ classification_started ) * 1000 );
71077126
71087127 $ evidence ['effective_status ' ] = $ this ->classify_dirty_unpushed_effective_status ( $ evidence );
71097128
0 commit comments