Installs into .claude/skills of the current project.
Are you the author of Harness Git Workflow?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/intense-visions-harness-git-workflow)
# Harness Git Workflow
> Worktree setup, dependency installation, baseline verification, and branch finishing. Clean isolation for every workstream.
## When to Use
- When starting work that should be isolated from the main branch (new feature, experiment, multi-task plan)
- When finishing a branch and deciding how to land it (merge, PR, keep, discard)
- When `on_pr` or `on_commit` triggers fire and worktree management is needed
- When the human asks to "set up a branch" or "start a new workstream"
- NOT for simple single-file changes that do not need branch isolation
- NOT when work is already in progress on the correct branch
## Process
**Prompt the human in plain text** — every choice and destructive confirmation in this skill (worktree location, discard-experiment, etc.) is plain text only. Do not elevate to `AskUserQuestion`: option labels like the A/B/C worktree-location choices and natural headers like "Discard commits" routinely exceed its 4-option / 12-char caps and render as ERR.
### Part A: Worktree Creation
#### Step 1: Choose Worktree Location
1. **Check for `.worktrees/` directory** in the project root. If it exists, use it — this is the preferred location.
2. **Check CLAUDE.md or AGENTS.md** for worktree preferences. Some projects specify a custom worktree directory or naming convention. Follow those instructions.
3. **If neither exists, ask the user:** "Where should I create the worktree? Options: (A) `.worktrees/<branch-name>` in the project root, (B) a sibling directory alongside the project, (C) a custom path."
4. **If placing worktrees in the project directory,** verify that the worktree directory is gitignored. Check `.gitignore` for `.worktrees/` or the chosen directory name. If not gitignored, add it before creating the worktree.
#### Step 2: Check for Existing Worktrees
1. **Run `git worktree list`** to see active worktrees.
2. **If a worktree already exists for the target branch,** do not create a duplicate. Ask: "A worktree for branch `<name>` already exists at `<path>`. Should I use it, or create a new branch?"
3. **If the target directory already exists** (but is not a worktree), do not overwrite. Ask the user how to proceed.
#### Step 3: Create Branch and Worktree
1. **Create the branch** from the current HEAD (or from the specified base):
```
git branch <branch-name> <base>
```
2. **Create the worktree:**
```
git worktree add <path> <branch-name>
```
3. **Verify the worktree was created.** Check that the directory exists and contains a `.git` file (not a `.git` directory — worktrees use a file pointing to the main repo).
#### Step 4: Auto-Detect and Run Setup
Inspect the worktree for project files and run the appropriate setup:
| File Found | Action |
| ---------------------------------- | ------------------------------------------------------------------------ |
| `package.json` | `npm install` (or `yarn install` / `pnpm install` if lockfile indicates) |
| `Cargo.toml` | `cargo build` |
| `go.mod` | `go mod download` |
| `requirements.txt` | `pip install -r requirements.txt` |
| `pyproject.toml` | `pip install -e .` or `poetry install` |
| `Gemfile` | `bundle install` |
| `Makefile` (with `install` target) | `make install` |
If multiple project files exist (monorepo), install at the root level. Do not guess which subpackages to install — follow the project's documented setup or ask.
#### Step 5: Verify Clean Baseline
Before any work begins, verify the worktree is in a clean, working state:
1. **Run the test suite.** All tests must pass on the fresh branch before any changes.
2. **Run `harness validate`.** Project health must be green before starting work.
3. **If tests fail or validation fails on the fresh branch,** stop. The base branch has issues. Report: "Baseline verification failed on fresh branch: [failure details]. The base branch needs to be fixed first."
4. **Record the baseline.** Note the test count and validation result. This is the comparison point for the branch finishing phase.
---
### Part B: Branch Finishing
When work on the branch is complete, follow this protocol to land the changes.
#### Step 1: Pre-Finish Verification
1. **Run the full test suite.** All tests must pass.
2. **Run `harness validate`.** Project health must be green.
3. **Check for uncommitted changes.** Run `git status`. All changes must be committed. If there are uncommitted changes, commit or stash them before finishing.
4. **Check the branch is up to date.** If the base branch has advanced since the worktree was created:
```
git fetch origin
git log HEAD..origin/main --oneline
```
If there are new commits on the base, rebase or merge before finishing:
```
git rebase origin/main
```
Re-run tests after rebasing.
#### Step 2: Choose Finishing Strategy
Present 4 options to the user:
1. **Merge locally.** Merge the branch into the base branch on the local machine.
- Best for: small changes, solo work, when CI is not required
- Command: `git checkout main && git merge <branch>`
2. **Push and create PR.** Push the branch to the remote and open a pull request.
- Best for: team work, changes that need review, when CI must pass
- Command: `git push -u origin <branch>` then create PR via `gh pr create`
3. **Keep as-is.** Leave the branch and worktree in place for continued work later.
- Best for: work-in-progress, experiments, paused projects
4. **Discard.** Delete the branch and worktree. All changes are lost.
- Best for: failed experiments, abandoned approaches
- Safety: Confirm with the user before discarding. List the commits that will be lost.
#### Step 3: Execute Chosen Strategy
**If merge locally:**
```bash
cd <main-repo-path>
git merge <branch-name>
# Run tests on main after merge
# Run harness validate after merge
git worktree remove <worktree-path>
git branch -d <branch-name>
```
**If push and create PR:**
```bash
cd <worktree-path>
git push -u origin <branch-name>
gh pr create --title "<title>" --body "$(cat <<'EOF'
## Summary
<PR body with real newlines — never use \n escape sequences>
## Test plan
<checklist>
EOF
)"
# Report the PR URL to the user
# Leave worktree in place until PR is merged
```
**If keep as-is:**
```
No action needed. Report the worktree path and branch name for future reference.
```
**If discard:**
```bash
# Confirm with user first — list commits that will be lost
git worktree remove <worktree-path>
git branch -D <branch-name>
```
#### Step 3.5: Cross-Reference Conventions for Commit Messages and PR Bodies
GitHub auto-links any `#N` token in commit messages, PR titles, and PR bodies to the issue or PR with that number. Treat `#N` as a reserved sigil — never use it for non-issue references.
- **Do not** use `#N` for proposal success criteria, list ordinals, footnote refs, table rows, or any other in-document numbering. Write "criterion 9", "item 9", "step 3" instead. Using `#9` to mean "criterion 9" will silently cross-reference issue #9 — which is almost certainly an unrelated issue — and add a misleading back-reference to that issue's timeline.
- **Do** reference the actual roadmap/tracker issue when finishing work tied to one. Use `Refs #<issue>` for context-only links and `Closes #<issue>` / `Fixes #<issue>` only when the merge should auto-close that issue.
- **Before pushing or opening the PR**, scan the commit messages and PR body for stray `#N` tokens. For each one, confirm it points to the intended issue/PR — or rewrite it as plain text.
#### Step 4: Clean Up
1. **Remove the worktree** (unless keeping as-is or waiting for PR merge):
```
git worktree remove <worktree-path>
```
2. **Prune stale worktree references:**
```
git worktree prune
```
3. **Verify cleanup.** Run `git worktree list` and confirm the removed worktree is no longer listed.
## Harness Integration
- **`harness validate`** — Run during baseline verification (Step 5 of Part A) and pre-finish verification (Step 1 of Part B). Ensures project health is green at both boundaries.
- **Test runner** — Run fresh in the worktree, not in the main repo. Tests must pass both at baseline (before work) and at finish (after work).
- **`.gitignore`** — Verify worktree directory is gitignored if it lives inside the project tree.
## Success Criteria
- Worktree was created in the correct location (`.worktrees/` preferred, or per project convention)
- Dependencies were auto-detected and installed
- Baseline verification passed (tests green, harness validates) before any work began
- Branch finishing strategy was chosen by the user (not assumed)
- Chosen strategy was executed correctly (merge, PR, keep, or discard)
- Worktree was cleaned up after finishing (unless keeping for continued work)
- No stale worktree references remain after cleanup
## Rationalizations to Reject
| Rationalization | Reality |
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "The tests are probably fine on the fresh branch — they were passing on main when I last checked. I'll skip baseline verification and start working." | Baseline verification is the condition that makes branch work trustworthy. A test failure discovered at finish time is ambiguous — it could be pre-existing or introduced by the work. Skipping baseline removes the only clean comparison point. |
| "The user said 'just merge it' — I'll merge without checking if the base branch has advanced since the worktree was created." | The pre-finish check for base branch divergence is mandatory before any finishing strategy. Merging without rebasing first can produce a merge that silently breaks tests that were passing on the branch but conflict with new commits on main. |
| "The worktree directory isn't gitignored, but it's inside a nested folder that's unlikely to be committed accidentally." | The `.gitignore` check is not about likelihood — it is about preventing accidental commits of worktree state that would corrupt the repository. If the worktree directory is not gitignored, add it before creating the worktree. No exceptions. |
| "The user chose to discard — I'll delete the branch and worktree immediately without showing the commits that will be lost." | The discard path requires showing the commit list from `git log main..HEAD --oneline` and receiving explicit confirmation before running `git worktree remove` and `git branch -D`. Work is being permanently deleted; the user must see what they are losing. |
| "There's already a worktree for this branch at a different path — I'll create a second one since the user asked for a fresh setup." | Git does not allow two worktrees checked out to the same branch. Attempting to create a duplicate will fail. Instead, ask the user whether to use the existing worktree or create a new branch. Never assume a second worktree is the right answer. |
| "I'll use `#9` in the commit message to refer to 'success criterion 9' in the proposal — it's obviously an in-document reference." | `#N` is GitHub's reserved syntax for issue/PR links in commits and PR bodies. It will auto-link to issue/PR #9 regardless of intent and post a misleading back-reference on that unrelated issue. Write "criterion 9" (no `#`) and cite the real roadmap issue separately with `Refs #<n>`. |
## Examples
### Example: Setting Up a Worktree for a New Feature
```bash
# Check for preferred location
ls .worktrees/ # exists — use it
# Check gitignore
grep '.worktrees' .gitignore # found — good, already gitignored
# Check existing worktrees
git worktree list
# /Users/dev/project abc1234 [main]
# No existing worktree for this feature
# Create branch and worktree
git branch feat/notifications main
git worktree add .worktrees/notifications feat/notifications
# Auto-detect setup (found package.json)
cd .worktrees/notifications && npm install
# Verify baseline
npm test # 142 tests, all pass
harness validate # passes
# Ready to work. Report:
# "Worktree created at .worktrees/notifications on branch feat/notifications.
# 142 tests passing. harness validate green. Ready to start."
```
### Example: Finishing a Branch with PR
```bash
# Pre-finish verification
cd .worktrees/notifications
npm test # 158 tests, all pass (16 new)
harness validate # passes
git status # clean — all committed
# Check if base has advanced
git fetch origin
git log HEAD..origin/main --oneline
# 3 new commits on main — rebase
git rebase origin/main
npm test # still passes after rebase
# User chooses: Push and create PR
git push -u origin feat/notifications
gh pr create --title "feat(notifications): email and in-app notifications" --body "$(cat <<'EOF'
## Summary
Implements notification service with create, list, and expiry.
## Test plan
- [x] 16 new tests, all passing
EOF
)"
# Report: "PR created: https://github.com/org/repo/pull/42
# Worktree at .worktrees/notifications kept until PR merges."
```
### Example: Discarding a Failed Experiment
```bash
# User says: "That approach didn't work, let's scrap it."
# Show what will be lost
git log main..HEAD --oneline
# a1b2c3d try websocket approach
# d4e5f6g add socket.io dependency
# "These 2 commits will be lost. Discard? (yes/no)"
# Human: "yes"
git worktree remove .worktrees/ws-experiment
git branch -D feat/ws-experiment
git worktree prune
git worktree list # ws-experiment no longer listed
```