Skip to content

Commit 8baa8c3

Browse files
committed
fix: aggregate cleanup chunk evidence from job data
1 parent bb6dae9 commit 8baa8c3

2 files changed

Lines changed: 63 additions & 42 deletions

File tree

inc/Cleanup/DataMachineJobCleanupRunEvidenceStore.php

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ public function read( string $run_id, bool $include_evidence = false ): array|\W
2929
return new \WP_Error( 'cleanup_run_not_found', sprintf( 'Cleanup run not found: %s', $this->cleanup_run_id( $job_id ) ), array( 'status' => 404 ) );
3030
}
3131

32-
$engine_data = $this->normalize_engine_data( $job['engine_data'] ?? array() );
33-
$child_jobs = $this->get_cleanup_run_descendant_jobs( $job_id );
34-
$aggregate = $this->aggregate_cleanup_child_jobs( $child_jobs );
35-
$children = $aggregate['children'];
36-
$state = $this->cleanup_run_state( (string) ( $job['status'] ?? '' ), $children );
32+
$engine_data = $this->normalize_engine_data( $job['engine_data'] ?? array() );
33+
$parent_result = $this->extract_system_task_result( $engine_data );
34+
$child_jobs = $this->get_cleanup_run_descendant_jobs( $job_id );
35+
$aggregate = $this->aggregate_cleanup_child_jobs( $child_jobs );
36+
$children = $aggregate['children'];
37+
$state = $this->cleanup_run_state( (string) ( $job['status'] ?? '' ), $children );
3738
$output = array(
3839
'success' => true,
3940
'state' => $state,
@@ -47,8 +48,8 @@ public function read( string $run_id, bool $include_evidence = false ): array|\W
4748
'children' => $children,
4849
);
4950

50-
if ( isset( $engine_data['system_task_result'] ) && is_array( $engine_data['system_task_result'] ) ) {
51-
$engine_data['system_task_result'] = $this->with_cleanup_aggregate_report( $engine_data['system_task_result'], $aggregate );
51+
if ( array() !== $parent_result ) {
52+
$engine_data['system_task_result'] = $this->with_cleanup_aggregate_report( $parent_result, $aggregate );
5253
}
5354

5455
if ( $include_evidence ) {
@@ -121,7 +122,7 @@ private function aggregate_cleanup_child_jobs( array $child_jobs ): array {
121122
$child_job_id = (int) ( $child['job_id'] ?? 0 );
122123
$status = (string) ( $child['status'] ?? '' );
123124
$engine_data = $this->normalize_engine_data( $child['engine_data'] ?? array() );
124-
$result = is_array( $engine_data['system_task_result'] ?? null ) ? $engine_data['system_task_result'] : array();
125+
$result = $this->extract_system_task_result( $engine_data );
125126

126127
++$summary['children']['total'];
127128
if ( $child_job_id > 0 ) {
@@ -145,13 +146,16 @@ private function aggregate_cleanup_child_jobs( array $child_jobs ): array {
145146
if ( 'worktree_cleanup_chunk' !== (string) ( $engine_data['task_type'] ?? '' ) && ! isset( $result['chunk_type'] ) ) {
146147
continue;
147148
}
149+
if ( array() === $result ) {
150+
continue;
151+
}
148152

149153
if ( $child_job_id > 0 ) {
150154
$summary['children']['chunk_job_ids'][] = $child_job_id;
151155
}
152156

153157
$this->merge_cleanup_item_result( $summary['cleanup_items'], $result );
154-
if ( 'artifacts' === (string) ( $result['chunk_type'] ?? '' ) ) {
158+
if ( in_array( (string) ( $result['chunk_type'] ?? '' ), array( 'artifacts', 'artifact_discovery' ), true ) ) {
155159
$this->merge_cleanup_item_result( $summary['artifact_cleanup'], $result );
156160
}
157161
}
@@ -323,6 +327,26 @@ private function normalize_engine_data( mixed $engine_data ): array {
323327
return array();
324328
}
325329

330+
/**
331+
* Extract a task result from either nested packets or direct task engine data.
332+
*
333+
* @param array $engine_data Job engine data.
334+
* @return array<string,mixed>
335+
*/
336+
private function extract_system_task_result( array $engine_data ): array {
337+
if ( isset( $engine_data['system_task_result'] ) && is_array( $engine_data['system_task_result'] ) ) {
338+
return $engine_data['system_task_result'];
339+
}
340+
341+
foreach ( array( 'chunk_type', 'planned_count', 'applied_count', 'skipped_count', 'failed_count', 'bytes_reclaimed', 'report', 'job_backed' ) as $key ) {
342+
if ( array_key_exists( $key, $engine_data ) ) {
343+
return $engine_data;
344+
}
345+
}
346+
347+
return array();
348+
}
349+
326350
/**
327351
* Count a child job status into stable status buckets.
328352
*

tests/smoke-worktree-cleanup-cli.php

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -472,20 +472,18 @@ public function execute( array $input ): array {
472472
'source' => 'system',
473473
'status' => 'completed',
474474
'engine_data' => array(
475-
'task_type' => 'worktree_cleanup_chunk',
476-
'system_task_result' => array(
477-
'success' => true,
478-
'chunk_type' => 'artifacts',
479-
'planned_count' => 3,
480-
'applied_count' => 2,
481-
'skipped_count' => 1,
482-
'failed_count' => 0,
483-
'bytes_reclaimed' => 4096,
484-
'skipped' => array(
485-
array( 'handle' => 'repo@dirty', 'reason_code' => 'dirty_worktree' ),
486-
),
487-
'failed' => array(),
475+
'task_type' => 'worktree_cleanup_chunk',
476+
'success' => true,
477+
'chunk_type' => 'artifact_discovery',
478+
'planned_count' => 3,
479+
'applied_count' => 2,
480+
'skipped_count' => 1,
481+
'failed_count' => 0,
482+
'bytes_reclaimed' => 4096,
483+
'skipped' => array(
484+
array( 'handle' => 'repo@dirty', 'reason_code' => 'dirty_worktree' ),
488485
),
486+
'failed' => array(),
489487
),
490488
),
491489
array(
@@ -494,19 +492,17 @@ public function execute( array $input ): array {
494492
'source' => 'system',
495493
'status' => 'failed - apply_failed',
496494
'engine_data' => array(
497-
'task_type' => 'worktree_cleanup_chunk',
498-
'system_task_result' => array(
499-
'success' => false,
500-
'chunk_type' => 'artifacts',
501-
'planned_count' => 1,
502-
'applied_count' => 0,
503-
'skipped_count' => 0,
504-
'failed_count' => 1,
505-
'bytes_reclaimed' => 0,
506-
'skipped' => array(),
507-
'failed' => array(
508-
array( 'handle' => 'repo@failed', 'reason_code' => 'apply_failed' ),
509-
),
495+
'task_type' => 'worktree_cleanup_chunk',
496+
'success' => false,
497+
'chunk_type' => 'artifacts',
498+
'planned_count' => 1,
499+
'applied_count' => 0,
500+
'skipped_count' => 0,
501+
'failed_count' => 1,
502+
'bytes_reclaimed' => 0,
503+
'skipped' => array(),
504+
'failed' => array(
505+
array( 'handle' => 'repo@failed', 'reason_code' => 'apply_failed' ),
510506
),
511507
),
512508
),
@@ -542,13 +538,11 @@ public function execute( array $input ): array {
542538
'mode' => 'retention',
543539
'source' => 'workspace_cleanup_cli',
544540
),
545-
'system_task_result' => array(
546-
'success' => true,
547-
'job_backed' => true,
548-
'report' => array(
549-
'bytes_reclaimed' => 0,
550-
'freed_human' => 'pending child jobs',
551-
),
541+
'success' => true,
542+
'job_backed' => true,
543+
'report' => array(
544+
'bytes_reclaimed' => 0,
545+
'freed_human' => 'pending child jobs',
552546
),
553547
),
554548
),
@@ -673,6 +667,9 @@ public function execute( array $input ): array {
673667
datamachine_code_cleanup_assert( 4096 === (int) ( $status_json['artifact_cleanup']['bytes_reclaimed'] ?? 0 ), 'cleanup status aggregates artifact bytes from child chunks' );
674668
datamachine_code_cleanup_assert( 4 === (int) ( $status_json['cleanup_items']['planned_rows'] ?? 0 ), 'cleanup status aggregates planned rows from DB-backed cleanup item evidence' );
675669
datamachine_code_cleanup_assert( 4096 === (int) ( $status_json['cleanup_items']['bytes_reclaimed'] ?? 0 ), 'cleanup status reconstructs reclaimed bytes from cleanup item evidence' );
670+
datamachine_code_cleanup_assert( 3 === (int) ( $status_json['cleanup_items']['by_type']['artifact_discovery']['planned_rows'] ?? 0 ), 'cleanup status preserves artifact discovery chunk type aggregation' );
671+
datamachine_code_cleanup_assert( 1 === (int) ( $status_json['cleanup_items']['by_type']['artifacts']['planned_rows'] ?? 0 ), 'cleanup status preserves artifact apply chunk type aggregation' );
672+
datamachine_code_cleanup_assert( ! isset( $status_json['cleanup_items']['by_type']['unknown'] ), 'cleanup status does not aggregate completed chunks under unknown type' );
676673
datamachine_code_cleanup_assert( '4.0 KiB' === ( $status_json['system_task_result']['report']['freed_human'] ?? '' ), 'cleanup status replaces pending child job freed placeholder' );
677674

678675
WP_CLI::$logs = array();

0 commit comments

Comments
 (0)