Files
wp-agentic-writer/docs/architecture/PLUGIN_AUDIT_RETRACE_TWELFTH_PASS_2026-05-26.md

12 KiB

WP Agentic Writer Twelfth Retrace Audit

Audit date: 2026-05-26
Baseline retraced: docs/architecture/PLUGIN_AUDIT_RETRACE_ELEVENTH_PASS_2026-05-26.md
Scope: twelfth pass after eleventh-retrace implementation, covering chat/context continuity, provider transparency, model registry adoption, cost attribution, UI/UX readiness, and release verification.
Status: COMPLETE / RETRACED
Completion marker: 2026-05-26
Follow-up retrace: docs/architecture/PLUGIN_AUDIT_RETRACE_THIRTEENTH_PASS_2026-05-26.md

This twelfth-pass report has been implemented and retraced. Keep this document as historical evidence only; use the thirteenth-pass report for current remaining work.

Executive Summary

The eleventh-pass implementation closed several meaningful items:

  • The sidebar now uses the canonical /conversation/{post_id} endpoint instead of the deprecated /chat-history/{post_id} endpoint.
  • applyProviderMetadata() is now called from many previously missed frontend paths, including meta generation, summarization, intent detection, reformat blocks, and refine-from-chat completion.
  • Model registry adoption is broader: Settings V2 fallback labels/defaults, OpenRouter constructor defaults, and image manager defaults now draw from WPAW_Model_Registry.
  • PHP and JavaScript syntax checks pass.

No new P0 blocker was found.

The remaining risk is narrower, but one new regression-class issue appeared during retrace: moving the sidebar to /conversation bypasses the legacy chat migration path that still lives under the deprecated chat-history compatibility method. That can make old post-meta chat history disappear from the editor UI for legacy posts that have not yet been migrated into conversation sessions.

Verification Performed

  • PHP syntax check across plugin PHP files: passed.
  • node -c assets/js/sidebar.js: passed.
  • node -c assets/js/settings-v2.js: passed.
  • node -c assets/js/sidebar-utils.js: passed.
  • Static retrace of eleventh-pass findings against current code.
  • Static sweep of provider metadata coverage, model registry usage, chat/context hydration, cost hook contracts, and stale compatibility code.
  • No live WordPress editor/browser workflow was run in this pass.

Eleventh-Pass Status Trace

Eleventh-pass item Current status Evidence
Sidebar still used deprecated /chat-history Fixed in active sidebar assets/js/sidebar.js:673 now fetches /conversation/${postId}.
Provider metadata missing in meta/summarize/intent/reformat/refine paths Mostly fixed applyProviderMetadata() is now called at assets/js/sidebar.js:596, 1603, 1647, 2195, and 2836.
Model registry not adopted in Settings V2 fallbacks/OpenRouter/image defaults Improved Settings V2 and provider/image defaults now use registry-backed defaults; residual hard-coded presets remain.
Raw cost hook drift Still open Direct do_action( 'wp_aw_after_api_request', ... ) calls remain, including seven-argument calls that lose provider attribution.
Browser verification Still open Syntax checks passed, but live editor workflows were not verified.

Remaining Findings

P1: Canonical /conversation Endpoint Bypasses Legacy Chat Migration

The active sidebar moved to the canonical endpoint:

  • assets/js/sidebar.js:673 fetches /conversation/${postId}.

However, the canonical backend handler only reads an existing conversation session:

  • includes/class-gutenberg-sidebar.php:1408-1418 calls get_session_by_post_id() and returns an empty message list when no session exists.
  • includes/class-conversation-manager.php:200-218 returns null when no active session is found.

The legacy migration behavior still exists, but only in the deprecated compatibility path:

  • includes/class-gutenberg-sidebar.php:1479-1492 reads _wpaw_chat_history, calls migrate_legacy_chat_history(), and returns migrated messages.

Impact:

  • Legacy posts that still have _wpaw_chat_history but no conversation session can now hydrate as empty in the sidebar.
  • This can look like conversation loss after the eleventh-pass fix, even though the data still exists in post meta.
  • The deprecated endpoint has the safer migrate-on-read behavior, while the canonical endpoint does not.

Recommended fix:

  • Make handle_get_conversation_by_post() use the same migrate-on-read behavior when no session exists and _wpaw_chat_history is present.
  • Return the migrated session_id, post_id, has_session: true, and messages after migration.
  • Add a regression test or fixture for a post with only _wpaw_chat_history and no wpaw_conversations row.

P1: Cost Ledger Still Loses Provider Attribution For Some AI Actions

The centralized track_ai_cost() helper exists, but some AI actions still use the raw hook with the old seven-argument shape.

Examples:

  • includes/class-keyword-suggester.php:32-34 obtains a provider result, but includes/class-keyword-suggester.php:121-129 fires wp_aw_after_api_request without provider, session, or status arguments.
  • includes/class-gutenberg-sidebar.php:6862-6864 obtains the provider for improvement analysis, but includes/class-gutenberg-sidebar.php:6871-6879 also fires a seven-argument cost hook.
  • includes/class-cost-tracker.php:50 registers the listener with nine accepted arguments, so omitted provider fields fall back to unknown.

Impact:

  • Cost rows for keyword suggestions and improvement suggestions can under-report provider and fallback status.
  • Provider/cost dashboards can show unknown for actions where provider metadata was actually available.
  • This weakens the new provider transparency work because the UI response and ledger do not always agree.

Recommended fix:

  • Replace these raw hook calls with track_ai_cost() or a shared public cost helper.
  • Where the helper is not accessible, pass the full nine-argument hook contract, including provider result, session id when available, and status.
  • Add a static check for seven-argument wp_aw_after_api_request calls.

P2: Provider Metadata UI Coverage Is Much Better, But Not Exhaustive

The eleventh-pass implementation fixed the major previously listed misses:

  • Meta generation calls applyProviderMetadata(data) at assets/js/sidebar.js:596.
  • Summarization calls it at assets/js/sidebar.js:1603.
  • Intent detection calls it at assets/js/sidebar.js:1647.
  • Reformat blocks calls it at assets/js/sidebar.js:2195.
  • Refine-from-chat completion calls it at assets/js/sidebar.js:2836.

Remaining missed or duplicate paths:

  • One stream completion branch at assets/js/sidebar.js:3697-3710 emits a completion payload with totalCost only, so the frontend has no provider metadata to apply.
  • Another completion handler at assets/js/sidebar.js:3930-3945 updates cost/timeline without applying provider metadata.
  • The clarity check path at assets/js/sidebar.js:4818-4825 parses clarityData but does not apply provider metadata from the response.

Impact:

  • The provider badge is now reliable for many common flows, but can still remain stale after some generation or clarity workflows.
  • Users may see correct cost movement while the provider/fallback display still reflects a previous request.

Recommended fix:

  • Ensure every backend AI response and stream completion payload includes provider_metadata when a provider was involved.
  • Call applyProviderMetadata(data) immediately after every AI JSON response parse and every stream complete event that can carry metadata.
  • For endpoints intentionally without provider metadata, document that in code next to the parse/complete branch.

P2: Model Registry Still Has Residual Hard-Coded Defaults And Presets

Registry adoption is now strong in the active PHP defaults, but not complete:

  • assets/js/settings-v2.js:32-58 still defines budget/balanced/premium presets with hard-coded model IDs.
  • includes/class-settings.php:72-78, 98-117, 138-140, 197, and 1029-1049 still contain legacy settings defaults and presets with hard-coded model IDs.
  • wp-agentic-writer.php:100-104 can still instantiate the legacy settings class if Settings V2 is unavailable.

Some hard-coded model strings are acceptable when they are display labels, compatibility checks, pricing keys, or provider-specific suggestions. The remaining concern is default/preset ownership.

Impact:

  • The registry is not yet the only source of model defaults users can activate.
  • JS presets and legacy settings can drift from the PHP registry.
  • Future model migrations still require edits in more than one place.

Recommended fix:

  • Localize presets from WPAW_Model_Registry::get_frontend_data() or add explicit registry preset support.
  • Either retire the legacy WP_Agentic_Writer_Settings path or make it read registry defaults.
  • Keep provider suggestion maps and pricing tables separate, but name them as suggestions/pricing rather than defaults.

P2: Live Browser Verification Is Still The Final Release Gate

Static checks passed, but the plugin still needs a live editor pass before calling the audit chain fully complete.

Manual verification should cover:

  • Sidebar opens in the block editor and survives page reload.
  • Existing legacy post-meta chat history migrates and appears through /conversation/{post_id}.
  • New chat messages persist, reload, and retain session id continuity.
  • Provider/fallback badges update after chat, clarity, planning, generation, refinement, summarize, reformat, meta, keyword, and improvement actions.
  • Cost totals update in the UI and cost ledger with provider/session/status fields populated.
  • Model setting changes affect generated requests and visible provider metadata.
  • Unauthorized REST access remains denied.

P3: Stale Compatibility Comments And Backup Files Can Create Audit Noise

The deprecated chat-history docblock is now stale:

  • includes/class-gutenberg-sidebar.php:1349-1350 says the endpoint does not use the conversations table, but the implementation delegates through conversation/session migration behavior.

Also, backup JavaScript files still reference old endpoint behavior:

  • assets/js/sidebar.js.backup
  • assets/js/sidebar.js.bak

Impact:

  • Future retraces can mistake backup files or stale comments for active behavior.
  • If backup files are accidentally packaged, old endpoint usage can leak into distribution artifacts.

Recommended fix:

  • Update the deprecated endpoint docblock to describe the actual compatibility behavior.
  • Exclude backup files from packaging or remove them after confirming they are not needed.

Priority Queue

  1. P1: Add migrate-on-read behavior to /conversation/{post_id} for legacy _wpaw_chat_history.
  2. P1: Fix seven-argument cost hooks for keyword and improvement suggestions so provider attribution is preserved.
  3. P2: Finish provider metadata propagation for remaining stream completion and clarity branches.
  4. P2: Move active JS presets and legacy settings defaults under the model registry, or explicitly retire/de-scope legacy settings.
  5. P2: Run live WordPress editor browser verification.
  6. P3: Clean stale chat-history comments and backup endpoint references.

Completion Criteria For Next Pass

The next retrace can mark this pass complete when:

  • /conversation/{post_id} migrates legacy chat history when no session exists.
  • Keyword and improvement suggestion cost rows include provider, fallback, session/status where available.
  • Provider metadata is applied or explicitly de-scoped for every AI response path.
  • Remaining model preset/default ownership is either centralized in the registry or documented as intentional.
  • A live editor verification note exists with the exact workflows checked.