# Filing Pull Requests

> **Related**: [filing issues](./filing-issues.md), [versioning](./versioning.md), kernel skill `aiwg-pr` (run `aiwg show skill aiwg-pr`)

A high-quality PR is focused, verified, policy-compliant, and reaches `main` with green CI. This guide covers the AIWG-specific delivery rules — branching strategy, the no-attribution rule, the CI-green-before-done discipline, and the release-time obligations.

---

## Pre-flight: delivery policy

**Before you create a branch or open a PR**, read the project's `.aiwg/aiwg.config` `delivery.mode`. Three modes, three workflows:

| Mode | Branch | PR | Closing |
|---|---|---|---|
| `direct` | No — commit straight to `default_branch` | **No PR** | `Closes #N` in commit message |
| `feature-branch` | Branch per issue | No PR | `Closes #N` in commit on the branch |
| `pr-required` | Branch per issue | **Required** | `Closes #N` in PR body |

```bash
aiwg config get --project delivery.mode
# or
cat .aiwg/aiwg.config | jq -r '.delivery.mode'
```

**If `mode: direct`, do not open a PR.** Commit directly to `main` with `Closes #N` in the message. The [`delivery-policy`](https://github.com/jmagly/aiwg/blob/main/agentic/code/addons/aiwg-utils/rules/delivery-policy.md) rule (kernel rule, always loaded) is authoritative.

The AIWG repo runs in `direct` mode — the May-2026 fix sweep (commits `6500e167`, `497fcca7`, `3f2b557b`, `d052aa2f`, `a50c1d76`, `ac61a2b8`) landed straight to `main` with `Closes #N` per commit.

---

## The walkthrough

### 1. Find or file the issue first

Every PR closes (or refs) an issue. If you don't have one:

- Search for existing matches: `aiwg run skill steward-prep-delivery -- "<topic>"`
- If none match, file via [filing issues](./filing-issues.md) before drafting the PR

### 2. Branch (only for non-direct modes)

```bash
git checkout -b fix/{issue-number}-{slug}
# slug: short, lowercase, hyphenated derivation of the issue title
```

For `direct` mode, skip this step.

### 3. Make the change

Stay focused on the linked issue. Anti-patterns to avoid:

- **"While I'm at it"** — adding unrelated changes. Split into separate PRs/commits.
- **Reformatting unrelated files mid-PR** — send formatting as its own PR.
- **Adding new dependencies without justification** — note why in the PR body.

### 4. Verification (REQUIRED before commit)

| Check | Command | Pass criterion |
|---|---|---|
| Typecheck | `npx tsc --noEmit` | Clean (no output) |
| Tests | `npm test` | All pass (or only pre-existing flaky perf tests fail; document the latter) |
| Lint | `npm exec markdownlint-cli2` (for docs) | Clean |
| Build | `npm run build:cli` | Succeeds (catches `dist/` vs `src/` path drift) |

Don't skip these. The CI-failure-then-fix cycle in `497fcca7` → `3f2b557b` was caused by skipping the local test run before push. Two pushes, one wasted CI cycle, easily prevented.

### 5. Commit message

Use **conventional commits**: `type(scope): subject`

```
fix(area): one-line subject

Body explains WHY, not just what. The diff already shows what.
Reference the linked issue; for `direct` mode include `Closes #N`
so the issue auto-closes on push.

Verification:
- npx tsc --noEmit clean
- npm test — 6306 pass, 1 pre-existing flake (cli-perf cold-start)
- Manual: <smoke-test description>

Closes #N
```

Conventional commit types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `ci`, `build`. Scope is the area (e.g., `steward`, `sdlc,release`, `cli,docs`).

### 6. No AI attribution

The project [no-attribution rule](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/no-attribution.md) is universal across platforms. The commit/tag/PR body **must not** contain:

- `Co-Authored-By: Claude <…>` (or any AI tool)
- `Generated with [Claude Code]` / "Generated by Codex" / "Written by GitHub Copilot"
- 🤖 emoji or any tool branding

The AI is a tool. Tools don't sign their output.

### 7. Push

```bash
# For direct mode
git push origin main

# For feature-branch / pr-required
git push origin fix/{issue-number}-{slug}
```

### 8. Open the PR (only for pr-required mode)

Use the template at [`.gitea/pull_request_template.md`](https://git.integrolabs.net/roctinam/aiwg/src/branch/main/.gitea/pull_request_template.md) (or [`.github/pull_request_template.md`](https://github.com/jmagly/aiwg/blob/main/.github/pull_request_template.md)). Required sections:

- **Summary** — one paragraph: what changed and why
- **Linked issues** — `Closes #N` / `Refs #N`
- **Changes** — bullets of meaningful changes (not file count)
- **Verification** — filled-in checklist showing typecheck/test/CI status
- **Risk and rollback** — even if "low / git revert"
- **Policy reminders** — delivery mode + no-attribution + CI-green-before-done

The body should be **agent-readable**: clear sections, specific paths, no marketing speak.

### 9. CI green before done

A commit isn't done until CI is green. After push, wait for the run on `origin` (Gitea). AIWG CI takes ~2 minutes.

If it fails:

1. Diagnose the failure
2. **Fix the underlying issue** — no `|| true`, no `continue-on-error: true`, no test deletion. See [`anti-laziness`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/anti-laziness.md) and [`dev-pipeline-safety`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/dev-pipeline-safety.md) rules.
3. Commit the fix and wait again
4. Don't declare the work done until green

**Never leave `main` in a red state.**

### 10. After merge (pr-required) or push (direct)

- The linked issue auto-closes via `Closes #N`
- If you imported a cross-tracker report, **thank the original reporter** in a closing comment on the source tracker (see [filing issues § import flow](./filing-issues.md#import-flow-cross-tracker-reports))
- Update [`CHANGELOG.md`](https://github.com/jmagly/aiwg/blob/main/CHANGELOG.md) if the change is user-visible — for releases, the [`flow-release`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/skills/flow-release/SKILL.md) skill handles this; for individual PRs that ship before the release, append to the unreleased section

---

## Release-time PRs

When the PR is part of a release sequence, the [`flow-release` skill](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/skills/flow-release/SKILL.md) handles the orchestration. The PR itself follows the same rules as any other PR, but the release flow adds extra gates:

- Version bump (`package.json` + `CHANGELOG.md` + `docs/releases/v{version}-announcement.md`)
- UAT for stable channel: `npm run uat` — all 9 tests must pass
- Tag creation, push to origin, optional GitHub mirror push
- npm dist-tag promotion

See [`flow-release`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/skills/flow-release/SKILL.md) for the full sequence. The `.aiwg/release.config` declares which gates apply.

---

## Anti-patterns to avoid

- **AI attribution lines** — never. Universal rule.
- **`--no-verify` or `--no-gpg-sign`** — never bypass hooks. Fix the underlying issue.
- **`continue-on-error: true` on tests** — never silence the smoke detector. See [`dev-pipeline-safety`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/dev-pipeline-safety.md).
- **Skipping CI green wait** — if CI fails, fix it before declaring done.
- **Bundling unrelated changes** — split into focused PRs.
- **Workarounds instead of root-cause fixes** — see [`anti-laziness`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/anti-laziness.md) Rule 9: "real fix over workaround".
- **`Closes #N` in a PR body for `direct` mode** — wrong; use the commit message instead.

---

## When stuck

If the verification gates fail and you can't fix them in 3 attempts, **escalate** per the [`anti-laziness`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/anti-laziness.md) recovery protocol. Don't take destructive shortcuts (skip tests, weaken assertions, etc.).

---

## Quick reference

| Need to | Run |
|---|---|
| Check delivery mode | `aiwg config get --project delivery.mode` |
| Verify locally before push | `npx tsc --noEmit && npm test && npm run build:cli` |
| Run UAT (release prep) | `npm run uat` |
| Fetch full PR guide | `aiwg show skill aiwg-pr` |
| Drive a release | `aiwg show skill flow-release` |

## Related

- **In-context kernel skill**: `aiwg-pr` (always loaded; same content as this doc, accessible to agents)
- **Issue companion**: [filing issues](./filing-issues.md)
- **Templates**: [`.gitea/pull_request_template.md`](https://git.integrolabs.net/roctinam/aiwg/src/branch/main/.gitea/pull_request_template.md), [`.github/pull_request_template.md`](https://github.com/jmagly/aiwg/blob/main/.github/pull_request_template.md)
- **Rules**: [`delivery-policy`](https://github.com/jmagly/aiwg/blob/main/agentic/code/addons/aiwg-utils/rules/delivery-policy.md) (kernel), [`no-attribution`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/no-attribution.md) (kernel), [`anti-laziness`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/anti-laziness.md), [`dev-pipeline-safety`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/rules/dev-pipeline-safety.md)
- **Release flow**: [`flow-release`](https://github.com/jmagly/aiwg/blob/main/agentic/code/frameworks/sdlc-complete/skills/flow-release/SKILL.md)
- **Versioning**: [versioning policy](./versioning.md)
- **Origin**: #1269 (templates infrastructure), #1264–#1268 (tester report sweep that codified this pattern)
