# Phase 02 — Strip OAuth and Anthropic-specific machinery **Estimated time:** ~30 minutes **Touches:** `lib/dispatch/adapter/minimax.rb` and 7 sub-files (deletions). ## Goal Delete all code and methods that exist solely to support Anthropic's OAuth flow, Stainless SDK fingerprinting, Claude Code cloaking, the `/api/oauth/usage` endpoint, and Anthropic's unified rate-limit header format. After this phase the gem will be missing some required pieces (`Headers.build` will be partially broken until phase 03) — that's OK, phase 03 reconstructs the simplified replacements. MiniMax uses a single static API key (Token Plan) — no OAuth, no PKCE, no token refresh, no usage endpoint, no Stainless headers. ## Files to DELETE entirely ```text lib/dispatch/adapter/minimax/oauth.rb lib/dispatch/adapter/minimax/oauth/ (the whole directory and callback_server.rb) lib/dispatch/adapter/minimax/pkce.rb lib/dispatch/adapter/minimax/cloaking.rb lib/dispatch/adapter/minimax/usage_client.rb lib/dispatch/adapter/minimax/rate_limit_headers.rb spec/dispatch/adapter/minimax/oauth_spec.rb spec/dispatch/adapter/minimax/pkce_spec.rb spec/dispatch/adapter/minimax/cloaking_spec.rb spec/dispatch/adapter/minimax/usage_report_fixtures_spec.rb spec/dispatch/adapter/minimax/auth_lifecycle_spec.rb spec/fixtures/responses/oauth-profile.json spec/fixtures/responses/oauth-usage-full.json spec/fixtures/responses/oauth-usage-partial.json ``` (The `token_store.rb` file is renamed in phase 03, not deleted here.) ## Edits in `lib/dispatch/adapter/minimax.rb` ### 1. Remove the now-stale `require_relative` lines Delete these from the top of `lib/dispatch/adapter/minimax.rb`: ```ruby require_relative "minimax/pkce" require_relative "minimax/oauth" require_relative "minimax/cloaking" require_relative "minimax/usage_client" require_relative "minimax/rate_limit_headers" ``` Also delete the corresponding stdlib requires that ONLY OAuth needed: ```ruby require "securerandom" # only used by PKCE / OAuth state require "digest" # only used by PKCE require "base64" # only used by OAuth.CLIENT_ID decode ``` ### 2. Delete the following methods from the `MiniMax` class - `authenticate!` - `authenticated?` - `logout!` - `usage_report` - `with_auth_recovery` (private) - `rotate_token_for_usage` (private) - `ensure_token!` (private) - `expired?` (private) - `resolve_is_oauth` (private) - `explicit_api_key_present?` (private) - `capture_rate_limit_headers` (private) - `log_rate_limit_info` (private) - `http_client_claude_code` (private) ### 3. Delete the following ivars / state Remove all assignment to and reading of: - `@is_oauth` - `@is_oauth_override` - `@token_store` (will be replaced by `@key_store` in phase 03; for this phase, you may leave the variable name alone but DO simplify the assignment so it no longer takes a `token_path:` parameter — see below) - `@explicit_api_key` - `@strict_disabled` (KEEP — phase 06 retargets the strict-fallback) - `@rate_limit_info` - `@last_all_headers` - `@rate_limit_log_path` - `@models_cache`, `@models_cache_at` (KEEP — list_models is staying) ### 4. Simplify `initialize` Replace the constructor signature and body with a minimal version that accepts just `api_key:` (and the existing `model:`, `base_url:`, `max_tokens:`, `thinking:`, `cache_retention:`, `min_request_interval:`, `rate_limit:`, `extra_betas:`). Remove these constructor parameters: - `token_path:` - `is_oauth:` - `token_store:` - `user_agent_override:` Inside the body, remove all the `resolve_api_key` / `resolve_is_oauth` / TokenStore wiring. Phase 03 will introduce a `KeyStore` to load the API key from disk; for this phase, just accept `api_key:` as a keyword argument and require it (raise `ArgumentError` if it's nil/empty for now — phase 03 makes it optional and falls back to env / file). ```ruby def initialize( model: DEFAULT_MODEL, api_key: nil, base_url: DEFAULT_BASE_URL, max_tokens: nil, thinking: "high", cache_retention: nil, min_request_interval: DEFAULT_MIN_REQUEST_INTERVAL, rate_limit: nil, extra_betas: [] ) super() @model = model.to_s @base_url = base_url.to_s.chomp("/") @max_tokens = max_tokens @thinking = thinking @cache_retention = cache_retention @extra_betas = Array(extra_betas) @api_key = api_key.to_s raise ArgumentError, "api_key required" if @api_key.empty? @strict_disabled = false rate_limit_path = File.join(Dir.home, ".config", "dispatch", "minimax_rate_limit") @rate_limiter = RateLimiter.new( rate_limit_path: rate_limit_path, min_request_interval: min_request_interval, rate_limit: rate_limit ) end ``` ### 5. Simplify `chat` and `count_tokens` Inside both `#chat` and `#count_tokens`, remove the `with_auth_recovery` wrapper and the `ensure_token!` call. Keep `with_rate_limit`. Example: ```ruby def chat(messages, system: nil, tools: [], stream: false, ...) with_rate_limit do # body unchanged end end ``` ### 6. Simplify `RequestBuilder` calls In every place `RequestBuilder.build(...)` is called, remove the `is_oauth: @is_oauth` keyword argument. The `RequestBuilder` itself is edited in phase 06 to drop the parameter from its signature. ### 7. Simplify `ResponseBuilder.build` calls Remove the `is_oauth: @is_oauth` keyword argument from `ResponseBuilder.build(json, model_info: model_info, is_oauth: @is_oauth)`. The `ResponseBuilder` itself drops the parameter in phase 08. ### 8. Simplify `StreamCollector.new` calls Remove the `is_oauth: @is_oauth` keyword. The `StreamCollector` itself drops the parameter in phase 08. ### 9. Simplify `Headers.build` callsite In `build_headers_proc`, remove `claude_code_only:` (delete the parameter on the lambda and the `cc_only` capture). Phase 03 deletes the entire `claude_code_only` branch inside `Headers.build`. For now, just stop threading the parameter through. ### 10. Update or delete `RequestBuilder` references to cloaking If `request_builder.rb` requires or calls `Cloaking.cloak!` or `Cloaking.something`, REMOVE those calls. The system prompt and message shaping should remain identical to a non-OAuth Anthropic call. (Cloaking exists only because OAuth tokens require Claude-Code-style behavior; without OAuth, no cloaking is needed.) ## Acceptance criteria After completing this phase: - `grep -rn 'OAuth\|PKCE\|Cloaking\|UsageClient\|RateLimitHeaders' lib/` returns ZERO matches. - `grep -rn '@is_oauth\|claude_code_only\|sk-ant-oat\|usage_report\|token_path' lib/` returns ZERO matches. - `grep -rn '/api/oauth' lib/` returns ZERO matches. - All deleted files are gone from the working tree. - All deleted spec files are gone from the working tree. - `bundle exec rubocop --autocorrect-all` exits 0 (run via `run_tests`). - `bundle exec rspec` may have failures from specs that target the rate-limit-header parser or strict-fallback (phase 06/07 hooks), but must NOT have any `LoadError` or `NameError` referring to the deleted modules. If you see one, the corresponding `require_relative` line was missed in step 1. ## Verification Run `run_tests` with `project_path=reference/dispatch-adapter-minimax`. Resolve every rubocop offense before calling `ask_for_next_plan`. RSpec failures from removed-functionality test files should not exist after this phase (they were deleted) — other failures are acceptable and will be addressed in subsequent phases.