Skip to content

Cloud session bootstrap and DRAGON_REQUIRE_NATIVE (cloud migration items 1 and 4) - #219

Merged
thejackshelton merged 15 commits into
masterfrom
cloud-bootstrap
Oct 8, 2026
Merged

thejackshelton merged 15 commits into
masterfrom
cloud-bootstrap

Conversation

@thejackshelton

@thejackshelton thejackshelton commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Cloud migration plan (docs/goals/milestone-2-proof/notes/cloud-migration.md), items 1 and 4.

What changed

Item 1, session bootstrap

  • scripts/cloud-setup.sh: exits 0 at once unless CLAUDE_CODE_REMOTE=true (the documented cloud-session marker), so it is a no-op locally. In a cloud session it reads the Node pin from .github/workflows (the one full x.y.z node-version, currently 24.15.0; a major-only pin must match its major, any other value fails), and the pnpm pin from package.json packageManager (10.33.2). It downloads Node from nodejs.org, checks it against SHASUMS256.txt, installs it into ~/.local/share/dragon/node-v<ver>-<platform> (atomic rename, skipped when already there), installs pnpm into that prefix, verifies both versions, then runs pnpm install --frozen-lockfile and pnpm setup:git. It appends the Node bin dir to CLAUDE_ENV_FILE so later Bash commands use it. Only the one summary line goes to stdout (a hook's stdout reaches Claude's context); install output goes to stderr. pnpm installs with npm install --global --prefix "$NODE_HOME"; curl uses --retry-connrefused. set -euo pipefail; every failure names its cause. --print-versions prints the two pins (used by the test).
  • .claude/settings.json (new; no project settings existed): a SessionStart hook with no matcher (every source: startup, resume, clear, compact, fork, since compaction drops CLAUDE_ENV_FILE exports), running bash "$CLAUDE_PROJECT_DIR"/scripts/cloud-setup.sh with a 900 s timeout.
  • pnpm setup:git now also runs git config rerere.enabled false, matching the landing driver's merges; a fresh clone has no rerere cache. scripts/floor-merge.ts exports SETUP_GIT_CONFIG (rerere off, then MERGE_DRIVERS); the landing driver's prepareWorktree sets it, and floor-merge.test.ts "pnpm setup:git sets exactly the git config the landing driver sets" compares setup:git to it. Reason for that test change: it pinned setup:git to exactly MERGE_DRIVERS, so the new rerere line failed it; it still demands exact equality, now with the landing driver's full list, so it is not loosened.

Item 4, no silent native passes

  • DRAGON_REQUIRE_NATIVE (packages/translate/src/native.ts, requireNative): 1 is on; unset, empty or 0 is off; any other value throws. With it on, runTarget (check.ts) throws DRAGON_REQUIRE_NATIVE=1 and native:<target> has no toolchain: <tool> (<reason>) instead of returning blocked (owner tooling); runHostLane (parity lanes.ts) throws likewise. That matches CI's "No native run was blocked (owner tooling)" step, which fails any run whose describe() lines say blocked or name a missing toolchain. runTarget and runHostLane take an explicit require/requireNative so the tests that prove the blocked path (must-fix, lanes) keep proving it whatever the environment says.
  • In a cloud session, cloud-setup.sh writes export DRAGON_REQUIRE_NATIVE=1 to CLAUDE_ENV_FILE first (before reading pins, so it holds even if setup fails), and fails if CLAUDE_ENV_FILE is unset (PM ruling on review of 892a687). Cloud sessions have no Swift or Kotlin, so a lane that runs a native file there fails loudly and must use CI (test-files.yml, separate PR).
  • must-fix "a JDK without kotlinc is blocked too" returned early without a JDK; with DRAGON_REQUIRE_NATIVE=1 that early return now fails. Stricter only; no tolerance, check or test was loosened or removed.

Tests added

  • packages/translate/test/require-native.test.ts: env parsing; env 1 plus a missing JDK/kotlinc (injected lookup) or a missing swiftc (PATH stubbed to an empty dir) throws naming the tool; env unset keeps blocked (owner tooling) with no suites on both targets; a bad value fails rather than reading as off.
  • packages/parity/test/lanes.test.ts: runHostLane with requireNative: true, or env 1, rejects naming the missing Kotlin toolchain; env unset stays blocked.
  • packages/parity/test/cloud-setup.test.ts: --print-versions equals the repo's workflow pins and packageManager; a no-op (exit 0, no output, nothing written to HOME) for CLAUDE_CODE_REMOTE unset, empty, false, 1, TRUE; fails naming the cause for differing full pins (one in a .yaml), a mismatched major, an expression pin, no full pin, a non-pnpm or non-semver packageManager, both with --print-versions and in a cloud session; accepts a +sha512 suffix; rejects unknown arguments; pins the hook entry and the rerere line of setup:git.

Linux path proven in CI

ci.yml's checks job now runs on ubuntu-24.04 (x86_64, the cloud image) and, before setup-node, runs CLAUDE_CODE_REMOTE=true CLAUDE_ENV_FILE=$RUNNER_TEMP/env scripts/cloud-setup.sh twice. Each round sources the env file and checks node -v is the pin, pnpm --version is the pin, DRAGON_REQUIRE_NATIVE=1 is exported, stdout is one line, and pnpm typecheck passes; the first round must install Node and the second must install nothing. Passing run at 579bce9: https://github.com/compiled-run/dragoncss/actions/runs/37736147076/job/113176001692

What passed (macOS, local)

  • After the review fixes: pnpm typecheck; cloud-setup.test.ts (7 tests, now also: the cloud run exports DRAGON_REQUIRE_NATIVE=1 even when a pin fails, fails without CLAUDE_ENV_FILE, hook has no matcher) and pr-review.test.ts: 2 files, 59 tests; actionlint on ci.yml clean; shellcheck clean.
  • After the second commit: pnpm typecheck; ci.yml's suites (vitest run packages/layout packages/dragon: 109 files, 2527 tests; chrome-ports, parity registry-claims, api-floor, floor-merge, macroscope-ignore: 5 files, 51 tests); floor-merge, sorted-merge, land, cloud-setup tests: 4 files, 129 tests.
  • pnpm typecheck
  • vitest run packages/translate/test (all 37 files, including native-swift/kotlin, native-dpr-, every planted- file, must-fix, require-native) plus packages/parity/test/lanes.test.ts, lanes-host-errors.test.ts, chrome-ports.test.ts, packages/parity/test/registry-claims.test.ts, packages/dragon/test/registry-claims.test.ts, cloud-setup.test.ts: 37 files, 481 tests passed (cloud-setup.test.ts re-run after its last edit: 6/6).
  • With DRAGON_REQUIRE_NATIVE=1 exported: test-shards.test.ts, require-native.test.ts, lanes.test.ts, must-fix.test.ts: 4 files, 344 tests passed.
  • shellcheck scripts/cloud-setup.sh clean.
  • Full pnpm test was not run (targeted per task). The Linux install path of cloud-setup.sh (download, checksum, pnpm install) was not executed here (no Linux host or Docker locally); the first cloud session exercises it, and it fails loudly on any step.

🤖 Generated with Claude Code

…Apps kept the host in the scaled window one scene rotation left, so capture trust's OS screenshot showed the wallpaper
# Conflicts:
#	packages/parity/test/device-run.test.ts
…t lanes rerun, so the device records await the landing driver's device run)
…ems 1 and 4)

scripts/cloud-setup.sh, run by the project SessionStart hook only when CLAUDE_CODE_REMOTE=true, installs the Node every
workflow pins and the pnpm of packageManager, then pnpm install --frozen-lockfile and pnpm setup:git, which now also turns
rerere off. DRAGON_REQUIRE_NATIVE=1 turns a native run with a missing toolchain from blocked (owner tooling) into a failure
naming the tool, in runTarget and runHostLane, as CI's "No native run was blocked" step does.
…atch mode)

regen-on-ci.yml takes a sha (patch mode): no push, run-name "regen of <sha>", the combined
outputs.patch uploaded as regen-patch, every cache restored only. land-devices-ci.ts adds the
regen workflow, land-regen/c-<sha> scratch branches and the patch application; land.ts sends its
four regen call sites and the parallel preparations through it.
…then the merge drivers)

floor-merge.test.ts pins pnpm setup:git to exactly what the landing driver sets; rerere.enabled false joins both, so the
exact-equality check stays and covers the new line.
The master warm run no longer yields to patch-mode runs; a regen step cut off (timeout, lost
runner, cancel) is CiUnavailable, only one that completed with failure blames the tree; patch mode
does not use setup-node's saving pnpm cache; DEFAULT_REGEN_WAIT_S covers the 6-round chain; a
commitApart error is CiUnavailable; the regen commit names the CI run; abandonCiRun says CI run.
…_NATIVE=1, prove the Linux path in CI

Review of 892a687: the hook now has no matcher, so it reruns after compact, clear and fork (compaction drops CLAUDE_ENV_FILE
exports); in a cloud session the script writes export DRAGON_REQUIRE_NATIVE=1 to CLAUDE_ENV_FILE first (PM ruling) and fails
without that file; only the summary line reaches stdout; npm --prefix; curl --retry-connrefused. ci.yml's checks job runs on
ubuntu-24.04 and runs cloud-setup.sh twice before setup-node, checking Node, pnpm, the export, typecheck and no reinstall.
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
@thejackshelton
thejackshelton merged commit 3099f7b into master Oct 8, 2026
4 checks passed
@thejackshelton
thejackshelton deleted the cloud-bootstrap branch October 8, 2026 07:10
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