---
name: scorpio-commit
description: Manage git branching, staging, and commits with strict safety rules. Determines the appropriate branch, stages changes, creates conventional commit messages, and never touches a protected branch (git.protectedBranches; default main/master). Use after scorpio-execute completes a task, or whenever code changes need to be committed.
---

# Git Commit

A disciplined git workflow skill that automates branching, staging, and committing with strict safety guardrails. This skill ensures good git hygiene while protecting the **protected branches** from accidental commits.

**Protected branches** = `git.protectedBranches` from `scorpio.config.json` (default `[main, master]` when config is absent); the integration branch features merge into is `git.baseBranch` (detected via `origin/HEAD` if config omits it). This skill resolves both from config and treats `main`/`master` only as the fallback default.

## Hard Rules — Never Violate

```
1. NEVER commit to a protected branch (git.protectedBranches; default main/master)
2. NEVER merge anything into a protected branch
3. NEVER create or open pull requests
4. NEVER force push (--force, --force-with-lease)
5. NEVER push without explicit user approval
6. NEVER run destructive commands (reset --hard, clean -f, branch -D)
7. NEVER skip hooks (--no-verify)
8. NEVER amend commits unless the user explicitly requests it
```

If any operation would violate these rules, **stop and explain why** instead of proceeding.

## Branch Safety Protocol

Before any git operation, always check the current branch first:

```bash
git branch --show-current
```

**WARNING**: Subagents and test scripts may switch the active branch as a side effect. Always re-verify the branch before **every** commit, even if you checked earlier in the session.

### If on a protected branch (or `git.baseBranch`):

**Do NOT proceed with any commits.** Instead:

1. Check for an existing feature branch that matches the current work:
   ```bash
   git branch --list
   ```

2. If a matching branch exists, switch to it:
   ```bash
   git checkout [branch-name]
   ```

3. If no matching branch exists, create and switch to a new one:
   ```bash
   git checkout -b [new-branch-name]
   ```

4. Only after confirming you are on a non-protected feature branch, proceed with staging and committing.

### If already on a feature branch:

Confirm the branch name is appropriate for the current work. If it is, proceed. If the work doesn't match the branch (e.g., working on a bug fix while on a feature branch for something else), ask the user before continuing.

### Fresh repo (zero commits yet) — the branch model still applies

A brand-new repo has an **unborn HEAD** (`git rev-parse HEAD` fails): there's nothing to branch from, yet the work **still must not land on a protected branch**. The initial commit is not an exception to the rules — bootstrap deliberately:

1. **Confirm `git.baseBranch` is not itself protected.** If `git.baseBranch` ∈ `git.protectedBranches` (a misconfiguration), **STOP and surface it** — never seed a protected branch.
2. **Put HEAD on `git.baseBranch`** (create it if the default unborn branch has a different name): `git checkout -b <git.baseBranch>`.
3. **Seed the base with an empty root commit** so a base exists to branch from, *without putting any work on it*:
   ```bash
   git commit --allow-empty -m "chore: initialize <git.baseBranch>"
   ```
4. **Branch the feature off it** and do the work there, then merge back into `git.baseBranch` via the normal flow. The issue's deliverable never sits directly on the base via a raw commit; it arrives by merge like every other issue.

Framework scaffolding (the `scorpio.config.json` / `scripts/` / `.claude/` the installer wrote) is a **setup** artifact — fold it into the base-init commit here or commit it at install time. **Never improvise a baseline/scaffolding commit straight onto a protected branch** mid-issue.

## Branch Naming Conventions

Branch names are derived from the task type and identifier:

| Task Type | Branch Pattern | Example |
|-----------|---------------|---------|
| New feature (project) | `feature/[project-or-feature-name]` | `feature/user-authentication` |
| Feature task | `feature/[task-id]-[short-desc]` | `feature/UI-002-share-button` |
| Bug fix | `bugfix/[task-id]-[short-desc]` | `bugfix/BUG-015-login-crash` |
| Rework from QA | Stay on the original branch | (same as the task being reworked) |
| Chore / infra | `chore/[short-desc]` | `chore/update-dependencies` |
| Spike / research | `spike/[short-desc]` | `spike/evaluate-auth-libraries` |

### Naming Rules

- All lowercase
- Use hyphens as separators (not underscores or spaces)
- Keep branch names under 50 characters when possible
- Include task ID when one exists
- Be descriptive but concise

### Rework Branches

Rework tasks from scorpio-qa-rework should **stay on the original feature branch**, not create new branches. The rework is a continuation of the same feature/fix work.

## Staging Rules

### What to Stage

Stage files that are part of the current task's implementation:

```bash
# Stage specific files by name (preferred)
git add path/to/changed-file.ts path/to/new-file.ts

# Stage a specific directory if all changes are relevant
git add src/components/ShareButton/
```

**Always prefer staging specific files by name** rather than using broad commands.

### What to NEVER Stage

| Pattern | Reason |
|---------|--------|
| `.env`, `.env.*` | Contains secrets |
| `*.key`, `*.pem`, `*.cert` | Cryptographic material |
| `credentials.*`, `secrets.*` | Credentials |
| `node_modules/`, `vendor/` | Dependencies (should be in .gitignore) |
| `.DS_Store`, `Thumbs.db` | OS artifacts |
| `*.log` | Log files |
| `*.sqlite`, `*.db` | Local databases |
| Build output (`dist/`, `build/`, `.next/`) | Generated files (unless intentional) |

If any of these are detected in the diff, **warn the user** and exclude them from staging.

### Pre-Stage Checklist

Before staging, always run:

```bash
git status
git diff --stat
```

Review the output to confirm:
1. Only expected files are modified
2. No sensitive files are in the changes
3. No unexpected large files or binaries

## Commit Timing

### When to Commit

| Event | Commit? | Notes |
|-------|---------|-------|
| Task implementation complete (Step 1 of scorpio-execute) | Yes | Commit the implementation |
| Self-QA fixes applied (Step 2 of scorpio-execute) | Yes | Separate commit for QA fixes |
| Rework task complete | Yes | Commit the rework |
| Logical checkpoint within a large task | Yes | If the task touches 5+ files, commit at natural boundaries |
| Mid-implementation, nothing complete | No | Don't commit half-done work |
| QA review (scorpio-qa-final) | No | Read-only phase, no commits |
| Triage (scorpio-qa-rework) | No | Decision phase, no commits |

### Logical Checkpoint Examples

For large tasks, commit at boundaries like:
- Database migration created and tested → commit
- API endpoints implemented → commit
- UI components built → commit
- Tests added → commit

Each checkpoint commit should represent a coherent, non-breaking change.

## Commit Message Format

Use conventional commits format:

```
<type>(<scope>): <description>

[optional body]

[optional footer]
```

### Types

| Type | When to Use |
|------|-------------|
| `feat` | New feature or functionality |
| `fix` | Bug fix |
| `refactor` | Code change that neither fixes a bug nor adds a feature |
| `test` | Adding or updating tests |
| `chore` | Build process, dependencies, config changes |
| `docs` | Documentation only |
| `style` | Formatting, missing semicolons, no code change |
| `perf` | Performance improvement |

### Scope

The scope is the area of the codebase affected. Derive from:
- Task ID if available: `feat(UI-002): add share button component`
- Module name: `fix(auth): handle expired token refresh`
- File area: `test(api): add integration tests for podcast endpoints`

### Description Rules

- Use imperative mood ("add" not "added", "fix" not "fixes")
- Don't capitalize the first letter
- No period at the end
- Under 72 characters
- Describe **what** changed, not **how**

### Body (Optional)

Use for commits that need more context:

```
feat(UI-002): add share button component

Implements copy-to-clipboard and Twitter share functionality
on the episode detail page. Follows existing DownloadButton
pattern for consistent UX.

Task: UI-002
```

### Footer (Optional)

Reference task IDs:

```
fix(BUG-015): prevent null pointer in save handler

Add null check for storage.insert() return value before
accessing result.id.

Fixes: BUG-015
Rework: REWORK-CORE-001-1
```

### Commit Message Examples

```bash
# Feature implementation
feat(CORE-001): add podcast creation API endpoint

# Bug fix
fix(BUG-015): handle null return from storage insert

# Self-QA fix (from scorpio-execute step 2)
fix(CORE-001): correct validation schema for podcast title

# Rework from QA
fix(REWORK-CORE-001-1): add input sanitization to save handler

# Test addition
test(CORE-001): add integration tests for podcast API

# Chore
chore: configure eslint rules for new module

# Multiple files in a logical checkpoint
feat(UI-002): implement share button UI and styles
```

## Complete Commit Workflow

### Step-by-Step Process

```
1. CHECK BRANCH
   └── On a protected branch / baseBranch? → Switch or create branch (see Branch Safety Protocol)
   └── On feature branch? → Verify it matches current work

2. REVIEW CHANGES
   └── git status
   └── git diff --stat
   └── Check for sensitive files

3. STAGE FILES
   └── Stage specific files by name
   └── Exclude sensitive/unwanted files
   └── Verify staged files: git diff --cached --stat

4. CREATE COMMIT
   └── Compose conventional commit message
   └── Include task ID in scope or footer
   └── Commit (without --no-verify)

5. VERIFY
   └── git log --oneline -1 (confirm commit created)
   └── git status (confirm working tree is clean or only has unrelated changes)

6. PROMPT FOR PUSH
   └── Ask user: "Push to remote? (y/n)"
   └── If yes: git push -u origin [branch-name]
   └── If no: Done (commit stays local)
```

### Prompt for Push

After committing, always ask the user before pushing:

```
Changes committed to [branch-name]:
  [commit-hash] [commit-message]

Push to remote? (y/n)
```

**Never push without the user's explicit approval.** If the user says no, the commit remains local and that's fine.

## Integration with Dev-Task-Runner

When used as part of the scorpio-execute workflow:

### After Task Implementation (Step 1)

```
1. Verify branch (switch off a protected branch if needed)
2. Stage files changed during implementation
3. Commit: feat(TASK-ID): [description of implementation]
```

### After Self-QA Fixes (Step 2)

```
1. If self-QA made changes:
   a. Stage the fix files
   b. Commit: fix(TASK-ID): [description of QA fix]
2. If self-QA found no issues:
   a. No commit needed
```

### After Rework (from scorpio-qa-rework)

```
1. Stay on the same branch as the original task
2. Stage rework files
3. Commit: fix(REWORK-TASK-ID): [description of rework]
```

### End of Session

After all tasks in a session are complete:
- Prompt user once to push the branch

## Handling Edge Cases

### Uncommitted Changes on a Protected Branch

If there are uncommitted changes while on a protected branch:

```
1. Stash the changes: git stash
2. Create/switch to the correct branch
3. Apply the stash: git stash pop
4. Proceed with staging and committing
```

### Merge Conflicts

If switching branches produces conflicts:
1. Inform the user about the conflict
2. Do NOT attempt to resolve automatically
3. Ask the user how they want to proceed

### Empty Commits

If `git status` shows nothing to commit after implementation:
- Verify the task was actually implemented (re-check files)
- If genuinely no changes needed, note it and skip the commit

### Multiple Tasks, One Branch

When executing several related tasks on the same branch:
- Create one commit per task (not one giant commit for all tasks)
- Each commit should be atomic and coherent

## What NOT To Do

- Do not use `git add .` or `git add -A` (too broad, risks staging secrets)
- Do not commit to a protected branch under any circumstances
- Do not push without asking the user
- Do not force push for any reason
- Do not amend previous commits unless explicitly asked
- Do not create PRs or merge branches
- Do not run `git reset --hard` or other destructive commands
- Do not modify git config (user.name, user.email, etc.)
- Do not use interactive git commands (`-i` flag)
- Do not combine unrelated changes in a single commit

## Skill Chain

This skill supports the execution layer of all three workflows:

### Typical Integration Point
```
[planning skills] → scorpio-execute + scorpio-commit → scorpio-qa-final → scorpio-qa-rework → scorpio-execute + scorpio-commit (rework)
```

Git operations happen during **scorpio-execute** execution only. QA and triage phases are read-only.
