fix(maintenance): v0.19.4 — composer GD-rung tests, layout-key cleanup, carried P3s

Items completed:
1. GD-rung tests (QA P2, verdict 2026-06-11-6f76df1.md P2-1):
   - New ImageComposerEditorTest.php: 7 tests covering wp_get_image_editor WP_Error,
     resize WP_Error, upscale size-mismatch guard, save WP_Error, zero-width geometry
     guard, missing-role guard, and successful OG resize happy path.
   - Orchestrator gd-rung test added to ImageComposerTest.php: forces capability='gd'
     via filter, asserts Imagick renderer is never called, pass-through featured is
     always first.

2. Dead layout keys removed (QA P3, same verdict P3-3):
   - Removed caption_margin_right (og) and caption_side_padding (square) from
     Layout::defaults(). The Imagick renderer never reads them: og text is
     left-anchored from logo_x+logo_w+caption_gap; square text is center-anchored
     at floor(width/2). Right-edge geometry is enforced by caption_chars_per_line.
     Decision: remove (not consume) — no renderer geometry to wire them to.

3. Amortized pv/role (P3 carried, phase-1 thread seq 49 + seq 50):
   - Post_Assembler::amortize_research_costs() SELECT now includes prompt_version
     and agent_role; INSERT carries them forward so amortized llm_research rows are
     no longer stamped with NULL/empty audit fields.

4. fetch_page() error body (P3 carried, phase-1 thread seq 50):
   - Runware_Catalog_Fetcher::fetch_page() non-200 exceptions now include up to
     200 chars of the response body for log-based diagnosis.

5. cto-review.yml isinstance guard: ALREADY FIXED at HEAD (line 454 uses
   c.get("severity", "UNKNOWN")). Noted in CHANGELOG; no code change.

Agent-Session: engineer-prab-maint-20260612
This commit is contained in:
peptiderepo
2026-06-12 12:46:48 +00:00
parent 5c3328dee2
commit b0fde2b686
7 changed files with 313 additions and 7 deletions

View File

@@ -38,6 +38,10 @@ class PRAutoBlogger_Image_Composer_Layout {
* plugin; sizes are px. Values were tuned against rendered samples (see
* PR #thread 2026-06-image-composer assets).
*
* Note: 'caption_margin_right' (og) and 'caption_side_padding' (square) were removed
* in v0.19.4 — the Imagick renderer enforces right-edge geometry via caption_chars_per_line
* and centered x positioning respectively, so those keys had no consumer.
*
* @return array<string, array<string, mixed>> Keyed by role: featured, og, square.
*/
public static function defaults(): array {
@@ -60,7 +64,6 @@ class PRAutoBlogger_Image_Composer_Layout {
'caption_size' => 32,
'caption_color' => '#FFFFFF',
'caption_gap' => 24,
'caption_margin_right' => 40,
'caption_max_lines' => 2,
'caption_chars_per_line' => 52,
'caption_line_height' => 1.3,
@@ -79,7 +82,6 @@ class PRAutoBlogger_Image_Composer_Layout {
'caption_color' => self::COLOR_INK,
'caption_max_lines' => 3,
'caption_chars_per_line' => 36,
'caption_side_padding' => 64,
'caption_line_height' => 1.3,
),
);

View File

@@ -91,7 +91,9 @@ class PRAutoBlogger_Post_Assembler {
* are generated. Its cost is logged with the run_id but no post_id. After all
* articles finish, this method divides the research cost evenly and inserts
* one 'llm_research' row per article so the cost breakdown popover includes
* the amortized research overhead.
* the amortized research overhead. The audit fields prompt_version and
* agent_role are carried from the original research row (v0.19.4 fix;
* prior builds left them NULL/empty — see phase-1 thread seq 49).
*
* Side effects: database SELECT, INSERT, DELETE on generation_log.
*
@@ -158,6 +160,8 @@ class PRAutoBlogger_Post_Assembler {
'estimated_cost' => $amortized_cost,
'response_status' => 'success',
'error_message' => '',
'prompt_version' => $research_row->prompt_version,
'agent_role' => $research_row->agent_role ?? '',
'created_at' => current_time( 'mysql' ),
)
);

View File

@@ -138,7 +138,8 @@ class PRAutoBlogger_Runware_Catalog_Fetcher {
* @param int $offset Pagination offset (0-based).
* @param int $limit Page size.
* @return array{results: array<int, array<string, mixed>>, totalResults: int}
* @throws \RuntimeException On HTTP error or malformed response.
* @throws \RuntimeException On HTTP error or malformed response (non-200 exceptions
* include up to 200 chars of the response body for diagnosis).
*/
private function fetch_page( string $api_key, int $offset, int $limit ): array {
$payload = array(
@@ -171,8 +172,10 @@ class PRAutoBlogger_Runware_Catalog_Fetcher {
$status = (int) wp_remote_retrieve_response_code( $response );
if ( 200 !== $status ) {
$raw_body = (string) wp_remote_retrieve_body( $response );
$body_excerpt = '' !== $raw_body ? ' — body: ' . substr( $raw_body, 0, 200 ) : '';
throw new \RuntimeException(
sprintf( 'Runware modelSearch returned HTTP %d', $status )
sprintf( 'Runware modelSearch returned HTTP %d%s', $status, $body_excerpt )
);
}