cc-triage --bare + CLAUDE_CODE_OAUTH_TOKEN = silent auth failure

Run 25487401956 produced clean snapshots but parse_failed: true on every version, with ~700ms empty-stderr exits. Tracked it to a flag-vs-auth incompatibility documented in claude --help but not in the script's comment.

The official statement claude --help

--bare: Minimal mode: skip hooks, LSP, plugin sync, attribution, auto-memory, background prefetches, keychain reads, and CLAUDE.md auto-discovery. Sets CLAUDE_CODE_SIMPLE=1. Anthropic auth is strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth and keychain are never read). 3P providers (Bedrock/Vertex/Foundry) use their own credentials.

Where it broke

// scripts/cc-triage.mjs (before)
spawnSync('claude', [
  '-p',
  '--bare',                 // ← locks auth to API key only
  '--max-turns', '1',
  '--output-format', 'text',
  '--model', 'claude-opus-4-7',
], { input: prompt, env: process.env, ... })

# .github/workflows/claude-release-watch.yml
env:
  CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
  # ANTHROPIC_API_KEY is NOT set on this workflow

The CLI sees --bare, refuses to read OAuth, falls back to ANTHROPIC_API_KEY which is unset, exits 1 silently, and the --bare-suppressed error path means stderr is empty. Looks identical to "binary missing" or "network down."

Diagnosis trail

  1. PR #1620: cc-triage failed with "claude native binary not installed" (clear).
  2. PR #1622: workflow patched to run install.cjs after --ignore-scripts — binary lands.
  3. Run 25487401956: cc-triage fails again, empty stderr, ~700ms × 2 attempts × 4 versions.
  4. Reading claude --help: spotted the --bare auth restriction.
  5. Confirmed by reading scripts/cc-triage.mjs:127-149 — it passes both --bare AND relies on CLAUDE_CODE_OAUTH_TOKEN in env.

Fix & trade-offs

Before

'-p',
'--bare',
'--max-turns', '1',
'--output-format', 'text',
'--model', 'claude-opus-4-7'
  • OAuth never read (despite env var set)
  • Silent exit 1 with empty stderr
  • Every version writes parse_failed: true
  • Adoption issues NEVER filed

After

'-p',
'--max-turns', '1',
'--output-format', 'text',
'--model', 'claude-opus-4-7'
  • OAuth token honored normally
  • cc-triage extracts features as designed
  • Adoption issues file against milestone
What does --bare actually buy us, and is losing it OK?

--bare skips hooks, LSP, plugin sync, attribution writes, auto-memory, background prefetches, keychain reads, and CLAUDE.md auto-discovery. For a one-shot text-extraction call running headless on a CI runner with no project files, none of those matter — there's no project to discover, no hooks installed, no keychain. The "minimal mode" was load-bearing-looking but actually unnecessary.

Verification

Once merged, dispatch claude-release-watch.yml manually OR run node scripts/cc-triage.mjs --retry-failed against the existing #1628 to refresh the parse_failed sentinels. Adoption issues for the 20 features in #1623's matrix should then file naturally.