exp-start · git:20260725.d478789 · 2026-07-25 · sha256 326b79d2cb079cb3
exp-start git:20260725.d478789A
Immutable. This exact content is served forever at /api/v1/blob/326b79d2cb079cb3.
--- name: "exp-start" description: "Create or join an experiment branch. Experiments run on short-lived `exp/<slug>` branches in a dedicated worktree. They never merge to `main` and neve" --- # exp-start command Apply this command workflow. Treat any text after its invocation as the command input. Create or join an experiment branch. Experiments run on short-lived `exp/<slug>` branches in a dedicated worktree. They never merge to `main` and never get PRs or issues. Keepers are distilled onto `gh-*` branches via `/gh-issue-push` + `/gh-issue-pop`. Two modes: - **Local-only** (default): the experiment lives entirely on this repository's `origin`. - **Remote-backed** (`--remote`): the experiment additionally syncs two ways with a separate repository through `git subtree` — remote content lives under a deterministic prefix inside the experiment branch, and local changes to that prefix can be pushed back. ## Input $ARGUMENTS Syntax: `<slug> [--remote <url-or-owner/repo>] [--branch <upstream-branch>] [--prefix <path>]` The slug is kebab-case (e.g. `transformer-perf`). `--remote` accepts a full Git URL or `owner/repo` shorthand (normalized to `https://github.com/owner/repo.git`). `--branch` names the upstream branch to sync with (default: the remote's default branch). `--prefix` sets the subtree path (default: `experiments/<slug>`). If no slug is given, ask the user for one. ## Phase 1 -- Validate 1. Validate the slug is kebab-case (`[a-z0-9]+(-[a-z0-9]+)*`). Reject anything else. 2. If `--remote` is given, normalize it: `owner/repo` becomes `https://github.com/owner/repo.git`; URLs pass through. Record `REMOTE_URL`. 3. Confirm we are in the main repo directory, not inside a worktree, and the current branch is `main`: ```bash git branch --show-current ``` If not on `main`, warn the user and stop. Experiment branches are created from the main repo only. ## Phase 2 -- Create or Join 1. Fetch from origin: ```bash git fetch origin ``` 2. Check whether `origin/exp/<slug>` already exists: ```bash git ls-remote --heads origin exp/<slug> ``` ### If the remote branch exists (join) 3a. Create a worktree tracking the branch: ```bash git worktree add ../exp-<slug> exp/<slug> ``` 4a. If the worktree contains `.exp-sync.yaml`, this is a remote-backed experiment: read it and reconstruct the sync remote on this machine (Phase 3 step 2, using the file's `remote_name` and `remote_url`). Report that you joined an existing experiment and print the sync commands from Phase 4. ### If the remote branch does not exist (create) 3b. Create a worktree with a new branch: ```bash git worktree add ../exp-<slug> -b exp/<slug> ``` 4b. Initialize beads inside the worktree: ```bash cd ../exp-<slug> bd init ``` 5b. Commit the initial state: ```bash cd ../exp-<slug> git add -A git commit -m "exp/<slug>: initialize experiment Skill: exp-start Called-by: user" ``` 6b. Push the branch: ```bash git push -u origin exp/<slug> ``` If `--remote` was given, continue to Phase 3. Otherwise skip to Phase 5. ## Phase 3 -- Remote-Backed Setup (only with --remote) All commands run inside the worktree at `../exp-<slug>`. 1. Determine the upstream branch. If `--branch` was given, use it. Otherwise detect the remote's default branch: ```bash git ls-remote --symref <REMOTE_URL> HEAD | sed -n 's|^ref: refs/heads/\(.*\)\tHEAD|\1|p' ``` Record `UPSTREAM_BRANCH`. 2. Add the sync remote under a deterministic name and fetch it: ```bash git remote add exp-<slug>-remote <REMOTE_URL> 2>/dev/null || true git fetch exp-<slug>-remote ``` 3. Add the subtree under the prefix (default `experiments/<slug>`): ```bash git subtree add --prefix=<prefix> exp-<slug>-remote <UPSTREAM_BRANCH> --squash ``` 4. Record the sync metadata so any machine can rejoin and continue syncing. Write `.exp-sync.yaml` at the worktree root: ```yaml slug: <slug> remote_name: exp-<slug>-remote remote_url: <REMOTE_URL> upstream_branch: <UPSTREAM_BRANCH> prefix: <prefix> push_branch: exp/<slug> ``` The `push_branch` is the branch created **in the remote repository** when local subtree changes are pushed back; it follows the same never-merge convention there. 5. Commit and push the metadata and initial subtree state: ```bash git add .exp-sync.yaml git commit -m "exp/<slug>: configure subtree sync with <REMOTE_URL> Skill: exp-start Called-by: user" git push ``` ## Phase 4 -- Ongoing Two-Way Sync (remote-backed) Subtree operations always name the remote and branch explicitly, so plain `git push`/`git pull` stay unambiguous: they talk only to this repository's `origin` and the `exp/<slug>` branch, never to the sync remote. Pull remote updates into the prefix: ```bash cd ../exp-<slug> git fetch exp-<slug>-remote git subtree pull --prefix=<prefix> exp-<slug>-remote <UPSTREAM_BRANCH> --squash git push # share the merged state on origin exp/<slug> ``` Push local subtree changes back to the remote repository: ```bash cd ../exp-<slug> git subtree push --prefix=<prefix> exp-<slug>-remote exp/<slug> ``` This creates or updates branch `exp/<slug>` in the remote repository. It never touches the remote's default branch; landing changes there is the remote repo's own review flow, out of scope here. ## Phase 5 -- Report Print the worktree path and the convention reminders: ``` Experiment ready at ../exp-<slug> (branch exp/<slug>). <if remote-backed:> Syncing with <REMOTE_URL> (<UPSTREAM_BRANCH>) under <prefix>/. pull: git subtree pull --prefix=<prefix> exp-<slug>-remote <UPSTREAM_BRANCH> --squash push: git subtree push --prefix=<prefix> exp-<slug>-remote exp/<slug> Reminders: - Never merge exp/* to main. Never open a PR or GitHub issue from it. - Treat every push as potentially permanent — no secrets or sensitive data. Remote-backed: subtree pushes land in the OTHER repository and survive local cleanup. - To keep a result, distill it onto a gh-* branch via /gh-issue-push + /gh-issue-pop. - To conclude the experiment, run /exp-stop <slug>. - On other machines, run /exp-start <slug> to join this experiment (remote-backed sync reconstructs itself from .exp-sync.yaml). ```