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

9.5 KiB

WP Agentic Writer Eleventh Retrace Audit

Audit date: 2026-05-26
Baseline retraced: docs/architecture/PLUGIN_AUDIT_RETRACE_TENTH_PASS_2026-05-26.md
Scope: eleventh pass after tenth-retrace implementation, covering provider transparency coverage, model registry adoption, chat/context compatibility, cost tracking contracts, UI/UX, and release readiness. Status: COMPLETE / RETRACED
Completion marker: 2026-05-26
Follow-up retrace: docs/architecture/PLUGIN_AUDIT_RETRACE_TWELFTH_PASS_2026-05-26.md

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

Executive Summary

The tenth-pass implementation improved the plugin again:

  • A shared frontend applyProviderMetadata() helper now exists.
  • Several AI response paths call that helper, so provider/fallback metadata reaches the UI in more than just the original stream completion path.
  • The P0 failed-attempt fatal from the ninth pass remains fixed.
  • PHP and JavaScript syntax checks pass.

No new P0 blocker was found. The remaining issues are now narrower, but still real:

  • Provider metadata UI coverage is broader, but still not complete across all AI response paths.
  • Model registry adoption is improved, but some active and fallback paths still carry hard-coded model IDs.
  • The sidebar still hydrates chat through deprecated /chat-history.
  • Raw cost hook calls still bypass the track_ai_cost() helper in many places.
  • Live WordPress editor browser verification is still pending.

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 tenth-pass findings against current code.
  • Static sweep of provider metadata UI usage, model registry adoption, chat-history usage, and raw cost hooks.
  • No live WordPress editor/browser workflow was run in this pass.

Tenth-Pass Status Trace

Tenth-pass item Current status Evidence
Shared frontend provider metadata helper Fixed applyProviderMetadata() exists at assets/js/sidebar.js:75-91.
Provider metadata UI coverage Improved, still partial Helper is called at assets/js/sidebar.js:1043, 1772, 1995, 2281, and 3349, but some AI response paths still do not call it.
Provider badge rendering Fixed for covered paths Provider/fallback badge renders near cost at assets/js/sidebar.js:4677-4720.
Model registry adoption Improved, still partial Active settings/sidebar paths use WPAW_Model_Registry, but fallback model lists, JS presets, provider property defaults, and some image paths still hard-code model IDs.
Sidebar /chat-history dependency Still open assets/js/sidebar.js:666-680 still fetches /chat-history/${postId}.
/chat-history docblock mismatch Still open Docblock still says the endpoint does not use the conversations table at includes/class-gutenberg-sidebar.php:1337-1339.
Raw cost hook drift Still open Direct do_action( 'wp_aw_after_api_request', ... ) calls remain in includes/class-gutenberg-sidebar.php outside track_ai_cost().
Browser verification Still open Syntax checks passed, but no live editor workflow was verified.

Remaining Findings

P1: Provider Metadata UI Coverage Is Still Partial

The new frontend helper is good:

  • applyProviderMetadata() supports both provider_metadata and top-level provider fields at assets/js/sidebar.js:75-91.
  • It is called from several important paths, including streaming completion and some JSON responses at assets/js/sidebar.js:1043, 1772, 1995, 2281, and 3349.
  • The provider/fallback badge is rendered at assets/js/sidebar.js:4677-4720.

However, not every AI response path applies provider metadata yet. Examples:

  • Meta generation parses JSON at assets/js/sidebar.js:595-605 but does not call applyProviderMetadata().
  • Summarize context parses JSON at assets/js/sidebar.js:1601-1612 but does not call it.
  • Intent detection parses JSON at assets/js/sidebar.js:1644-1648 but does not call it.
  • Reformat blocks parses JSON at assets/js/sidebar.js:2191-2219 but does not call it.
  • Refine-from-chat streaming parses data events at assets/js/sidebar.js:2771-2828 but does not apply metadata on completion.

Impact:

  • The provider badge can be stale after some AI actions.
  • Users may see provider information for generation/chat but not for meta, summarization, intent, reformat, or refinement workflows.
  • This still falls short of a consistent provider transparency contract.

Recommended fix:

  • Call applyProviderMetadata(data) immediately after every AI JSON response parse.
  • Call it on every streaming complete event, including refine-from-chat.
  • Add a quick static check that every fetch to an AI endpoint either calls applyProviderMetadata() or explicitly comments why provider metadata is not expected.

P1: Model Registry Still Is Not The Sole Source Of Truth

Registry adoption improved in active settings and sidebar defaults, but hard-coded model IDs remain in several places:

  • includes/class-settings-v2.php:188-215 still contains fallback model arrays with literal model IDs.
  • includes/class-settings-v2.php:224-230 still uses literal fallback IDs in model transformation.
  • assets/js/settings-v2.js:32-58 still hard-codes budget/balanced/premium preset IDs.
  • includes/class-openrouter-provider.php:29-75 still hard-codes provider property defaults, and the constructor uses those properties when settings are absent at includes/class-openrouter-provider.php:437-448.
  • includes/class-image-manager.php:409-478 still hard-codes image model fallbacks.
  • Legacy includes/class-settings.php still contains hard-coded defaults and may be instantiated if Settings V2 is unavailable.

Impact:

  • The registry can still drift from runtime behavior.
  • The settings UI fallback list can disagree with generation defaults.
  • Future model changes still require touching multiple locations.

Recommended fix:

  • Replace remaining active runtime fallbacks with WPAW_Model_Registry::get_default_model() or get_fallback_model().
  • Treat JS presets as curated presets and document them as such, or generate them from localized registry data.
  • Initialize OpenRouter provider defaults from the registry in the constructor.
  • Replace image manager fallback literals at includes/class-image-manager.php:409-478.
  • Decide whether legacy class-settings.php is supported; if yes, update its defaults to use the registry, otherwise remove fallback instantiation.

P2: Sidebar Still Uses Deprecated /chat-history

The route compatibility bug from earlier passes appears fixed, but the sidebar still uses the deprecated route:

  • assets/js/sidebar.js:666-680 fetches /chat-history/${postId}.
  • The backend route remains registered at includes/class-gutenberg-sidebar.php:346-354.
  • The docblock still says the endpoint does not use conversations at includes/class-gutenberg-sidebar.php:1337-1339, even though the implementation now reads session-backed history.

Impact:

  • The UI still depends on a compatibility endpoint.
  • Documentation and behavior disagree.
  • Future cleanup can break chat hydration again.

Recommended fix:

  • Move sidebar hydration to the canonical conversation/session context endpoint.
  • If /chat-history remains, update the docblock and response contract to explicitly say it returns session-backed compatibility data.

P2: Cost Tracking Helper Is Not Yet Enforced

track_ai_cost() exists, but raw cost hook calls remain:

  • includes/class-gutenberg-sidebar.php still has many direct do_action( 'wp_aw_after_api_request', ... ) calls outside the helper.
  • includes/class-keyword-suggester.php:122 also calls the cost hook directly.

Impact:

  • New changes can still bypass provider/session/status normalization.
  • The codebase still relies on manual discipline instead of enforcing the cost tracking contract.

Recommended fix:

  • Convert remaining route-level raw hooks to track_ai_cost().
  • Either expose a shared cost helper outside the sidebar class or document why non-sidebar callers may use the raw hook.
  • Add a static guard that only allows raw wp_aw_after_api_request calls in approved files/lines.

P2: Live Editor Browser Verification Still Remains

No live WordPress editor browser workflow was run in this retrace.

Recommended browser checklist:

  • Sidebar opens and persists in the block editor.
  • Chat session continues after page reload.
  • Provider/fallback warnings render after every AI action with metadata.
  • Cost display updates after chat, plan, refine, and meta actions.
  • Unauthorized post access fails cleanly.
  • Model settings changes reflect in generated requests.
  1. Add applyProviderMetadata() to the remaining AI response paths.
  2. Finish model registry adoption in active runtime paths or explicitly document curated exceptions.
  3. Move sidebar chat hydration off /chat-history, or update the route contract/docblock.
  4. Convert remaining raw cost hooks or add a static guard for approved direct hook use.
  5. Run the live WordPress editor browser workflow pass.

Current Verdict

The tenth-pass implementation is proper for the provider-UI helper it targeted and does not introduce a new P0. The audit chain is now mostly down to consistency, cleanup, and browser validation.

I would not call the plugin fully audit-clean yet, but the remaining issues are bounded and should be much smaller to close than the earlier authorization/context/cost blockers.