@@ -36,16 +36,7 @@ private function worktree_cleanup_inventory_only( string $older_than, string $so
3636 return $ duration_seconds ;
3737 }
3838
39- $ threshold_ts = time () - $ duration_seconds ;
40- $ age_filter = array (
41- 'type ' => 'older_than ' ,
42- 'older_than ' => $ older_than ,
43- 'duration_seconds ' => $ duration_seconds ,
44- 'threshold ' => gmdate ('c ' , $ threshold_ts ),
45- 'threshold_unix ' => $ threshold_ts ,
46- 'excluded ' => 0 ,
47- 'unknown_age ' => 0 ,
48- );
39+ $ age_filter = WorktreeAgeFilter::build ($ older_than , $ duration_seconds );
4940 }
5041
5142 $ candidates = array ();
@@ -117,56 +108,33 @@ private function worktree_cleanup_inventory_only( string $older_than, string $so
117108 if ( $ include_repaired_metadata && $ repaired ) {
118109 $ age_decision = null ;
119110 if ( null !== $ age_filter ) {
120- $ created_ts = is_string ($ created_at ) && '' !== $ created_at ? strtotime ($ created_at ) : false ;
121- if ( false === $ created_ts ) {
122- ++$ age_filter ['unknown_age ' ];
111+ $ age_decision = WorktreeAgeFilter::decide ($ created_at , $ age_filter );
112+ if ( 'unknown_age ' === $ age_decision ['decision ' ] ) {
123113 $ skipped [] = array_merge (
124- $ base_row , array (
125- 'reason_code ' => 'unknown_age ' ,
126- 'reason ' => 'missing or invalid created_at metadata - age filter cannot decide safely ' ,
127- 'age_filter ' => array (
128- 'type ' => 'older_than ' ,
129- 'older_than ' => $ age_filter ['older_than ' ],
130- 'threshold ' => $ age_filter ['threshold ' ],
131- 'decision ' => 'unknown_age ' ,
132- ),
133- )
114+ $ base_row ,
115+ WorktreeAgeFilter::skip_fields ($ age_decision )
134116 );
135117 continue ;
136118 }
137119
138- $ age_decision = array (
139- 'type ' => 'older_than ' ,
140- 'older_than ' => $ age_filter ['older_than ' ],
141- 'threshold ' => $ age_filter ['threshold ' ],
142- 'created_at ' => $ created_at ,
143- 'age_seconds ' => time () - $ created_ts ,
144- );
145- if ( $ created_ts > $ age_filter ['threshold_unix ' ] ) {
146- ++$ age_filter ['excluded ' ];
120+ if ( 'excluded ' === $ age_decision ['decision ' ] ) {
147121 $ skipped [] = array_merge (
148- $ base_row , array (
149- 'reason_code ' => 'age_filter ' ,
150- 'reason ' => sprintf ('created_at %s is newer than --older-than=%s threshold %s ' , $ created_at , $ age_filter ['older_than ' ], $ age_filter ['threshold ' ]),
151- 'age_filter ' => array_merge ($ age_decision , array ( 'decision ' => 'excluded ' )),
152- )
122+ $ base_row ,
123+ WorktreeAgeFilter::skip_fields ($ age_decision )
153124 );
154125 continue ;
155126 }
156- $ age_decision ['decision ' ] = 'included ' ;
157127 }
158128
129+ $ signal = WorktreeCleanupSignal::from_metadata ($ metadata , true );
159130 $ candidate = array_merge (
160131 $ base_row , array (
161132 'dirty ' => 0 ,
162- 'signal ' => 'repaired_metadata ' ,
163- 'reason_code ' => 'repaired_metadata ' ,
164- 'reason ' => 'operator-approved cleanup of repaired metadata ' ,
165133 'repair_status ' => 'repaired_metadata ' ,
166- )
134+ ), WorktreeCleanupSignal:: candidate_fields ( $ signal ?? array ())
167135 );
168136 if ( null !== $ age_decision ) {
169- $ candidate ['age_filter ' ] = $ age_decision ;
137+ $ candidate ['age_filter ' ] = $ age_decision[ ' age_filter ' ] ;
170138 }
171139 $ candidates [] = $ candidate ;
172140 continue ;
@@ -181,63 +149,36 @@ private function worktree_cleanup_inventory_only( string $older_than, string $so
181149 continue ;
182150 }
183151
152+ $ age_decision = null ;
184153 if ( null !== $ age_filter ) {
185- $ created_ts = is_string ($ created_at ) && '' !== $ created_at ? strtotime ($ created_at ) : false ;
186- if ( false === $ created_ts ) {
187- ++$ age_filter ['unknown_age ' ];
154+ $ age_decision = WorktreeAgeFilter::decide ($ created_at , $ age_filter );
155+ if ( 'unknown_age ' === $ age_decision ['decision ' ] ) {
188156 $ skipped [] = array_merge (
189- $ base_row , array (
190- 'reason_code ' => 'unknown_age ' ,
191- 'reason ' => 'missing or invalid created_at metadata - age filter cannot decide safely ' ,
192- 'age_filter ' => array (
193- 'type ' => 'older_than ' ,
194- 'older_than ' => $ age_filter ['older_than ' ],
195- 'threshold ' => $ age_filter ['threshold ' ],
196- 'decision ' => 'unknown_age ' ,
197- ),
198- )
157+ $ base_row ,
158+ WorktreeAgeFilter::skip_fields ($ age_decision )
199159 );
200160 continue ;
201161 }
202162
203- if ( $ created_ts > $ age_filter ['threshold_unix ' ] ) {
204- ++$ age_filter ['excluded ' ];
163+ if ( 'excluded ' === $ age_decision ['decision ' ] ) {
205164 $ skipped [] = array_merge (
206- $ base_row , array (
207- 'reason_code ' => 'age_filter ' ,
208- 'reason ' => sprintf ('created_at %s is newer than --older-than=%s threshold %s ' , $ created_at , $ age_filter ['older_than ' ], $ age_filter ['threshold ' ]),
209- 'age_filter ' => array (
210- 'type ' => 'older_than ' ,
211- 'older_than ' => $ age_filter ['older_than ' ],
212- 'threshold ' => $ age_filter ['threshold ' ],
213- 'created_at ' => $ created_at ,
214- 'age_seconds ' => time () - $ created_ts ,
215- 'decision ' => 'excluded ' ,
216- ),
217- )
165+ $ base_row ,
166+ WorktreeAgeFilter::skip_fields ($ age_decision )
218167 );
219168 continue ;
220169 }
221170 }
222171
172+ $ signal = WorktreeCleanupSignal::from_metadata ($ metadata );
223173 $ candidate = array_merge (
224- $ base_row , array (
225- 'dirty ' => 0 ,
226- 'signal ' => 'cleanup_eligible ' ,
227- 'reason_code ' => 'cleanup_eligible ' ,
228- 'reason ' => 'worktree finalized or explicitly marked cleanup_eligible ' ,
229- 'pr_url ' => $ metadata ['pr_url ' ] ?? null ,
230- )
174+ $ base_row ,
175+ array (
176+ 'dirty ' => 0 ,
177+ ),
178+ WorktreeCleanupSignal::candidate_fields ($ signal ?? array (), true )
231179 );
232- if ( null !== $ age_filter && is_string ($ created_at ) && '' !== $ created_at ) {
233- $ candidate ['age_filter ' ] = array (
234- 'type ' => 'older_than ' ,
235- 'older_than ' => $ age_filter ['older_than ' ],
236- 'threshold ' => $ age_filter ['threshold ' ],
237- 'created_at ' => $ created_at ,
238- 'age_seconds ' => time () - (int ) strtotime ($ created_at ),
239- 'decision ' => 'included ' ,
240- );
180+ if ( null !== $ age_decision ) {
181+ $ candidate ['age_filter ' ] = $ age_decision ['age_filter ' ];
241182 }
242183
243184 $ candidates [] = $ candidate ;
0 commit comments