 ## Background
  The Plugin Compass builder is public-facing and currently exposes OpenCode-specific error messages and codes to end users. This is confusing and leaks
  internal detail. Additionally, fallback behavior mixes client and server responsibilities in a way that can trigger the wrong recovery action (e.g.,
  switching models when a malformed edit should trigger a “continue”). Provider rate limits are configured in the admin panel, but the runtime behavior
  should distinguish between minute limits (wait and retry) vs. hour/day limits (skip to next model). Finally, the OpenCode CLI must reliably include
  WordPress validation instructions and ensure the WordPress validator tool is actually callable, while preserving token extraction to keep usage accurate.

  ## Goals
  1. **Public UX**: Replace builder error messaging with a safe, branded message.
  2. **Fallback correctness**:
     - Malformed edits → send “continue” to OpenCode (same model/session).
     - Provider/quota errors → switch to next model/provider.
  3. **Rate-limit behavior**:
     - Minute limits → wait until reset, then retry same provider/model.
     - Hour/day limits → skip immediately to next model.
     - Automatically return to a provider once limits lift.
  4. **WordPress validation**:
     - Ensure `wordpress-plugin.txt` prompt is always applied in builder sessions.
     - Ensure `wordpress-validator:validate_wordpress_plugin` is callable.
  5. **Token extraction safety**: Errors/continuations should not break token usage reporting in the builder UI.

  ## Non-Goals
  - Changing plan models or public model list behavior.
  - Redesigning the builder UI or admin UI.
  - Modifying export/ZIP workflows.

  ---

  ## Current State Summary (from repo)
  - Builder UI is in `chat/public/builder.js` and `chat/public/builder.html`.
  - Fallback logic for OpenCode is primarily in `chat/server.js`:
    - `sendToOpencodeWithFallback`
    - `isEarlyTerminationError`
    - `classifyProviderError`
    - `isProviderLimited`
  - WordPress prompt file exists at:
    - `opencode/packages/opencode/src/session/prompt/wordpress-plugin.txt`
  - WordPress validator tool exists as a built-in tool:
    - `opencode/packages/opencode/src/tool/validate-wordpress-plugin.ts`
  - MCP server for WP CLI testing is already wired in `chat/server.js`.

  ---

  ## Plan

  ### 1) Builder Error Masking (Public UI)
  **Files**: `chat/public/builder.js`

  **Changes**
  - When rendering assistant errors, replace any OpenCode or provider error text with:
    - **“Plugin Compass failed. Please try again.”**
  - Apply the same masking to `setStatus()` paths for OpenCode errors in builder UI.

  **Acceptance Criteria**
  - Builder page never shows “OpenCode failed” or raw exit codes.
  - Admin/internal logs remain unchanged.

  ---

  ### 2) Malformed Edit → Continue (OpenCode)
  **Files**: `chat/server.js`

  **Changes**
  - Extend `isEarlyTerminationError()` to treat malformed edit cases as early termination:
    - Add patterns like `/error:.*malformed edit/i` and `/error:.*invalid edit/i`.
  - This ensures `sendToOpencodeWithFallback` issues a `[CONTINUE]` retry in the same model/session before switching.

  **Acceptance Criteria**
  - Malformed edit errors trigger a “continue” attempt.
  - Only after `MAX_CONTINUE_ATTEMPTS` does it switch models.

  ---

  ### 3) Provider Errors → Switch Model
  **Files**: `chat/server.js`

  **Changes**
  - Expand `classifyProviderError()` to detect provider quota/billing messages:
    - “key limit reached”, “quota exceeded”, “insufficient quota”, “payment required”, etc.
  - Return `{ action: 'switch' }` for these errors.

  **Acceptance Criteria**
  - Quota/billing errors cause immediate fallback to next model/provider.

  ---

  ### 4) Rate Limits: Minute vs Hour/Day
  **Files**: `chat/server.js`

  **Changes**
  - Extend `isProviderLimited()` to return `retryAfterMs` when the limit field is per-minute.
  - In `sendToOpencodeWithFallback`:
    - If the limit is **minute-based**, wait for reset and retry the same provider/model.
    - If **hour/day**, skip immediately to next model.
  - Use provider usage timestamps to compute `retryAfterMs`.

  **Acceptance Criteria**
  - Minute limit → waits until reset, retries same model.
  - Hour/day limit → switches to next model without waiting.
  - When a provider’s limit clears, it is retried in chain order.

  ---

  ### 5) WordPress Validator MCP + Prompt Enforcement
  **Files**
  - `opencode/mcp-servers/wordpress-validator/*` (new)
  - `chat/server.js`
  - `opencode/packages/opencode/src/session/prompt/wordpress-plugin.txt`
  - `opencode/packages/opencode/src/session/system.ts`

  **Changes**
  1. **MCP Server**
     - Create `wordpress-validator` MCP server wrapping the same validation script.
     - Tool name: `validate_wordpress_plugin`.
  2. **Wire MCP server for builder**
     - Use `OPENCODE_EXTRA_MCP_SERVERS` in `chat/server.js` to enable this MCP server for builder sessions.
  3. **Prompt update**
     - Update `wordpress-plugin.txt` to reference both:
       - `wordpress-validator:validate_wordpress_plugin` (MCP)
       - `validate_wordpress_plugin` (built-in)
  4. **Force WordPress prompts**
     - Add `OPENCODE_FORCE_WORDPRESS=1` option in `system.ts` to always append WordPress prompts for builder sessions.
     - Set this env var when running OpenCode from the builder.

  **Acceptance Criteria**
  - WordPress validator tool is callable and not blocked by tool registry.
  - WordPress prompt always included for builder sessions.

  ---

  ### 6) Token Extraction & Usage Safety
  **Files**: `chat/server.js`, `chat/public/builder.js`

  **Changes**
  - Ensure token usage is recorded on:
    - Successful completion
    - Continuations
    - Error states with estimated tokens
  - Ensure builder calls `loadUsageSummary()` after completion/error even if SSE fails.

  **Acceptance Criteria**
  - Usage meter updates after errors and continuations.
  - No “missing token usage” regressions in builder.

  ---

  ## Public API / Interface Changes
  - New env flag:
    - `OPENCODE_FORCE_WORDPRESS=1`
  - New MCP server:
    - `wordpress-validator` (exposed through `OPENCODE_EXTRA_MCP_SERVERS`)

  ---

  ## Testing & Validation

  2. Malformed edit → continue attempt occurs before model switch.
  3. Provider minute limit → waits until reset then retries same model.
  4. Provider hour/day limit → switches immediately.
  5. Validator MCP tool works; WordPress prompt is applied.

  ---

  ## Risks / Mitigations
  - **Risk**: Overeager fallback if error matching is too broad.
    - Mitigation: Keep strict patterns and prefer explicit error prefixes.
  - **Risk**: Waiting too long on minute limits.
    - Mitigation: Compute retry after using usage timestamps and cap to 60s.

  ---

  ## Assumptions
  - Builder runs in the chat server context using OpenCode CLI.
  - Admin limits are authoritative for provider restrictions.
  - WordPress validator script exists at `scripts/validate-wordpress-plugin.sh`.

  ---

  ## Milestones
  1. Builder error masking
  2. Fallback and limit corrections
  3. MCP server + prompt enforcement
  4. Validation + testing
