Skip to content

Add cloud session bootstrap for eval runbook inputs - #1193

Open
charlesyhuang wants to merge 2 commits into
stagingfrom
claude/cloud-task-dependencies-g4puha
Open

Add cloud session bootstrap for eval runbook inputs#1193
charlesyhuang wants to merge 2 commits into
stagingfrom
claude/cloud-task-dependencies-g4puha

Conversation

@charlesyhuang

@charlesyhuang charlesyhuang commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Problem

The eval runbooks are written against a laptop — a venv at a ~ path, agent CLIs on PATH, secrets in ~/.env. A Claude Code cloud session has none of that, so those steps fail verbatim and every session re-derives the same setup by hand.

Auditing the SWE-Marathon runbook's inputs against a fresh container, most turn out not to need porting so much as translating:

Runbook input Reality in a cloud container
~/oddish/oddish/.venv/bin/oddish repo is cloned, just has no venv — uv sync rebuilds it
~/.grok/bin/grok installable on demand; trials install their own copy in-sandbox regardless
XAI_API_KEY via ~/.env belongs to the environment's variable config; no ~/.env exists
~/.oddish credentials does not exist anywhere in this repo
~/cyberpipeline/*.sh genuinely unreachable — laptop-only files must reach a repo first

The ~/.oddish one is worth calling out: oddish/src/oddish/cli/config.py (get_api_key, get_api_url) reads ODDISH_API_KEY / ODDISH_API_URL from the environment and nothing else. There is no credentials file and no oddish login, so looking for a dotfile to copy is a dead end.

Changes

.claude/hooks/session-start.sh — a remote-only SessionStart hook that rebuilds what can be rebuilt:

  • uv sync --frozen --extra server in oddish/, producing oddish/.venv/bin/oddish. The --extra server matches AGENTS.md's documented setup; without it the test suite cannot import sqlalchemy.
  • puts that venv, ~/.grok/bin, and ~/.local/bin on PATH via $CLAUDE_ENV_FILE
  • bridges configured credentials into ~/.env for scripts that source it, inside a marked block so anything else in the file survives
  • prints one status line per runbook input, so a session starts knowing what it has and which secrets are missing — names and states only, never values

It is idempotent, guarded on CLAUDE_CODE_REMOTE so it no-ops on a laptop, and always exits 0 — a partial bootstrap should degrade a session, not block it. It never invents a credential: an unset variable is reported, not fabricated. AWS_* is deliberately excluded, since the log-bucket credentials are short-lived STS tokens with their own refresh cycle (runbook §6).

docs/cloud-session-setup.md — the parts that cannot be automated from inside the container: which variables to set on the environment and where, why trial credentials are Modal secrets rather than session variables, that laptop-only scripts have to reach a repo before a session can see them, and the grok install command for when a session actually needs it.

docs/swe-marathon-eval-runbook.md — a pointer from §0 prereqs, where these inputs are first assumed.

Not included

The hook is not registered in .claude/settings.json. That file makes it auto-run for everyone who clones the repo, which is a call for a human to make rather than something to land silently; the snippet is in the doc. Until it is registered the hook is inert.

Validation

  • Hook run end to end in a cloud container: venv built, PATH written, ~/.env written 0600
  • Idempotent — two consecutive runs leave one marked block, and a hand-added line in ~/.env survives ✅
  • Credential values round-trip through source ~/.env intact, including quotes, $, and spaces ✅
  • No-ops with CLAUDE_CODE_REMOTE unset — no output, no files created ✅
  • pytest tests/test_links.py against the venv the hook builds: 34 passed ✅ (fails with ModuleNotFoundError: sqlalchemy without --extra server, which is what pinned that flag)
  • pre-commit run --files <changed>: all hooks pass ✅
  • bash -n: clean ✅ (shellcheck is not installed in this container)

Not validated: the grok install command in the doc. Fetch-and-run was blocked by this session's permission policy, so it is transcribed from OddishGrokBuildAgent.install() rather than executed.


Generated by Claude Code


Note

Low Risk
Mostly docs and an opt-in bootstrap script that is not registered yet. Credential bridging is careful (names only in logs, marked rewrite, 0600 perms) and does not change product auth.

Overview
Adds a remote-only SessionStart hook so Claude Code cloud sessions can run eval runbooks without a manual laptop-style setup pass.

.claude/hooks/session-start.sh rebuilds the missing pieces on CLAUDE_CODE_REMOTE=true: syncs the oddish venv with --extra server, prepends it to PATH via $CLAUDE_ENV_FILE, and bridges configured API keys into a marked ~/.env block (mode 0600). It reports status and missing secrets by name only, never invents credentials, and always exits 0 so a partial bootstrap degrades rather than blocks the session.

Also adds docs/cloud-session-setup.md covering environment variable setup, why trial keys stay as Modal secrets, and on-demand grok install, plus a pointer from the SWE-Marathon runbook prereqs. The hook is not registered in .claude/settings.json yet.

Reviewed by Cursor Bugbot for commit 09ee550. Bugbot is set up for automated code reviews on this repo. Configure here.

The eval runbooks are written against a laptop: a venv at a ~ path, agent
CLIs on PATH, secrets in ~/.env. A Claude Code cloud session has none of
those, so every one of those steps fails verbatim and each session
re-derives the same setup by hand.

Add a remote-only SessionStart hook that rebuilds what can be rebuilt --
syncs oddish/ with the documented --extra server, puts the venv on PATH,
and bridges configured credentials into ~/.env in a marked block -- then
reports one status line per runbook input so a session starts knowing
what it has and which secrets are absent. It never invents a credential
and always exits 0, so a partial bootstrap degrades a session instead of
blocking it.

Document the rest in docs/cloud-session-setup.md, since some inputs
cannot be rebuilt from inside the container: secrets belong to the
environment's variable config, and laptop-only scripts have to reach a
repo before a session can see them. Record that oddish has no ~/.oddish
credentials file -- config.py reads ODDISH_API_KEY/ODDISH_API_URL from
the environment and nothing else -- so that hunt ends at the docs.

The hook is not registered in .claude/settings.json here; enabling a
hook that auto-runs for everyone who clones the repo is a call for a
human to make, and the snippet to do it is in the doc.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NSorCmyqJqywkZF6cKku6n
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
oddish-app Ready Ready Preview Aug 12, 2026 12:48am

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6203df8. Configure here.

Comment thread .claude/hooks/session-start.sh Outdated
Comment thread .claude/hooks/session-start.sh
@cursor
cursor Bot requested review from kyle-compute and stateofkate August 12, 2026 00:44

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Risk: medium. Non-blocking comment only — Cursor Bugbot reported 2 unresolved medium findings that need human attention, so this was not approved. Assigned reviewers for follow-up.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

Two defects found in review, both confirmed in a container.

The two PATH exports were appended in sequence, so the second prepended
onto the result of the first and ~/.local/bin landed ahead of the venv.
That directory ships its own pytest, ruff, black, and mypy -- exactly the
tools this repo tests and lints with -- so `pytest` resolved to the
user-local copy instead of the project's. Emit a single export with the
venv first.

SessionStart also fires on resume, clear, and compact, and
CLAUDE_ENV_FILE persists across those firings, so the unguarded append
stacked another PATH prefix every time a session compacted. Write the
line at most once; three consecutive firings now leave one.

The uv sync still runs on every firing. That is deliberate: it costs
about a second once the cache is warm, and it repairs a venv that is
broken or partially installed -- the state that produced the
ModuleNotFoundError which pinned --extra server in the first place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NSorCmyqJqywkZF6cKku6n
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.

2 participants