Skip to content

Cloud sessions: a cloud-only SessionStart hook installs pwsh and Python 3.14 and sets the git identity - #2433

Merged
wshallwshall merged 1 commit into
mainfrom
claude/quirky-gould-2ecdf1
Oct 19, 2026
Merged

wshallwshall merged 1 commit into
mainfrom
claude/quirky-gould-2ecdf1

Conversation

@wshallwshall

Copy link
Copy Markdown
Collaborator

What

A cloud-only SessionStart hook, scripts/hooks/cloud-setup.sh, wired in .claude/settings.json. Because the tracked settings file is what every cloud session clones, it covers all of the owner's accounts with no per-account cloud-environment setup.

In a Claude Code cloud VM (CLAUDE_CODE_REMOTE=true) the hook:

  • installs pwsh from packages.microsoft.com. Without it, every repo hook fails to start, and the blanket-stage, API-burn and filesystem-scan guards are off;
  • installs Python 3.14 with uv, because the image ships 3.13;
  • sets the clone's git identity to the pushing GitHub account's own noreply address, read from gh api user. The default cloud identity fails the required cla check (wiki note 20261002T125230275Z-0glfkb, PR 1926). The address is never a fixed name;
  • re-runs the role card when pwsh was only just installed. The role-card hook resolves the seat itself; this hook supplies none;
  • prints one line naming what is off for each failure, and always exits 0.

Locally, the inline gate exits before the script is read. shell: bash runs it through Git Bash on Windows, and bash is not on the PATH there, so exec form would have failed to start in every local session.

The settings contract test now splits shell-form commands, scans .sh references and classifies .sh hook scripts. It has a planted control for the shell-form case.

Evidence

A probe cloud session on 2026-10-19 (PR 2432, closed) measured these:

  • pwsh installed in 17 s and Python 3.14 in 3 s, running as root;
  • the guards deny git add -A under pwsh;
  • gh pr returns 403 (GraphQL);
  • cla passes with an allowlisted identity.

The evaluation is at cloud-sessions-evaluation.md in the Manager's shared notes folder.

Not verified

  • Whether project hooks fire in a cloud session at all. The probe started with no repo attached, so this result was inconclusive. The docs say a single-repo session loads them. The re-test is a cloud session created with this repo selected.
  • Whether gh api user works through the cloud proxy. If it does not, the hook says so and leaves the identity, and cla refuses as before.
  • The venv is not built here. ensure-venv.ps1 does not run on Linux yet; a sibling session is fixing that. A full install can outrun a hook timeout, which would drop all of this output.

Checks

  • ruff check and format: clean. mypy (tests leg): clean. bash -n: clean.
  • pytest: 212 passed. The run covered test_cloud_setup_hook, test_claude_settings_contract, test_role_cards, test_tooling_partition and test_shell_guard_dispatch, with Git Bash on PATH so the bash tests ran rather than skipped.
  • pre-commit: all hooks passed.
  • code-review at xhigh, one repair round: 14 findings, 10 fixed and 4 skipped. The skipped four are Windows boxes without Git Bash, the unpinned Microsoft .deb (the documented install route, with a signed apt repo behind it), one bash spawn per local session start, and textual placeholder substitution. The QA comment has the detail.
  • Legs to read after push: the ubuntu and windows tooling legs, which run the bash tests.

…on 3.14 and sets the git identity

A Claude Code cloud VM ships no pwsh, so every repo hook fails to start
and the shell guards are off. Its Python is 3.13, and its commits use an
identity the required cla check refuses. Cloud environments are set per
account in the claude.ai UI, but this repo's settings.json reaches every
account.

scripts/hooks/cloud-setup.sh is a no-op unless CLAUDE_CODE_REMOTE=true,
gated inline as well. It installs pwsh, then Python 3.14 through uv. It
commits as the pushing GitHub account's noreply (gh api user), never a
fixed name. It re-runs the role card when pwsh is new, guesses no seat,
and builds no venv. Every failure prints what is off; it exits 0.

The settings contract now splits shell-form commands, scans .sh, and
classifies .sh hooks, with a planted control. Probe: MEFORORG/MessageFoundry
PR 2432.
@wshallwshall wshallwshall added the qa Builder QA record posted; not a merge gate label Oct 19, 2026
@wshallwshall

Copy link
Copy Markdown
Collaborator Author

QA: code-review skill at level xhigh (tag printed: xhigh effort → 10 inline angles → dedup (no verify) → sweep → ≤15 findings), against the staged diff, with docs/REVIEW-STANDARDS.md applied. Head reviewed: debb7d9, after the rebase. The rebase changed no line in the reviewed files except the settings.json context.

There were 14 findings and one repair round.

Fixed (10):

  • The hardcoded owner identity would have let any cloud commit pass cla. It now uses the pushing account's own noreply, from gh api user.
  • The ensure-venv call was known-broken on Linux; it is removed.
  • The venv build in the hook risked a timeout that drops all output; it is removed.
  • The origin URL match was unverified; it is removed.
  • The statusMessage understated what the hook does.
  • There was no planted control for the shell-form split.
  • .sh hooks were outside the wired-or-unwired invariant.
  • The identity branches had no test; stubbed tests are added.
  • The probe timings were restated in two places.
  • A shlex ValueError crashed every contract test.

Skipped (4), with reasons:

  • Windows without Git Bash. Exec-form pwsh cannot start in the cloud, and every SessionStart hook here already assumes a local toolchain.
  • The unpinned packages-microsoft-prod.deb. It is Microsoft's documented route, and the apt repo it adds is GPG-signed; a pinned checksum would break on every upstream rotation.
  • One bash spawn per local SessionStart. It is small next to the three pwsh hooks.
  • The test models env expansion, not Claude Code's textual placeholder substitution. It is unmeasured either way.

@wshallwshall

Copy link
Copy Markdown
Collaborator Author

Lander: enqueued at debb7d9, pinned. This is a priority, at the owner's request.

  • Review: the QA comment of 19:27:54Z (code-review at xhigh, tag printed) names this head.
  • The four skipped findings are filed as vault #3883, in open vault PR 2543. Graded non-blocking: none changes behaviour against main or weakens a control, because the hook runs only when CLAUDE_CODE_REMOTE is true. That grade is a Lander decision under the owner's Driver delegation, not an owner ruling.
  • All 9 live required contexts are SUCCESS on this head. The repo harness legs (ubuntu-latest, windows-2025), which run the bash tests, are SUCCESS too. No check is non-green.
  • After the merge, the new SessionStart hook in .claude/settings.json takes effect for every session that starts on the new main.

@wshallwshall
wshallwshall added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit 45c5ebc Oct 19, 2026
51 checks passed
@wshallwshall
wshallwshall deleted the claude/quirky-gould-2ecdf1 branch October 19, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

qa Builder QA record posted; not a merge gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant