skills/remote-project-control/SKILL.md
Coordinate local, Git remote, and SSH/HPC/RunAI research projects. Use for server state, sync safety, job submission, interactive sessions, logs, artifact lookup, context recovery, raw SSH commands, remote shell one-liners, SSH quoting issues, remote-cmd, remote-bash, or avoiding local shell expansion of remote variables.
npx skillsauth add a-green-hand-jack/ml-research-skills remote-project-controlInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
git rev-parse --git-common-dir vs --show-toplevel. In a project-control-root layout, <ProjectName>/ and <ProjectName>/code/ are independent repos — inspect them separately.memory/BRIEFING.md exists in the project root:
memory/BRIEFING.md — compact project state snapshotmemory/project-conventions.md — active conventions including SSH wrappers, server paths, and scope constraints for this project.agent/worktree-status.md first; write in-progress server state there, not into root memory/.Skipping this step risks using stale server state, wrong environment paths, or violating project-specific SSH wrapper conventions.
Help the user operate a project whose code is edited locally but actually runs on one or more servers over SSH. Establish project memory first, then coordinate safe local, Git remote, and server actions.
Terminology used by this skill:
local: the user's local development machine, usually the Mac where the agent is runningremote or git remote: the Git hosting remote such as GitHub or GitLab, e.g. originserver: an execution machine or cluster reached by SSH, such as quest, ibex-vscode, or epfl-haasThe skill name is historical. In project memory and user-facing summaries, prefer server for SSH/HPC/RunAI execution environments and reserve remote for Git remotes unless quoting an existing field name.
Pair this skill with research-project-memory when server execution state should be linked to project-level experiments, evidence, actions, or worktree status. Pair with run-status-monitor after job submission when lightweight progress checks or artifact-bounded monitoring are needed without pulling raw logs into context.
<installed-skill-dir>/
├── SKILL.md
├── references/
│ ├── memory-model.md
│ ├── operations.md
│ └── ssh-command-wrappers.md
├── scripts/
│ ├── remote-cmd
│ └── remote-bash
├── template_manifest.json
└── templates/
├── infra/remote-projects.yaml
├── docs/ops/current-status.md
├── docs/ops/decision-log.md
└── agent/local-overrides.yaml
references/memory-model.mdreferences/operations.md when the user wants to inspect, sync, run, monitor, or fetch artifactsreferences/ssh-command-wrappers.md before composing SSH commands that include loops, shell variables, command substitution, pipes, globs, find, awk, or multi-line logictemplates/ as the source of truth when bootstrapping memory files into the target projectmemory/, summarize verified server execution facts into research-project-memory boards without duplicating the server manifest.gh, git, ssh, curl, and scheduler/API commands; DNS, timeout, or connection errors in a sandboxed agent runtime must be retried with network permission before diagnosing credentials or configurationgit SSH access: git push may work while gh repo create, gh repo view, or gh repo fork fails because gh is not authenticatedgh may fail to reach api.github.com unless the command is rerun with network permissiongh project ... needs a token with the project scope; refresh it with gh auth refresh -s project before project-board commands when the scope is missing.<ProjectName>/ and <ProjectName>/code/ may be independent Git repos with different remotes and permissionsremote-cmd for simple argv-style server commands and remote-bash for scripts, loops, or anything with shell syntax. See Forbidden SSH Patterns below.Never compose these directly in the transcript or agent command output:
| Anti-pattern | Use instead |
|---|---|
| ssh <alias> "cd <path> && <cmd>" | remote-cmd <alias> <repo> -- <cmd> |
| ssh <alias> "<cmd> $VAR" (shell variable) | remote-cmd <alias> <repo> -- <args> |
| ssh <alias> "<cmd> \| <cmd>" (pipe / loop / find / awk) | remote-bash <alias> <repo> <script> |
| ssh <alias> "<cmd1> ; <cmd2>" (chained) | remote-bash <alias> <repo> <script> |
| ssh A "ssh B '<nested cmd>'" (nested one-liner) | project-local scripts/ops/ wrapper called via remote-bash |
Exception: single-word no-argument commands with no shell syntax are fine (ssh <alias> "pwd", ssh <alias> "hostname").
Why: local shell expands $VAR, ~, globs, and quotes before the SSH command is sent, silently corrupting the intended server-side command. Wrappers quote correctly and keep the transcript clean.
This skill manages four project-memory files with distinct roles:
infra/remote-projects.yaml: stable shared facts such as local repo path, Git remote/branch, server repo mapping, scheduler type, launch modes, key paths, and safety policiesdocs/ops/current-status.md: working memory for the current phase of the project, including active branch, focus, latest known job, open issues, and next stepdocs/ops/decision-log.md: durable explanations for why stable workflow decisions were made.agent/local-overrides.yaml: optional private overrides for one user's machine, ssh aliases, usernames, and private paths; this file should usually be gitignoredIf one or more files are missing, bootstrap them from the bundled templates before trying to infer project context from scratch.
git rev-parse --show-toplevel 2>/dev/null || pwd
<project-root>/infra/remote-projects.yaml<project-root>/docs/ops/current-status.md<project-root>/.agent/local-overrides.yaml<project-root>/docs/ops/decision-log.mdinfra/remote-projects.yaml is missing, bootstrap the project memory using the templates in this skill. Ask only for the minimum critical fields:If .agent/local-overrides.yaml is missing but private overrides are clearly needed, offer to create it and recommend adding .agent/ to .gitignore.
If the project appears to be a control root with component repos, inspect each relevant repo independently instead of assuming one Git remote:
git -C <project-root> remote -v
git -C <project-root>/code remote -v
git -C <project-root>/paper remote -v
Missing remotes in one repo do not imply missing remotes in another.
Merge the loaded files into a concise project context summary. Always show the user a compact bootstrap summary before doing substantial remote work.
Include, when known:
Before any remote action, verify the pieces of state that could have changed since the last session.
At minimum:
git rev-parse --short HEAD
git branch --show-current
git status --short
For the chosen server, verify the server-side repo and git state using the configured ssh_alias and remote_repo_root or server_repo_root:
ssh <ssh-alias> "cd <remote-repo-root> && pwd && git branch --show-current && git rev-parse --short HEAD && git status --short"
For repeated checks, prefer the safer wrapper equivalent:
remote-cmd <ssh-alias> <remote-repo-root> -- git status --short
remote-bash <ssh-alias> <remote-repo-root> scripts/ops/status.sh
If the request involves job submission or monitoring, also verify the scheduler tool and relevant log or output paths on the server.
Choose one of the following flows and follow the detailed guidance in references/operations.md:
bootstrap: create or repair the memory files from templates and fill the minimum required fieldsinspect: compare local and server git state, verify paths, env activation, scheduler availability, and summarize the current situationgit-remote-setup: inspect or create GitHub/GitLab repositories, set remotes, fork upstream repos, link optional GitHub Projects, or prepare local-to-server sync through a Git remotesync-code: prepare local commits, push through the configured Git remote, and update the server repo with non-destructive fast-forward pulls onlyrun-job: use the server context to submit a job safely; if a new reproducible job script is needed, use run-experiment after this skill has established the environmentinteractive-session: prepare the correct salloc, srun, or equivalent command and run subsequent commands from the server repo with the configured environment activationmonitor: inspect queue state and tail logs from the configured log rootsartifacts: locate remote checkpoints, outputs, and logs; do not bulk-transfer large data unless the user explicitly askscloseout: update project memory at the end of a sessionIf the runtime cannot execute SSH commands directly, still use this skill: generate the exact commands in the correct order, explain the assumptions, and keep the memory files up to date.
Before any gh operation that uses GitHub's API, including gh repo ... and gh project ..., run:
gh auth status
Interpret failures carefully:
api.github.com, github.com, or asks to check the internet connection, treat it as network/sandbox access first. Rerun the same gh check with network permission before asking the user to log in again.gh auth status has network access and still reports an invalid token, missing account, or failed login, stop the GitHub API flow and tell the user to re-authenticate with gh auth login -h github.com.For GitHub Projects:
gh auth status shows the project scope before gh project create, gh project view, gh project link, gh project item-*, or gh project field-*.gh auth refresh -s project.gh auth status fails but a network/keyring-enabled check succeeds, treat the normal failure as sandbox or Keychain access, not a real logout.memory/project.yaml when the code repo belongs to a project-control-root layout.Apply the same network-first classification to other commands:
git fetch, git push, git pull, git ls-remote: DNS or connection failure is network/sandbox access until rerun with network permission.ssh <server>: hostname resolution, timeout, or network unreachable is network/VPN/sandbox reachability until rerun with the expected network permission and VPN state.curl, package managers, and scheduler/API CLIs: connection failure is not enough to prove credentials or server configuration are wrong.When new information becomes trustworthy, persist it to the appropriate file:
infra/remote-projects.yamldocs/ops/current-status.mddocs/ops/decision-log.md.agent/local-overrides.yamlIf the repo also uses research-project-memory, write only cross-project pointers:
memory/evidence-board.md: verified job/run pointer for linked EXP-###memory/action-board.md: monitor, fetch-artifact, rerun, or report actionsmemory/current-status.md: latest verified server execution summary and next verification step.agent/worktree-status.md: server run status when tied to a branch/worktree purposeDo not write volatile scheduler output or one-off shell command results into the stable manifest.
Before finishing, update docs/ops/current-status.md whenever the session materially changed project state. Capture:
If a new stable practice was established, add a short entry to docs/ops/decision-log.md.
If a new project-specific SSH/remote convention was established (e.g., a new wrapper alias, a server path, a RunAI pool, a scheduler flag), write it to memory/project-conventions.md under the ssh or compute category. When server infrastructure changes make a convention obsolete, move it to Expired with the reason.
If the project has memory/current-status.md, update it with a concise cross-component pointer rather than copying the full remote status.
When bootstrapping a project, materialize these files from templates/:
templates/infra/remote-projects.yaml -> <project-root>/infra/remote-projects.yamltemplates/docs/ops/current-status.md -> <project-root>/docs/ops/current-status.mdtemplates/docs/ops/decision-log.md -> <project-root>/docs/ops/decision-log.mdtemplates/agent/local-overrides.yaml -> <project-root>/.agent/local-overrides.yaml when private overrides are neededPreserve existing files unless the user explicitly asks to overwrite them.
testing
Bootstrap project-local ml-research-skills. Use from global installs when creating a new ML research project, enabling this collection in an existing ML research repo, or deciding whether to install the full bundle locally. Route to project-init for new projects; do not handle paper or experiment work directly.
development
Route project operations tasks — git, memory, bootstrap, remote, workspace, code review, timeline, ops — to the correct skill. Use when the task involves commits, pushes, worktrees, project memory, enabling project-local skills, SSH/server coordination, sidecar runners, or audits. Do not solve the ops task directly.
testing
Route ML/AI paper writing tasks to the correct skill — contract planning, prose drafting, section writing, consistency editing, review simulation, rebuttal, submission, or citation work. Use when the task involves writing, revising, reviewing, or submitting a paper instead of guessing between paper-writing-assistant, paper-writing-contract-planner, paper-reviewer-simulator, auto-paper-improvement-loop, or citation skills. Do not draft prose directly.
data-ai
Project-local router for ML research skill selection. Use inside an initialized ML research project, or while maintaining this skill repo, when the user describes an ML research/paper/experiment/discovery/ops/release workflow and may not know the skill; route to a domain router or high-signal leaf. Do not use for generic non-ML projects.