Skip to content

Cloud Builder safety: coord scripts refuse under CLAUDE_CODE_REMOTE, ensure-venv on Linux, CLAUDE.md cloud rule - #2434

Merged
wshallwshall merged 4 commits into
mainfrom
claude/xenodochial-euclid-bb7971
Oct 19, 2026
Merged

wshallwshall merged 4 commits into
mainfrom
claude/xenodochial-euclid-bb7971

Conversation

@wshallwshall

Copy link
Copy Markdown
Collaborator

Makes the repo's tooling safe for a Claude Code cloud Builder session (CLAUDE_CODE_REMOTE=true). Three layers, one per commit.

  1. Coordination scripts refuse in the cloud. seat.ps1, mail.ps1, alloc.ps1 and claim.ps1 print one stderr line and exit 3. seat.ps1 exempts its two hook paths, -Record and -Prompt. seat-declare-prompt.ps1 prints a one-line cloud-Builder notice instead of the prompt, stamps nothing, and still exits 0. The reason: in a cloud VM, --git-common-dir resolves to the clone's own .git, so these scripts would otherwise "succeed" into a mefor-coord nobody reads (fleet wiki note 20261018T215116801Z-5lqiqo). tests/conftest.py drops an inherited CLAUDE_CODE_REMOTE, so the existing pwsh suites keep testing the local path inside a cloud VM. The new tests/test_coord_cloud_refusal.py pairs each refusal with a control that takes the normal path.
  2. ensure-venv.ps1 works on Linux. It uses .venv/bin/python off Windows. On Linux -Python defaults to python3.14 when that is on PATH, otherwise to python3. The install line is unchanged, so both parity tests still pass. tests/test_worktree_ensure_venv.py loses its Windows-only gate, so the ubuntu tooling leg now drives the bin/python branch.
  3. CLAUDE.md section 5: "A cloud session is a Builder in its own session". The rule:
    • The session runs on this repo alone. A multi-repo session loads no project hooks.
    • It opens its PR over REST, because the proxy returns 403 for GraphQL.
    • It hands the PR to the Lander with the qa label and a PR comment.
    • It cites its item in the commit body. A subject citation needs a claim, and claim.ps1 refuses in the cloud.
    • It commits under the allowlisted identity.
    • Evidence: probe PR 2432.

Not changed: .claude/settings.json hooks, and no onFailure: block. Related: PR 2433 adds the cloud SessionStart setup hook. Its file set does not overlap this one except possibly at tests/tooling_manifest.txt, on different lines.

Checks run locally (Windows):

  • ruff check and ruff format --check.
  • mypy, all four CLAUDE.md section 7 legs.
  • pytest on test_coord_cloud_refusal, test_worktree_ensure_venv, both venv parity tests, test_tooling_partition, test_coord_seat_prompt, test_session_mail, test_coord_alloc_reentrancy, test_coord_claim_refresh, test_precompact_reprime_hook, test_coord_handoff_clear, test_coord_seat_session_key, and the 125 test files that read CLAUDE.md.
  • One unrelated flake under -n 8 (test_sandbox relay-thread). It passes alone.

Read on CI: the ubuntu repo harness tests leg. It is the first run of test_worktree_ensure_venv.py and of the cloud refusal tests on Linux, and nothing local covered Linux.

Follow-up, not in this PR: other mefor-coord writers still dead-letter in a cloud VM: handoff.ps1, lane.ps1, lock.ps1, owner_log.py, and the korus wiki write.ps1. The deeper fix is one shared coord-root resolver that refuses under CLAUDE_CODE_REMOTE.

QA -- korus roles/BUILDER.md step 11
Level: xhigh, from the brief. Tag: xhigh effort → 10 inline angles → dedup (no verify) → sweep → ≤15 findings.
Rounds: 1. Findings: 6 reported; 5 fixed (Linux-unproven -Record test now Windows-gated, Linux python3 default below 3.14, claim-gate deadlock and git identity missing from the CLAUDE.md rule, brittle exit-3 count); 1 skipped as the follow-up above; 0 open.

In a cloud VM --git-common-dir resolves to the clone's own .git, so
seat.ps1, mail.ps1, alloc.ps1 and claim.ps1 would "succeed" into a
mefor-coord directory no other session reads. Each now prints one
stderr line and exits 3 when CLAUDE_CODE_REMOTE=true. seat.ps1 exempts
its two hook paths, -Record and -Prompt, which must exit 0. The
SessionStart declare-prompt hook prints a one-line cloud-Builder notice
instead of the prompt, stamps nothing, and still exits 0.

tests/conftest.py drops an inherited CLAUDE_CODE_REMOTE so the existing
pwsh suites keep testing the local path inside a cloud VM. New
tests/test_coord_cloud_refusal.py pairs each refusal with a control
that takes the normal path.
It hardcoded .venv\Scripts\python.exe, so it failed on a Claude Code
cloud VM even with pwsh installed. It now uses .venv/bin/python off
Windows, judged by [Environment]::OSVersion so Windows PowerShell 5.1
(no $IsWindows) still reads as Windows, and defaults -Python to python3
there. The install line is unchanged, so both parity tests hold.

tests/test_worktree_ensure_venv.py drops its Windows-only gate and
builds the fixture's site-packages path per platform, so the ubuntu
legs, which carry pwsh, drive the bin/python branch.
Section 5 gains one rule: a Claude Code cloud session is a Builder in
its own session, on MEFORORG/MessageFoundry alone and never with a
second repository attached, because a multi-repo session loads no
project hooks. It opens its PR over REST, since the proxy refuses
GraphQL, and hands it to the Lander with the qa label and a PR comment,
not mail. Evidence: probe PR 2432 and wiki note
20261018T215116801Z-5lqiqo.
@wshallwshall wshallwshall added the qa Builder QA record posted; not a merge gate label Oct 19, 2026
@github-actions github-actions Bot added the ci-red A required check went red. Attribute it before retrying. label Oct 19, 2026
The ubuntu tooling leg errored in the fixture: the template's commit
detached background maintenance, whose .git/objects/maintenance.lock
vanished while copytree walked it. The template now sets
maintenance.auto=false and gc.auto=0, and the per-test copy skips
*.lock files.
@wshallwshall

Copy link
Copy Markdown
Collaborator Author

Lander: enqueued at f9e7726, pinned.

  • Review: the QA line in the PR body (code-review at xhigh, tag printed, 1 round, 0 open) covers the code through 77219a0.
  • The one later commit, f9e7726, is a test-fixture fix: it turns off git background maintenance in the temp template and skips *.lock files in the copy. The Lander read and reviewed it, and it changes no product or script behaviour.
  • The one skipped finding is the follow-up, engine PR 2437, which is stacked on this PR.
  • All 9 live required contexts are SUCCESS on this head.

@wshallwshall
wshallwshall added this pull request to the merge queue Oct 19, 2026
@github-actions

Copy link
Copy Markdown

CI failed in test (windows-2025, py3.14) / Tests (pytest) while this pull request was in the merge queue, so the queue ejected it.

Its own head can still be green: the queue revalidates the merge, and the path gates that skip on a pull request run there. Read the run before retrying.

https://github.com/MEFORORG/MessageFoundry/actions/runs/39328796441

@wshallwshall

Copy link
Copy Markdown
Collaborator Author

Queue ejection triage (author): the one failure in run 39328796441 is tests/test_approval_repeat_request.py::test_repeats_racing_from_two_processes_file_one_request on windows-2025, a child process hitting PermissionError (Windows sharing violation) reading its race-go-* file in pytest's temp dir. This PR touches no engine or approvals code; its only suite-wide change is tests/conftest.py dropping CLAUDE_CODE_REMOTE, which that test does not read. Every leg on head f9e7726 is green, including test (windows-2025, py3.14). No code change made; this reads as a flake in that test, for the Lander to re-enqueue or route.

Merged via the queue into main with commit d18836b Oct 19, 2026
51 checks passed
@wshallwshall
wshallwshall deleted the claude/xenodochial-euclid-bb7971 branch October 19, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-red A required check went red. Attribute it before retrying. qa Builder QA record posted; not a merge gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant