# Phase 04 — Simplify Headers.build

**Estimated time:** ~15 minutes
**Touches:** `lib/dispatch/adapter/minimax/headers.rb`,
`lib/dispatch/adapter/minimax.rb` (callsite cleanup).

## Goal

Collapse `Headers.build` from the Anthropic Claude Code header set
(Stainless SDK fingerprints, `anthropic-version`, `anthropic-beta` list,
Claude Code UA, OAuth-vs-API-key branching, `claude_code_only` mode) to
the bare minimum MiniMax accepts:

- `Authorization: Bearer <api_key>`
- `Content-Type: application/json`
- `Accept: application/json` (or `text/event-stream` when `stream: true`)

That's it. No version header, no betas, no Stainless metadata, no UA.

## Steps

### 1. Rewrite `lib/dispatch/adapter/minimax/headers.rb` end to end

```ruby
# frozen_string_literal: true

module Dispatch
  module Adapter
    class MiniMax < Base
      module Headers
        module_function

        # Build the request headers for a MiniMax API call.
        #
        # @param api_key [String]   the MiniMax API key (Token Plan or PAYG)
        # @param stream  [Boolean]  set Accept to text/event-stream when true
        # @param extra   [Hash]     low-priority caller overrides
        # @return [Hash<String,String>]
        def build(api_key:, stream: false, extra: {})
          headers = extra.transform_keys(&:to_s)
          headers["Content-Type"] = "application/json"
          headers["Accept"]       = stream ? "text/event-stream" : "application/json"
          # Authorization is always last so caller extras cannot override it.
          headers["Authorization"] = "Bearer #{api_key}"
          headers
        end
      end
    end
  end
end
```

### 2. Update every callsite in `lib/dispatch/adapter/minimax.rb`

Find every `Headers.build(...)` and `build_headers_proc` invocation. The
old signature took these keywords:

```
api_key:, is_oauth:, stream:, extra_betas:, interleaved_thinking:,
base_url:, extra:, claude_code_only:
```

Replace EACH callsite with the new signature, keeping only:

```
api_key:, stream:, extra: (only when actually passed)
```

DELETE every passing of:
- `is_oauth:`
- `extra_betas:`
- `interleaved_thinking:`
- `base_url:` (Headers no longer cares about it)
- `claude_code_only:`

### 3. Drop `extra_betas` from the constructor

Phase 02 may have left `@extra_betas` ivar in place. Now delete:

- The `extra_betas:` keyword on `initialize`.
- The `@extra_betas = Array(extra_betas)` assignment.
- Any reference in `chat`, `count_tokens`, `list_models`, etc.

### 4. Drop the `build_headers_proc` lambda if it exists

If `lib/dispatch/adapter/minimax.rb` still has a `build_headers_proc`
method or lambda factory, delete it. Replace its call sites with direct
`Headers.build(api_key: @api_key, stream: ...)` calls. The wrapper was
needed because `claude_code_only` and `extra_betas` varied per request;
they no longer exist.

## Acceptance criteria

- `headers.rb` is approximately the size shown above (≤ 25 lines of code).
- `grep -rn 'anthropic-version\|anthropic-beta\|x-stainless\|claude-cli\|claude_code_only\|interleaved_thinking\|extra_betas\|DEFAULT_BETAS\|CLAUDE_CODE_VERSION\|STAINLESS_PACKAGE_VERSION\|sk-ant-oat' lib/` returns ZERO matches.
- The constructor no longer accepts `extra_betas:`.
- Every `Headers.build` callsite in `lib/dispatch/adapter/minimax.rb` uses
  only `api_key:`, `stream:`, and optionally `extra:` keywords.
- `bundle exec rubocop --autocorrect-all` exits 0.

The headers spec will fail until phase 13 retargets it; that is expected.

## Verification

Run `run_tests` with `project_path=reference/dispatch-adapter-minimax`.
Rubocop must be clean. RSpec failures in `headers_spec.rb` are acceptable
(retargeted in phase 13). RSpec failures elsewhere caused by missing
header keywords are NOT acceptable — chase them down and fix the call
chain before calling `ask_for_next_plan`.
