# Gh Weld Adopt

> Formalizes untracked work into the GitHub loop — reads session context and git state, creates a structured GitHub issue, creates or renames a branch to match repo conventions, commits loose changes, pushes, and exports the session as a Gist comment on the new issue. This is the forward path for same-session work: when you decide to implement something now without filing an issue first, adopt creates the issue + branch + commit in one step (you don't have to use gh-weld-issue then gh-weld-next). Works equally retroactively on ad-hoc work already done, and from any branch including main (moves uncommitted changes or ahead-commits to a new branch). Use when: you're implementing work this session that has no issue yet, you started work without creating an issue first, or when the user says 'adopt this work', 'track what we're building', 'create an issue for what we're doing', 'formalize this branch', 'retroactively track this', 'adopt this cleanup', 'adopt this chore'.

- Skill: `wrathza/gh-weld-adopt` (Agent Skill)
- Install (CLI): `npx skillmds@latest add wrathza/gh-weld-adopt`
- Raw SKILL.md: https://api.skillmd.com/api/skills/wrathza/gh-weld-adopt/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: WrathZA (https://skillmd.com/u/wrathza)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/wrathza/gh-weld-adopt

---


# gh-weld-adopt

You did the work first — or you're about to. Either way, gh-weld-adopt creates the paper trail.

## NEVER

- **NEVER proceed adoption from `main` when working tree is clean and no commits are ahead of `origin/main`**
  **Instead:** Output "Nothing to adopt — working tree is clean and main is up to date." and stop.
  **Why:** There is genuinely nothing to adopt — adoption requires loose work to formalize.

- **NEVER create the issue before confirming the summary with the user**
  **Instead:** Show the synthesized summary and proposed issue body; wait for (a)ccept before calling `gh issue create`.
  **Why:** The issue is permanent. A wrong title or misattributed scope creates backlog noise that outlasts the session.

- **NEVER commit without showing what will be staged**
  **Instead:** Display `git status --porcelain` output and ask "(a)ccept / (s)kip" before staging anything.
  **Why:** Unintended files (`.env`, build artifacts) committed here will be pushed and visible in the GitHub issue thread.

- **NEVER commit with a generic subject like `adopt: capture in-progress work for issue #<N>`**
  **Instead:** Derive the subject from the issue title created in Step 4 — `<type>: <what changed>`.
  **Why:** Adopt branches usually carry a single commit, and GitHub's squash-merge inherits that commit's subject over the PR title. A generic subject lands on `main` permanently and says nothing about what changed.

- **NEVER pass a body with `#`-prefixed lines as an inline `--body` argument**
  **Instead:** Write to `.weld/tmp/adopt-issue-body.md` with the Write tool and pass via `--body-file`.
  **Why:** `#`-prefixed lines trigger Claude Code's security check on every execution, interrupting the agent mid-flow.

- **NEVER skip deleting the old remote branch after rename**
  **Instead:** After pushing the new branch name, run `git push origin --delete <old-name>` if the old remote existed.
  **Why:** GitHub shows both branches as linked to the issue — the stale name creates ambiguity in the development sidebar.

- **NEVER skip the session export**
  **Instead:** Always invoke `/gh-weld-export` with the new issue number as context after pushing.
  **Why:** The Gist comment is the audit trail — it proves what was already done before the issue was created.

## Workflow

### 1 — Handle if on main

```bash
git branch --show-current
```

If the result is `main` or `master`:

Check for uncommitted changes:

```bash
git status --porcelain
```

Check for commits ahead of remote:

```bash
git log origin/main..HEAD --oneline
```

**If neither has output:** output "Nothing to adopt — working tree is clean and main is up to date." and stop.

**If both are present:** follow the uncommitted-changes path below — the ahead-commits carry over automatically since HEAD is preserved.

The branch created here is a **provisional throwaway** — Step 6 renames it to the final `<prefix>/<issue-number>-<slug>` once the issue number is known. Do not prompt for a name here; generate one silently and just inform the user it's temporary.

**If uncommitted changes exist:**

Generate a temporary local branch name silently — `adopt/wip-<short-slug>`, where `<short-slug>` is a brief slug derived from the session work (lowercase, hyphens). Do not prompt.

```bash
git checkout -b adopt/wip-<short-slug>
```

Tell the user: "Working on provisional branch `adopt/wip-<short-slug>` — I'll rename it to the final name once the issue exists."

Continue to Step 2.

**If commits are ahead of `origin/main`:**

Generate a temporary local branch name silently — `adopt/wip-<short-slug>` (lowercase, hyphens). Do not prompt.

Create the branch at the current HEAD, reset main, then check out the new branch:

```bash
git branch adopt/wip-<short-slug>
```

```bash
git reset --hard origin/main
```

```bash
git checkout adopt/wip-<short-slug>
```

Tell the user: "Working on provisional branch `adopt/wip-<short-slug>` — I'll rename it to the final name once the issue exists."

Continue to Step 2.

### 2 — Read working state

Run each as a separate Bash call:

```bash
git status --porcelain
```

```bash
git log main..HEAD --oneline
```

```bash
git diff main..HEAD --name-only
```

Save the current branch name — you'll need it to detect and delete the old remote after renaming.

### 3 — Synthesize and confirm

Before synthesizing, ask:
- Does the diff scope match the session discussion, or are there changes outside the stated work?
- Does this read as a bug fix, feature, or chore?
- Are there uncommitted files that should NOT be part of this issue (build artifacts, unrelated edits)?

From **session context** (what has been discussed and built in this conversation) and the git output above, synthesize:

- A proposed issue title (one line, imperative mood)
- The work type (bug / feature / chore) — use this to frame the issue title and acceptance criteria; for the branch prefix, use whatever pattern was inferred from `git branch -a` above
- A structured issue body (see template below)

Before naming the type, inspect the repo's existing branch names to infer the local convention (skip if already run in Step 1 — reuse that result):

```bash
git branch -a
```

Look for patterns in existing branches (e.g. `fix/`, `feat/`, `feature/`, `bugfix/`, `chore/`, no prefix at all). Match whatever convention the repo already uses. If no pattern is apparent, use no prefix. Do not impose a convention the repo hasn't adopted.

Show the synthesis to the user:

```
Here's what I see you working on:

**Title:** <proposed title>
**Type:** <bug / feature / chore>

**Body preview:**
<body>

(a)ccept / (e)dit / (q)uit
```

- `a` — proceed to Step 4
- `e` — user provides corrections; update and loop
- `q` — abort

**Issue body template:**

```markdown
## Summary

<2–3 sentence description of what is being built and why>

## Acceptance Criteria

- [ ] <verifiable criterion — names a command, visible change, or measurable value>

## Blockers

None

---
*Created with [gh-weld](https://github.com/WrathZA/github-weld)*
```

Acceptance criteria must be verifiable. Reject vague entries like "works correctly" — they must name a command, visible change, or measurable value.

### 4 — Create the issue

Write the confirmed body to `.weld/tmp/adopt-issue-body.md` using the Write tool.

Apply the appropriate label if it exists in the repo:

```bash
gh label list
```

Create the issue, redirecting output to capture the URL:

```bash
gh issue create --title "<title>" --label "<label>" --body-file .weld/tmp/adopt-issue-body.md > .weld/tmp/adopt-issue-url.txt
```

If the label doesn't exist, omit `--label`.

Read `.weld/tmp/adopt-issue-url.txt` with the Read tool to get the issue URL. Extract the issue number from the URL (it appears as `.../issues/<N>`).

Clean up:

```bash
rm .weld/tmp/adopt-issue-body.md
rm .weld/tmp/adopt-issue-url.txt
```

### 5 — Commit uncommitted changes

Check for loose work:

```bash
git status --porcelain
```

If output is non-empty, show it and ask:

```
These changes will be committed and pushed:
<git status output>

(a)ccept / (s)kip
```

If accepted:

```bash
git add .
```

Derive the commit subject from the issue title created in Step 4 — never a generic "adopt:" subject. When a branch has a single commit, GitHub's squash-merge inherits that commit's subject rather than the PR title, so this message is what lands on `main` permanently.

Format the subject as `<type>: <what changed>`, where `<type>` is the conventional-commit type matching the issue's label (`fix`, `feat`, `docs`, `chore`, `refactor`, `test`). Rewrite the issue title into an imperative description of the change; keep it under 72 characters. Do not append the issue number — `gh-weld-ship` appends the PR number at squash time, and `Closes #<N>` in the PR body links the issue.

```bash
git commit -m "<type>: <what changed>"
```

Examples, given the issue title in hand:

| Issue title | Commit subject |
|---|---|
| `Adopt commit message destroys the main log` | `fix: derive adopt commit subject from the issue title` |
| `Add activity digest skill` | `feat: add gh-weld-activity digest skill` |
| `README setup steps are out of date` | `docs: update README setup steps` |

### 6 — Rename the branch

Construct the new branch name using the prefix convention inferred from `git branch -a` (Step 3), the issue number, and a slug derived from the issue title. Slug rules: lowercase, hyphens only, max 40 chars. The final form is `<prefix>/<issue-number>-<slug>`.

This is the **only** branch-name approval prompt in the workflow. Show the final name and ask: "(a)ccept or enter a different name?" Use the result for the rename below.

Check whether the current branch has a remote tracking branch:

```bash
git rev-parse --abbrev-ref --symbolic-full-name @{u}
```

If this succeeds, record the old remote branch name (strip the `origin/` prefix). If it fails (no upstream), there's nothing to delete after rename.

Rename locally:

```bash
git branch -m <new-branch-name>
```

### 7 — Push

```bash
git push -u origin <new-branch-name>
```

If an old remote branch existed, delete it:

```bash
git push origin --delete <old-branch-name>
```

### 8 — Export session

Invoke `/gh-weld-export` with the issue number as context. This exports the current session transcript, uploads it as a secret Gist, and posts a structured summary comment on the issue.

### 9 — Output

```
Adopted.

Issue:  <issue-url>
Branch: <new-branch-name>
```

Done.

## Errors

| Situation | Action |
|-----------|--------|
| On a non-main branch, `git log main..HEAD` is empty (branch exists but no commits ahead of main) | Warn "Branch has no commits ahead of main — loose changes only. Continue? (y/n)" |
| `gh issue create` fails | Surface the error; do not rename the branch or push (nothing to link to yet) |
| `git push --delete` fails on old remote name | Warn "Could not delete old remote branch `<name>` — delete it manually via GitHub." and continue |
| `git branch -m` fails because new name already exists | Output the conflict and ask the user for an alternative branch name |
| `/gh-weld-export` fails | Warn "Session export failed — adopt is otherwise complete." and output issue URL and branch name |

