Repository navigation
Fix CLI delivery and fresh launch environments for managed SSH agents - #26464
Conversation
Main now bundles the CLI into the server slot and writes a profile launcher on Unix. Drop this branch's parallel CLI packaging, slot launchers, and build-time version; keep the owning-host binding (now exported by main's launcher), the Windows native launcher on main's layout, the Claude command order, and the refreshed shell environment.
…-remote-launch-env
… background Only the first chat start waits for the login shell; later starts get the last snapshot and refresh it in the background once it is 10 s old. On Windows hosts without the registry addon (managed server slots), the saved PATH is reread with reg.exe. The Windows server CLI launcher stager now checks the target architecture, and the CLI help says ambient selectors are ignored inside a managed server.
…he Windows profile once A login-shell capture now says whether the shell produced the env or Orca fell back to its own, and only a real capture replaces the snapshot. Windows loads the PowerShell profile once per process and refreshes only the saved PATH. The reg.exe fallback queries the whole key so a missing user Path no longer drops the saved PATH. The first capture starts when the resolvers are created.
…-remote-launch-env # Conflicts: # src/main/orcad/orcad-cli-launcher.test.ts # src/main/runtime/structured-agent-shell-environment.ts
It only types the chat command resolver it injects; main's launch-routing guard (#26801) matched the name.
… the first run - Any settled cached entry, a fallback included, now serves other readers while a forced capture runs; only a real capture replaces it. - Native chat's first capture shares a run a startup reader already began, so the login shell runs once per process at startup on macOS/Linux. - Type the injected Claude resolver without naming resolveClaudeCommand. - Cover the runtime's Claude command options, the owning-host --host check, and the PTY flag drop.
The persistent terminal daemon merges its own environment into every pane, so an inherited ORCA_CLI_OWNING_HOST reached desktop panes even though main strips it from the spawn env. Drop it with the other per-launch CLI variables.
Review summary (final head
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ➖ Normal Merge Risk: 🔵 Low · up to
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
88ac6d06-ebaf-459d-a671-a859e0ecdade
📒 Files selected for processing (46)
.github/workflows/node-server-tests.ymlconfig/scripts/build-orcad.mjsconfig/scripts/build-windows-cli-launcher.mjsconfig/scripts/build-windows-cli-launcher.test.mjsconfig/scripts/node-server-test-paths.mjsconfig/scripts/orcad-windows-cli-launcher.mjsconfig/scripts/orcad-windows-cli-launcher.test.mjsnative/windows-cli-launcher/src/main.rssrc/cli/index-local-command-routing-flags.test.tssrc/cli/index-test-harness.tssrc/cli/index.tssrc/cli/root-help-text-secondary.tssrc/cli/runtime/client-execution-host.test.tssrc/cli/runtime/client.tssrc/main/claude/claude-structured-child-env.test.tssrc/main/claude/claude-structured-child-env.tssrc/main/claude/claude-structured-launch-resolution.tssrc/main/cli/cli-dev-launcher.tssrc/main/cli/orca-cli-child-path.test.tssrc/main/cli/orca-cli-child-path.tssrc/main/codex/codex-structured-child-environment.test.tssrc/main/codex/codex-structured-session-adapter.test.tssrc/main/daemon/pty-subprocess-env-inheritance.test.tssrc/main/daemon/pty-subprocess/spawn-environment.tssrc/main/ipc/pty-daemon-spawn-agent-home-env.test.tssrc/main/ipc/pty/host-env/assembly.tssrc/main/orcad/orcad-cli-launcher.integration.test.tssrc/main/orcad/orcad-cli-launcher.test.tssrc/main/orcad/orcad-cli-launcher.tssrc/main/orcad/orcad-cli-orchestration.integration.test.tssrc/main/pty/windows-environment-path.tssrc/main/pty/windows-path-registry-reader.test.tssrc/main/pty/windows-path-registry-reader.tssrc/main/runtime/orca-runtime-get-worktree-ps.tssrc/main/runtime/orca-runtime-structured-launch-settings-wiring.test.tssrc/main/runtime/structured-agent-session-runtime.tssrc/main/runtime/structured-agent-shell-environment.test.tssrc/main/runtime/structured-agent-shell-environment.tssrc/main/runtime/structured-claude-runtime-adapter.tssrc/main/runtime/structured-session-child-identity-env.test.tssrc/main/runtime/structured-session-child-identity-env.tssrc/main/startup/login-shell-environment-cache.test.tssrc/main/startup/login-shell-environment.tssrc/shared/cli-execution-host-env.tssrc/shared/orcad-artifacts.test.tssrc/shared/orcad-artifacts.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.
…-remote-launch-env # Conflicts: # .github/workflows/node-server-tests.yml # config/scripts/build-windows-cli-launcher.mjs # config/scripts/orcad-windows-cli-launcher.mjs # config/scripts/orcad-windows-cli-launcher.test.mjs # native/windows-cli-launcher/src/main.rs # src/main/cli/orca-cli-child-path.test.ts # src/main/orcad/orcad-cli-launcher.test.ts # src/main/orcad/orcad-cli-launcher.ts
|
Synced with What changed on
I checked myself:
Checks
The PR body is updated to match. The earlier live SSH QA (Linux container) still describes the user-facing behaviour, since the Linux path is unchanged by this sync. |
…art the first chat after an install The native-chat agent environment now sets the owning server's ORCA_USER_DATA_PATH and empty ORCA_ENVIRONMENT / ORCA_PAIRING_CODE / ORCA_REMOTE_PAIRING, which the CLI already reads as unset; empty rather than deleted, because the spawn merges the launch overlay over the server's own env. The ORCA_CLI_OWNING_HOST flag, the CLI's skip of ambient selectors, the launchers' export of it, the terminal clean-up, the help-text exception and the WSL launcher guard are gone, so a person's terminal follows their own settings as on main. A launch that finds no program in the shell snapshot waits for one shared refresh (at most one shell timeout) and resolves again; create support rereads the shell once before refusing. On Windows a failed PowerShell profile load is retried on the next refresh instead of being kept until restart.
The pre-create check for OpenCode, OMP and Pi forced its own login-shell capture on every refusal: not shared with launches, one per concurrent check, triggered by an installed-but-too-old version too, and an older capture finishing last could overwrite a newer cached environment. On Windows, every launch miss also reran a failed PowerShell profile load, bypassing the 10-second limit. - One saved shell environment per host: chat launches, their misses, the pre-create check and AI commit messages read it and share one refresh. - The pre-create check resolves the agent's program the way a launch does, so only a missing program waits for the refresh; registrations declare how to resolve their launch and check its version. - A forced login-shell capture joins one already running for the same shell, so captures cannot land out of order. - On Windows, a miss within 10 s of a failed PowerShell load rereads only the saved PATH.
Main's #27204 moved every native-chat agent onto one composed launch path. This PR's launch-side changes are carried onto it: - The composer's sources take the runtime's refreshAfterMissingProgram, and the launch basis exposes it; after a refresh its environment reads return the refreshed environment. Each agent's part (Claude, Codex, ACP, Pi) resolves its program through resolveAgainAfterRefreshOnMissingProgram with it, so a launch that finds no program waits for the one shared refresh. - Claude resolves its command from the launch's own environment. - The parity snapshot gains the three remote selectors the seal sets empty; nothing else in it changed.
Review found two more races in the reread-on-miss machinery, both from the host wrapper keeping its own snapshot beside the login-shell cache: - A launch that found no program could join a reread that started before the agent was installed, and spend its one retry on the old PATH. - On Windows, saved-PATH rereads renewed the snapshot's age, so a failed PowerShell profile was never retried while launches kept missing. The login-shell cache is now the only owner of the captured environment, the run in progress and which result wins (the newest run started; a fallback never replaces a captured env). It takes three options instead of `force`: - startedAfter: a lookup that found nothing waits for a run that started no earlier than the lookup did, joining one if it has, else starting one. - refreshAfterMs: serve the last result and rerun in the background once the last attempt is older. - keepCaptured: a captured env is kept for good; only a fallback is rerun (Windows' PowerShell profile). The host wrapper keeps only policy: the 10 s interval, on Windows the saved PATH laid over the profile env on every read (a miss forces a fresh registry read), and the settings overlays. Its snapshot, pending promise, staleness and Windows "loaded" bookkeeping are gone. A lookup's start time travels with the miss (resolveAgainAfterRefreshOnMissingProgram passes it).
The previous commit read an injected environment on every acquisition, which broke main's 'caches shell exports but re-reads configured overrides for a resume' contract. It is read once when the resolvers are made again.
Live QA: the first new chat after installing Claude showed "Claude wasn't found on the computer running this chat". The chat launch itself reread the login shell and started the new binary, but Claude's model-list check ran first, with the environment read before the install, and never retried: catalog probes were deliberately built without the miss refresh. The retry now lives in each agent's one shared lookup of its binary and environment, which a launch and a model listing both call: resolveCodexStructuredInvocation, resolveAcpLaunchInvocation, a new shared resolvePiRpcInvocation, and resolveClaudeChildEnvSources (which already had it). Each catalog probe is given the runtime's refreshAfterMissingProgram, and the catalog context no longer strips it, so a listing and a launch reread the same single-owner environment the same way.
…e extra wait cap CI on the merge with main failed main's new codex-workspace-relative-path test (#26684), which mocks the login-shell module with only resolveLoginShellEnvironment: the wrapper called captureLoginShellEnvironment and imported the spawn-timeout constant. The wrapper only needs the env, so it reads through resolveLoginShellEnvironment again, as on main. The miss wait no longer races its own 5 s timer: the shell run it waits for is already killed at the spawn timeout, so the second cap was a guard over the same bound. The constant goes back to private, as on main.
…-remote-launch-env # Conflicts: # src/main/runtime/structured-agent-runtime-registrations.ts
…-remote-launch-env # Conflicts: # src/main/runtime/structured-agent-launch-composition.ts # src/main/runtime/structured-agent-session-runtime.ts
…l timeout The bound lives in the one owner: the shell run is killed at the spawn timeout (5 s) and settles to a fallback, which never replaces a captured snapshot. A mutation raising that timeout fails this test.
Main's #26684 runs Codex through a workspace-relative PATH entry (`bin`, `node_modules/.bin`). The lookup searches such an entry against Orca's own directory and returns the bare name; the spawn then finds the program in the chat's directory. Counting that bare name as missing made every such launch wait for a login-shell reread. The retry now fires only when the lookup truly found nothing: a bare name back from a PATH whose entries are all absolute. Each agent's one lookup tells it which PATH it searched.
…Windows miss waits for a saved PATH read started after it looked A bare name with a relative PATH entry is checked from the launch's working directory, so an agent in neither entry still gets its one reread. On Windows the miss no longer joins a registry read that began before the lookup.
…-remote-launch-env
Review summary (head
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
🟡 Minor · 🩺 Stability & Availability · windows-environment-path.ts:265-270
src/main/pty/windows-environment-path.ts:265-270
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winThe
windowsHideconcern is refuted. TherunProcesspath resolves spawn options throughspawn-resolution.ts, which setswindowsHide: true.The encoding concern remains supported:
runProcessdecodes captured stdout as UTF-8, while thereg.exefallback supplies Windows console-code-page output. Non-ASCII PATH entries can therefore be decoded incorrectly and become unusable. Convert the registry output using the applicable Windows code page before parsing it, or use a Unicode-safe registry query path.Source: Learnings
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
0b937392-ce08-4139-848e-12e7d9f8bcb4
⛔ Files ignored due to path filters (1)
src/main/runtime/__snapshots__/structured-agent-launch-parity.test.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (42)
config/scripts/build-windows-cli-launcher.test.mjsconfig/scripts/node-server-test-paths.mjsnative/windows-cli-launcher/src/main.rssrc/cli/index-local-command-routing-flags.test.tssrc/cli/runtime/client-execution-host.test.tssrc/main/acp/acp-model-catalog-probe.tssrc/main/acp/acp-structured-launch-resolution.tssrc/main/claude/claude-structured-child-env.tssrc/main/claude/claude-structured-launch-resolution.tssrc/main/codex/codex-structured-child-environment.test.tssrc/main/codex/codex-structured-launch-resolution.tssrc/main/codex/codex-structured-session-adapter.test.tssrc/main/native-chat/structured-agent-command-resolution.tssrc/main/orcad/orcad-cli-launcher.integration.test.tssrc/main/orcad/orcad-cli-launcher.test.tssrc/main/orcad/orcad-cli-orchestration.integration.test.tssrc/main/pi/rpc-launch-resolution.test.tssrc/main/pi/rpc-launch-resolution.tssrc/main/pi/rpc-model-catalog-probe.tssrc/main/pi/rpc-runtime-registration.test.tssrc/main/pi/rpc-runtime-registration.tssrc/main/pty/windows-environment-path.tssrc/main/runtime/orca-runtime-get-worktree-ps.tssrc/main/runtime/structured-agent-install-refresh.test.tssrc/main/runtime/structured-agent-launch-composition.test-support.tssrc/main/runtime/structured-agent-launch-composition.tssrc/main/runtime/structured-agent-launch-support.test.tssrc/main/runtime/structured-agent-launch-support.tssrc/main/runtime/structured-agent-model-catalog-discovery.test.tssrc/main/runtime/structured-agent-model-catalog-discovery.tssrc/main/runtime/structured-agent-model-catalog-first-frame.test.tssrc/main/runtime/structured-agent-runtime-registrations-acp.test.tssrc/main/runtime/structured-agent-runtime-registrations.tssrc/main/runtime/structured-agent-session-runtime.tssrc/main/runtime/structured-agent-shell-environment.test.tssrc/main/runtime/structured-agent-shell-environment.tssrc/main/runtime/structured-claude-runtime-adapter.tssrc/main/runtime/structured-session-child-env.test.tssrc/main/runtime/structured-session-child-env.tssrc/main/startup/login-shell-environment-cache.test.tssrc/main/startup/login-shell-environment.test.tssrc/main/startup/login-shell-environment.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.
…-remote-launch-env # Conflicts: # src/main/native-chat/structured-agent-command-resolution.ts # src/main/startup/login-shell-environment.ts # src/shared/orcad-artifacts.test.ts
The problem
When you open a chat on a remote machine over SSH, Orca installs its own small server on that machine, called the "managed server". The agent, such as Claude, runs there, not on your laptop. Three things went wrong for agents started this way.
1. An agent's
orcacommand could talk to the wrong OrcaAgents use the
orcacommand to reach Orca itself, for example to message their coordinator or check their mail. Main installs that command on managed servers (#26539 for Linux and macOS, #27324 for Windows).Before
orcadoes anything, it decides which Orca to talk to, in this order:--environmentor--pairing-code);ORCA_ENVIRONMENT,ORCA_PAIRING_CODEorORCA_REMOTE_PAIRING);Before: Orca reads the remote machine's shell setup (for example
~/.profile) and passes it to agents. If that setup exportedORCA_ENVIRONMENTor a pairing code, perhaps left over from some other use, an agent'sorcacalls went to whatever Orca that named, not to the server running the agent. Its messages to its coordinator failed.After: agents always reach the server that launched them, and your own settings work normally.
orcaalready reads: the server's data folder, and the three target variables set to empty, whichorcatreats as "not set". A leftover setting in the shell setup can no longer redirect the agent.--environment,--pairing-code) still works for agents.orcain a terminal on that server is not affected: if your shell exportsORCA_ENVIRONMENT,orcafollows it, exactly as on main.2. A custom Claude command on the remote machine was refused
Before: your shell setup on the remote machine usually adds folders to the list of places the system searches for programs (
PATH). Codex and the other agents looked up their program after reading that setup; Claude looked up its program before. So a Claude that only your shell setup could find was reported as not runnable.After: Claude looks up its program the same way, and at the same point, as the other agents.
3. Installing an agent on the remote machine was ignored until Orca restarted
Before: the server read your shell setup once, when it started, and kept that copy forever. Installing an agent, fixing its path, or adding a folder to
PATHdid nothing for new chats until the server restarted.After:
PATHentry such asnode_modules/.bin, which is checked from the chat's folder; a relative entry that doesn't hold the program still counts as not found.PATHright away, not PowerShell. ThePATHthat Windows saves in its settings, which is where installers add themselves, is laid over the profile on every chat start (reread at most every 30 seconds, and when a program is missing, a reread that began after the start looked); after a successful profile read, PowerShell doesn't run again. A Windows server reads that through Windows'reg.exe, because the server doesn't ship the add-on the desktop uses.What you'll notice: after you install or change something on the remote machine, the next new chat picks it up without restarting Orca, including the first chat after installing an agent.
What changed in the code
applyThisAppCliinsrc/main/runtime/structured-session-child-identity-env.tssetsORCA_USER_DATA_PATHto the server's data folder andORCA_ENVIRONMENT,ORCA_PAIRING_CODEandORCA_REMOTE_PAIRINGto empty strings. Empty rather than removed, because every agent process (Claude, Codex, the agents that speak the Agent Client Protocol, Pi) is started over the server's own environment, and a removed variable would come back from there; an empty one wins. Theorcacommand already treats an empty value as unset, so the command itself is unchanged.run_server_cliinnative/windows-cli-launcher/src/main.rs): clearsORCA_WINDOWS_PACKAGED_CLI_LAUNCHER, a marker the desktop's own launcher sets. A server started withorca servefrom the desktop's command line inherits that marker, and then every agent'sorca orchestration askfailed with "The packaged Orca launcher did not provide a valid resume command".src/main/startup/login-shell-environment.tsis the one place the read shell setup lives: the last good copy, the reread in progress, and which result wins (the newest reread started; a failed read never replaces a good one). A caller can ask for a reread that started no earlier than a given time, for the saved copy with a background reread once the last attempt is older than 10 seconds, and on Windows to keep a loaded profile for good.src/main/runtime/structured-agent-shell-environment.tsholds only the policy on top: the 10-second interval, the Windows savedPATHlaid over the profile, and your settings. Chat starts, the pre-create check and AI commit messages all read through it, andrefreshAfterMissingProgramasks for a reread that began after the start looked.resolveAgainAfterRefreshOnMissingPrograminsrc/main/native-chat/structured-agent-command-resolution.tsis the one place that asks for that refresh. Each agent's one lookup of its program and environment calls it (resolveClaudeChildEnvSources,resolveCodexStructuredInvocation,resolveAcpLaunchInvocation,resolvePiRpcInvocation), and both a chat's launch and its model list go through that lookup.structuredAgentSupportsLaunch(the pre-create check) finds the agent's program through that same function, so only a missing program waits for the refresh; the version check then runs on what was found.Why this approach
orcaalready reads. An earlier version of this PR added a separate "this server's own" setting that madeorcaignoreORCA_ENVIRONMENTeverywhere on the server, including a person's deliberate one. Supplying the agent's defaults at the point the server starts it is the common pattern, needs no change to the command, and leaves people's settings alone.orca. Main already shipsorcato managed servers (Provide Orca CLI on managed Linux and macOS servers #26539, fix(orcad): provide the orca CLI in Windows managed-host terminals #27324). This PR adds nothing to how it is delivered.Differences from the common pattern
zsh -lc),orcain that shell follows it. A target named on purpose is unaffected.PATH. Orca reads all your shell setup's variables, and your "inherit shell environment" setting decides which reach chats. That's main's design.Linked Issue
Part of the maintainer-requested managed SSH native-chat fixes; no separate issue. Builds on #26539.
Visual Proof
No rendered UI changes; a live check over SSH shows the user-facing result. Recorded with the build of
81b1f10805f. The only later commit (88aadd422ee) changes how a relative PATH folder and Windows rereads are handled, which this Linux check doesn't exercise.Setup (Docker). The desktop app connected over SSH, as a normal (non-root) user, to a managed Orca server in a Linux container. Before connecting, the user's
~/.profilegot a strayORCA_ENVIRONMENT=qa-bogus-environmentand a bogus pairing code. Claude wasn't installed. Then the real Claude Code CLI (2.1.296) was installed while the server was running, on the login-shell PATH only (a plainshcan't find it). It was not signed in on purpose; no credentials were copied.1. The first new Claude chat after the install starts Claude. It shows Claude's own "isn't signed in" message, which proves Orca found and launched it. There is no "Claude wasn't found" anywhere; on
mainboth the chat and the banner above it said Claude wasn't found until the server restarted.2. A person's terminal on the server honours their own setting. With the profile's stray values,
orca statususes them, so it reports "Unknown environment: qa-bogus-environment", or that both a pairing code and an environment are set. With them cleared, it reaches this server (ok: true, the server's process id,connected).3. The agent's own
orcareaches its own server (checked from the process, no screenshot). In the running Claude process,ORCA_ENVIRONMENT,ORCA_PAIRING_CODEandORCA_REMOTE_PAIRINGare present but empty, overriding the profile.ORCA_USER_DATA_PATHandORCA_CLI_COMMANDare set. With exactly that environment,orca status --jsonreturnsok: truewith the managed server's process id,connected.4. A profile change reaches the next chat without a restart. After adding
export QA_LOGIN_MARK=after-changeto~/.profile, the next new chat's Claude had it.Real x86_64 Linux host with a signed-in Claude. The dev server deployed and ran. Check 3 passed there too, on the real agent process. A real Claude reply could not be shown: that machine's Claude login is currently broken outside Orca as well (a plain
claude -pfrom its login shell fails), so that part is not evidence either way.Testing
Agents reach their own server; people's settings work (problem 1):
ORCA_ENVIRONMENT,ORCA_PAIRING_CODEandORCA_REMOTE_PAIRING, inherited by both the shell copy and the server's own environment, the agent's final environment (through the real spawn merge) names the server's data folder and leaves all three empty. Fails without the change.orcaitself: with an agent's empty values it stays on its own server, while--environmentand--pairing-codestill reach a paired server; with a person'sORCA_ENVIRONMENT,ORCA_PAIRING_CODEorORCA_REMOTE_PAIRINGit goes where that names, as on main.--environmentand--host runtime:<id>routing also checked through the command entry point.ORCA_ENVIRONMENTand pairing code through and adds only the data folder. Fails against the previous head, whose launcher added the "this server's own" setting.orca statusreaches the running server despite stale target variables, and a person'sorca statuswithORCA_ENVIRONMENT=stale-shell-selectionis refused as "Unknown environment: stale-shell-selection", meaning their setting is honoured.build-windows-cli-launchertest).First chat after an install (problem 3):
PATHreaches. Fails without the change.powershell.exechild are faked): a PowerShell profile that fails once is loaded on the next refresh, after which refreshes run no PowerShell. Fails against the previous head.PATHhas a relative entry that doesn't hold it, and not when the entry does (checked from the chat's folder); on Windows, a missing program waits for a saved-PATHread that began after it looked, not one already running from before the install. Both fail against the previous head.reg.exereads with and without a saved userPath, and the measured waits (2-second profile[2053, 0, 2, 0]ms, hung profile[5003, 0, 1, 0]ms).Checks on this head:
Targeted tests: every test file this PR touches, plus the CLI routing, agent environment, login-shell, terminal environment, launch-resolution and pre-create check tests, and main's tests for the files returned to main (167 files, 1716 passed, 10 skipped).
Typecheck: node, cli and web clean.
Real Claude CLI suite: 13/13 (Claude's launch resolver changed).
orca-ci-checks --no-typecheck: 24/25; the one failure is the localtypecheck:cirunner, which needs abun checkscript this machine lacks. Typecheck passes on its own (above).CI on
ff3e9d9183a: 24 passed, 0 failed.SSH Windows hosts(run 38202750986): all four cells passed.Headless Node server(run 38202754321): all 11 jobs passed.Not verified on a real Windows host (CI runners only):
reg.exefallback and the PowerShell retry on a real Windows server.Review
Earlier heads went through several full review rounds. This head reworks problem 1 to the common pattern and adds the two refresh fixes; #26450 should merge first, because without it Claude chats on a managed server can't start, with or without this PR.
Agent skill upstream boundary
Notes
No new RPC parameters, stream frames, settings, credentials, or stored native-chat data. Old server slots without the CLI still start, as in #26539. Folder workspaces do not need Git.
Checklist