feat(M3): dossier edit+rerun UI, F2/F3, run-list badges — v0.20.0

- Dossier_Actions (4 AJAX endpoints, manage_options+nonce): save fork /
  queue replay / queue rebuild / stage-status poll. Run identity always
  derived server-side from post meta; the AJAX layer validates + queues
  ONLY — all mutations happen in the cron handlers (chained-cron, CPO
  hard constraint). Fork saves lock message structure (count/roles) so
  every version stays replayable.
- Edit panel per editable stage: per-message textareas prefilled from
  the latest fork or the recorded request_json; explicit fork +
  downstream-stale + queued-execution copy; spend strip with ceiling
  warning (filterable fraction, default 0.8). Disabled stages always
  show WHY (policy reasons; missing-input retention copy).
- Stale / human-edited / attempt chips per stage + header badges (M2
  slot filled); dossier polls stage status while a re-run is active
  (board poll interval setting) and re-renders when the run settles.
- F2: sidebar Models & Prompts card (per-stage model/pv/role) + Run
  Spend card. F3: log-only stages (image_a/b, llm_research, ...) render
  from generation_log + the _prautoblogger_image_role attachment grid.
- M2 correctness: dossier is now item-scoped (idea-hash meta) and
  excludes gen_log rows linked to other posts of a multi-article run.
- Run-list visibility (product AC): board cards get a Human-modified
  chip; Review Queue rows get a stale-stages chip linking to the
  dossier. Both via single batched queries (no N+1).
- v0.20.0 + CHANGELOG + ARCHITECTURE #24 (+ file tree, schema tables,
  db-version note) in this commit per versioning discipline.

Agent-Session: engineer-prab-m3-20260612
This commit is contained in:
peptiderepo
2026-06-12 13:40:27 +00:00
parent 38500b2781
commit 6ed639d1db
30 changed files with 2606 additions and 22 deletions

View File

@@ -103,6 +103,18 @@ $bulk_type = isset( $_GET['prautoblogger_bulk_type'] ) ? sanitize_text_field( wp
</span>
</div>
<?php
// v0.20.0: stale-stage warning chips (one batched query; CPO
// product AC -- the stale flag is visible at publish time).
$rq_post_runs = array();
foreach ( $query->posts as $rq_post ) {
$rq_run_id = (string) get_post_meta( $rq_post->ID, '_prautoblogger_run_id', true );
if ( '' !== $rq_run_id ) {
$rq_post_runs[ $rq_post->ID ] = $rq_run_id;
}
}
$rq_stale_runs = array_flip( PRAutoBlogger_Run_Stage_State::runs_with_stale_stages( array_values( $rq_post_runs ) ) );
?>
<table class="widefat striped prautoblogger-queue-table">
<thead>
<tr>
@@ -137,6 +149,11 @@ $bulk_type = isset( $_GET['prautoblogger_bulk_type'] ) ? sanitize_text_field( wp
</td>
<td>
<strong><?php the_title(); ?></strong>
<?php if ( isset( $rq_post_runs[ $post_id ], $rq_stale_runs[ $rq_post_runs[ $post_id ] ] ) ) : ?>
<a class="prab-review-stale-chip" href="<?php echo esc_url( PRAutoBlogger_Dossier_Page::url_for_post( (int) $post_id ) ); ?>">
<?php esc_html_e( 'Stale stages -- review dossier', 'prautoblogger' ); ?>
</a>
<?php endif; ?>
<?php if ( $editor_notes ) : ?>
<div class="prautoblogger-editor-notes"><?php echo esc_html( $editor_notes ); ?></div>
<?php endif; ?>