Skip to content

Migrate Claude harness from builtin to container-script provisioning#279

Open
ptone wants to merge 3 commits into
GoogleCloudPlatform:mainfrom
ptone:scion/cleanup-container-script-provisioning
Open

Migrate Claude harness from builtin to container-script provisioning#279
ptone wants to merge 3 commits into
GoogleCloudPlatform:mainfrom
ptone:scion/cleanup-container-script-provisioning

Conversation

@ptone
Copy link
Copy Markdown
Member

@ptone ptone commented May 31, 2026

Summary

  • Migrate the Claude harness from the compiled-in builtin provisioner to the extensible container-script model, matching what OpenCode and Codex already use
  • Add provision.py for Claude that handles auth resolution, API key pre-approval, project path setup, and MCP server translation
  • Add comprehensive parity tests and Python integration tests

Refs #100

What changed

pkg/harness/claude/embeds/config.yaml: Changed provisioner.type from builtin to container-script and added MCP capabilities block.

pkg/harness/claude/embeds/provision.py (new): Container-side provisioner script handling:

  • Auth resolution with Claude's 4-way precedence (API key → OAuth token → auth-file → Vertex AI)
  • API key pre-approval fingerprint in .claude.json (mirrors ClaudeCode.ApplyAuthSettings)
  • Project workspace path setup in .claude.json (mirrors ClaudeCode.provisionClaudeJSON)
  • MCP server translation using scion_harness.apply_mcp_servers_simple()
  • Auth env var overlay output for the runtime

pkg/harness/claude_parity_test.go (new): 11 tests covering:

  • Seed/embed verification (TestClaudeEmbedsSeedRootSupportFiles)
  • Activate-script idempotency (TestClaudeActivateScriptIsIdempotent)
  • ContainerScriptHarness vs ClaudeCode parity (TestClaudeContainerScriptHarnessParity)
  • Bundle staging and reconciliation
  • Python script integration: happy path, no-creds, API key approval, Vertex AI, MCP

What remains (tracked in #100)

  • Gemini harness: Still on builtin; needs its own provision.py (follow-up PR)
  • Retire builtin path: Once all harnesses migrate, remove newBuiltin() from resolve.go and the compiled provisioning methods

The compiled ClaudeCode harness is intentionally kept as a fallback for existing installations that haven't upgraded their harness-config.

Test plan

  • All 11 new parity/integration tests pass
  • All existing Claude tests still pass (no regressions)
  • All other harness tests pass (OpenCode, Codex, Gemini parity tests)
  • go vet ./pkg/harness/... clean
  • go build ./... succeeds

ptone added 2 commits May 31, 2026 16:43
Move the Claude harness from the compiled-in builtin provisioner to the
extensible container-script model, matching what OpenCode and Codex
already use. This is the first concrete step in retiring the builtin
provisioner path (refs #100).

The container-side provision.py handles:
- Auth resolution with Claude's 4-way precedence
  (API key → OAuth token → auth-file → Vertex AI)
- API key pre-approval fingerprint in .claude.json
- Project workspace path setup in .claude.json
- MCP server translation via scion_harness helper
- Auth env var overlay output for the runtime

The compiled ClaudeCode harness is kept intact as a fallback for
existing installations that haven't upgraded their harness-config.

Includes parity tests and Python integration tests that verify the
script produces identical outputs to the compiled harness.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request transitions the Claude Code harness provisioner to a container-script model, introducing a container-side Python script (provision.py) to handle configuration, MCP server translation, and authentication resolution. It also adds extensive parity and integration tests in Go. The review feedback highlights a critical issue in the Python script's auto-detection logic for Vertex AI, where requiring a local Application Default Credentials (ADC) file prevents successful authentication in GCP environments that use metadata-server-based service accounts.

Comment thread pkg/harness/claude/embeds/provision.py Outdated
return "oauth-token", "CLAUDE_CODE_OAUTH_TOKEN"
if has_authfile:
return "auth-file", ""
if has_adc and has_gcp_project and has_gcp_region:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In GCP environments (such as GKE, Cloud Run, or Compute Engine), containers often authenticate using the VM or Pod's attached service account via the GCP metadata server (assign mode). In these cases, no local Application Default Credentials (ADC) file is mounted, meaning has_adc will be False.

Since has_adc is required in the current auto-detect block, auto-detection of vertex-ai will fail even if GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_REGION are correctly set, raising an unexpected ValueError and blocking provisioning.

Removing the has_adc requirement from the auto-detect fallback allows the GCP SDK/Vertex AI client to seamlessly fall back to the metadata server as expected.

Suggested change
if has_adc and has_gcp_project and has_gcp_region:
if has_gcp_project and has_gcp_region:

Address review feedback: remove the has_adc requirement from the
Vertex AI auto-detect path in provision.py. In GCP environments
(GKE, Cloud Run, Compute Engine), containers authenticate via the
metadata server using attached service accounts — no local ADC file
is mounted. The GCP SDK handles this fallback natively, so requiring
project + region is sufficient for auto-detection.

Add TestClaudeProvisionScript_Integration_VertexAI_NoADC to verify
the fix works for GCP service account environments.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant