{
  "$schema": "~/.claude/templates/quality-gates/shared/contracts.schema.json",
  "contracts": [
    {
      "id": "error-report",
      "description": "Plugin error report with diagnostic context including debug log",
      "schema": "schemas/report.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/FeedbackTransport.php",
        "test": [
          "tests/FeedbackTransportPayloadTest.php",
          "tests/FeedbackPayloadSchemaContractTest.php"
        ]
      },
      "consumer": {
        "file": "src/routes/reports.js",
        "test": "tests/FeedbackPayloadSchemaContractTest.php"
      },
      "parityTest": "tests/FeedbackTransportE2ERoundTripTest.php",
      "fixtures": {
        "valid": [
          "fixtures/error-report.valid.json"
        ],
        "invalid": [
          "fixtures/error-report.invalid-missing-debug-log.json"
        ]
      }
    },
    {
      "id": "heartbeat",
      "description": "Periodic health check from plugin to server",
      "schema": "schemas/report.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/FeedbackTransport.php",
        "test": "tests/FeedbackPayloadSchemaContractTest.php"
      },
      "consumer": {
        "file": "src/routes/reports.js",
        "test": "tests/FeedbackPayloadSchemaContractTest.php"
      },
      "parityTest": "tests/FeedbackTransportE2ERoundTripTest.php",
      "fixtures": {
        "valid": [
          "fixtures/heartbeat.valid.json"
        ],
        "invalid": [
          "fixtures/heartbeat.invalid-missing-version.json"
        ]
      }
    },
    {
      "id": "uninstall-report",
      "description": "Plugin uninstall feedback with reason and optional contact email",
      "schema": "schemas/report.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/FeedbackTransport.php",
        "test": "tests/FeedbackPayloadSchemaContractTest.php"
      },
      "consumer": {
        "file": "src/routes/reports.js",
        "test": "tests/FeedbackPayloadSchemaContractTest.php"
      },
      "parityTest": "tests/FeedbackTransportE2ERoundTripTest.php",
      "fixtures": {
        "valid": [
          "fixtures/uninstall-report.valid.json"
        ],
        "invalid": [
          "fixtures/uninstall-report.invalid-missing-version.json"
        ]
      }
    },
    {
      "id": "support-request",
      "description": "User support request with message, reply email, and debug log excerpt",
      "schema": "schemas/report.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/Ajax_SupportRequest.php",
        "test": [
          "tests/FeedbackTransportSupportRequestPayloadTest.php",
          "tests/FeedbackPayloadSchemaContractTest.php"
        ]
      },
      "consumer": {
        "file": "src/routes/reports.js",
        "test": "tests/FeedbackPayloadSchemaContractTest.php"
      },
      "parityTest": "tests/FeedbackTransportE2ERoundTripTest.php",
      "fixtures": {
        "valid": [
          "fixtures/support-request.valid.json"
        ],
        "invalid": [
          "fixtures/support-request.invalid-missing-user-message.json"
        ]
      }
    },
    {
      "id": "ajax-update-pagination",
      "description": "Admin table pagination AJAX request",
      "schema": "schemas/ajax-update-pagination.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/view_updater_pagination.js",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "consumer": {
        "file": "includes/ajax/ViewUpdater.php",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-update-pagination.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-update-pagination.invalid-missing-subpage.json"
        ]
      }
    },
    {
      "id": "ajax-refresh-stats-dashboard",
      "description": "Dashboard stats refresh AJAX request",
      "schema": "schemas/ajax-refresh-stats-dashboard.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/view_updater_stats.js",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "consumer": {
        "file": "includes/ajax/ViewUpdater.php",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-refresh-stats.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-refresh-stats.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-refresh-health-bar",
      "description": "Health bar refresh AJAX request",
      "schema": "schemas/ajax-refresh-health-bar.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/view_updater_stats.js",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "consumer": {
        "file": "includes/ajax/ViewUpdater.php",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-refresh-health-bar.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-refresh-health-bar.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-run-lazy-backfill",
      "description": "Admin table page-load lazy denorm and sort-key backfill request",
      "schema": "schemas/ajax-run-lazy-backfill.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/view_updater_lazy_backfill.js",
        "test": [
          "tests/HealthBarAjaxDecouplingTest.php",
          "tests-js/lazy-backfill-polling.test.js"
        ]
      },
      "consumer": {
        "file": "includes/ajax/Ajax_RunLazyBackfill.php",
        "test": [
          "tests/RedirectsDenormBackfillIntegrationTest.php",
          "tests/AjaxRuntimeContractValidationTest.php"
        ]
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-run-lazy-backfill.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-run-lazy-backfill.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-support-request",
      "description": "Support request FormData AJAX from admin modal",
      "schema": "schemas/ajax-support-request.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/SupportRequest.js",
        "test": "tests-js/support-request-button.test.js"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_SupportRequest.php",
        "test": "tests-js/support-request-button.test.js"
      },
      "parityTest": "tests-js/support-request-button.test.js",
      "fixtures": {
        "valid": [
          "fixtures/ajax-support-request.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-support-request.invalid-bad-trigger.json"
        ]
      }
    },
    {
      "id": "ajax-support-request-preview",
      "description": "Support request preview read-only AJAX",
      "schema": "schemas/ajax-support-request-preview.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/SupportRequest.js",
        "test": "tests-js/support-request-button.test.js"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_SupportRequestPreview.php",
        "test": "tests-js/support-request-button.test.js"
      },
      "parityTest": "tests-js/support-request-button.test.js",
      "fixtures": {
        "valid": [
          "fixtures/ajax-support-request-preview.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-support-request-preview.invalid-missing-trigger.json"
        ]
      }
    },
    {
      "id": "ajax-cross-plugin-preview",
      "description": "Cross-Plugin Importer preview AJAX from admin stats page",
      "schema": "schemas/ajax-cross-plugin-preview.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ViewTrait_Stats.php",
        "test": "tests/AjaxCrossPluginImporterContractTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_CrossPluginImporter.php",
        "test": "tests/AjaxCrossPluginImporterContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-cross-plugin-preview.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-cross-plugin-preview.invalid-bad-source.json"
        ]
      }
    },
    {
      "id": "ajax-engine-profiles",
      "description": "Engine Profile CRUD AJAX from admin engine profiles page",
      "schema": "schemas/ajax-engine-profiles.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/ajax-engine-profiles.js",
        "test": "tests/AjaxEngineProfilesContractTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_EngineProfiles.php",
        "test": "tests/AjaxEngineProfilesContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-engine-profiles.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-engine-profiles.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-update-options",
      "description": "Plugin options update AJAX from admin settings page",
      "schema": "schemas/ajax-update-options.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/js/general.js",
        "test": "tests/AjaxUpdateOptionsContractTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_Php.php",
        "test": "tests/AjaxUpdateOptionsContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-update-options.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-update-options.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-restore-defaults",
      "description": "Restore plugin settings to defaults AJAX from admin settings page",
      "schema": "schemas/ajax-restore-defaults.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/RestoreDefaults.js",
        "test": "tests/SettingsRestoreDefaultsActionTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_RestoreDefaults.php",
        "test": "tests/SettingsRestoreDefaultsActionTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-restore-defaults.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-restore-defaults.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-settings-mode-toggle",
      "description": "Simple/Advanced settings mode toggle AJAX",
      "schema": "schemas/ajax-settings-mode-toggle.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/SettingsModeToggle.js",
        "test": "tests/AjaxSettingsModeToggleTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_SettingsModeToggle.php",
        "test": "tests/AjaxSettingsModeToggleTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-settings-mode-toggle.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-settings-mode-toggle.invalid-bad-mode.json"
        ]
      }
    },
    {
      "id": "ajax-suggestion-compute",
      "description": "Background suggestion computation triggered server-side via wp_remote_post",
      "schema": "schemas/ajax-suggestion-compute.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/SpellChecker.php",
        "test": "tests/AjaxSuggestionComputeContractTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_SuggestionCompute.php",
        "test": "tests/AjaxSuggestionComputeContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-suggestion-compute.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-suggestion-compute.invalid-missing-token.json"
        ]
      }
    },
    {
      "id": "ajax-suggestion-polling",
      "description": "Public-facing 404 page suggestion polling AJAX",
      "schema": "schemas/ajax-suggestion-polling.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/SuggestionPolling.js",
        "test": "tests/AjaxSuggestionPollingJsonContractTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_SuggestionPolling.php",
        "test": "tests/AjaxSuggestionPollingJsonContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-suggestion-polling.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-suggestion-polling.invalid-missing-url.json"
        ]
      }
    },
    {
      "id": "ajax-trash-link",
      "description": "Trash/restore redirect AJAX from admin redirects table",
      "schema": "schemas/ajax-trash-link.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/trash_link_ajax.js",
        "test": "tests/AjaxTrashLinkContractTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_TrashLink.php",
        "test": "tests/AjaxTrashLinkContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-trash-link.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-trash-link.invalid-missing-id.json"
        ]
      }
    },
    {
      "id": "ajax-trend-data",
      "description": "Trend analytics chart data AJAX from admin stats page",
      "schema": "schemas/ajax-trend-data.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ViewTrait_Stats.php",
        "test": "tests/AjaxTrendDataContractTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_TrendData.php",
        "test": "tests/AjaxTrendDataContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-trend-data.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-trend-data.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-admin-endpoint-support-helper",
      "description": "Shared admin AJAX response envelope emitted by Ajax_AdminEndpointSupport for every admin endpoint",
      "schema": "schemas/ajax-admin-endpoint-support-helper.schema.json",
      "direction": "server-to-client",
      "consumer": {
        "file": "includes/ajax/Ajax_AdminEndpointSupport.php",
        "test": "tests/ViewQueryFailureDiagnosticsTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-admin-endpoint-support-helper.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-admin-endpoint-support-helper.invalid-missing-success.json"
        ]
      }
    },
    {
      "id": "ajax-get-pagination-links-handler",
      "description": "Extracted PHP handler for admin table pagination AJAX",
      "schema": "schemas/ajax-update-pagination.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/view_updater_pagination.js",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_GetPaginationLinks.php",
        "test": "tests/ViewUpdaterAjaxFetchRenderContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-update-pagination.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-update-pagination.invalid-missing-subpage.json"
        ]
      }
    },
    {
      "id": "ajax-refresh-admin-nonces-handler",
      "description": "Extracted PHP handler for refreshing admin AJAX nonces",
      "schema": "schemas/ajax-refresh-admin-nonces.schema.json",
      "direction": "server-to-client",
      "consumer": {
        "file": "includes/ajax/Ajax_RefreshAdminNonces.php",
        "test": "tests/AjaxRefreshAdminNoncesTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-refresh-admin-nonces.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-refresh-admin-nonces.invalid-missing-data.json"
        ]
      }
    },
    {
      "id": "ajax-refresh-health-bar-handler",
      "description": "Extracted PHP handler for health bar refresh AJAX",
      "schema": "schemas/ajax-refresh-health-bar.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/view_updater_stats.js",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_RefreshHealthBar.php",
        "test": "tests/HealthBarAjaxDecouplingTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-refresh-health-bar.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-refresh-health-bar.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-refresh-stats-dashboard-handler",
      "description": "Extracted PHP handler for dashboard stats refresh AJAX",
      "schema": "schemas/ajax-refresh-stats-dashboard.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/view_updater_stats.js",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_RefreshStatsDashboard.php",
        "test": "tests/ViewUpdaterAjaxRefreshStatsDashboardContractTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-refresh-stats.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-refresh-stats.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-uninstall-prefs-handler",
      "description": "Extracted PHP handler for uninstall/deactivation preference AJAX",
      "schema": "schemas/ajax-uninstall-prefs.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/js/uninstall-modal.js",
        "test": "tests-js/ajax-response-validation.test.js"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_UninstallPrefs.php",
        "test": "tests/UninstallPreferencesMultisiteTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-uninstall-prefs.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-uninstall-prefs.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-load-gsc-section",
      "description": "Deferred Google Search Console admin section AJAX. Loaded on demand from the Options page so the GSC OAuth + remote-fetch cost does not block initial admin render.",
      "schema": "schemas/ajax-load-gsc-section.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/js/settingsDeferred.js",
        "test": "tests/AjaxNullParamsAdversarialTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_LoadGscSection.php",
        "test": "tests/AjaxNullParamsAdversarialTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-load-gsc-section.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-load-gsc-section.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-redirect-destination-autocomplete",
      "description": "Autocomplete suggestions for the redirect-destination dropdown in the redirect edit modal.",
      "schema": "schemas/ajax-redirect-destination-autocomplete.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/redirect_to_ajax.js",
        "test": "tests/AjaxNullParamsAdversarialTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_RedirectDestinationAutocomplete.php",
        "test": "tests/AjaxNullParamsAdversarialTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-redirect-destination-autocomplete.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-redirect-destination-autocomplete.invalid-bad-include-flag.json"
        ]
      }
    },
    {
      "id": "ajax-update-options-handler",
      "description": "Admin-page options update AJAX (extracted from Ajax_Php for parity with other Ajax_*.php handlers).",
      "schema": "schemas/ajax-update-options.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/js/general.js",
        "test": "tests/AjaxNullParamsAdversarialTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_UpdateOptions.php",
        "test": "tests/AjaxNullParamsAdversarialTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-update-options.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-update-options.invalid-missing-nonce.json"
        ]
      }
    },
    {
      "id": "ajax-view-logs",
      "description": "Per-redirect log view AJAX. Returns the formatted hit log for a specific redirect ID for the admin logs modal.",
      "schema": "schemas/ajax-view-logs.schema.json",
      "direction": "client-to-server",
      "producer": {
        "file": "includes/ajax/search_logs_ajax.js",
        "test": "tests/AjaxNullParamsAdversarialTest.php"
      },
      "consumer": {
        "file": "includes/ajax/Ajax_ViewLogs.php",
        "test": "tests/AjaxNullParamsAdversarialTest.php"
      },
      "parityTest": "tests/AjaxRuntimeContractValidationTest.php",
      "fixtures": {
        "valid": [
          "fixtures/ajax-view-logs.valid.json"
        ],
        "invalid": [
          "fixtures/ajax-view-logs.invalid-missing-nonce.json"
        ]
      }
    }
  ]
}
