| 1 | --- |
| 2 | name: cw-land |
| 3 | description: "Use when turning verified Codewhale work into commits, branches, or a merge: choosing direct-main vs. worktree vs. integration branch, preserving contributor credit, and honoring the gate artifact before merging." |
| 4 | --- |
| 5 | |
| 6 | # cw-land |
| 7 | |
| 8 | Verified work still has to land without stepping on other writers, losing |
| 9 | contributor credit, or merging past a gate that has not actually passed. This |
| 10 | stage is about the boundary between "it works" and "it is in `main`" — and about |
| 11 | which of those steps you are allowed to take. |
| 12 | |
| 13 | Stage 5 of the loop: [cw-orient](../cw-orient/SKILL.md) → |
| 14 | [cw-slice](../cw-slice/SKILL.md) → [cw-gates](../cw-gates/SKILL.md) → |
| 15 | [cw-dogfood](../cw-dogfood/SKILL.md) → **land** → |
| 16 | [cw-handoff](../cw-handoff/SKILL.md). |
| 17 | |
| 18 | ## When to use |
| 19 | |
| 20 | - The change is verified and needs to become a commit, branch, or PR. |
| 21 | - You are landing someone else's PR, harvesting a contributor's work, or |
| 22 | resolving a conflict caused by `main` moving. |
| 23 | - You are about to merge something behind a required gate. |
| 24 | |
| 25 | ## Workflow |
| 26 | |
| 27 | 1. **Choose the landing shape.** |
| 28 | - **Direct to `main`** is permitted for a small coherent change when this |
| 29 | checkout is current, clean, and owns the affected files. Local commit |
| 30 | permission never implies push, merge, tag, release, or deploy permission. |
| 31 | - **A worktree** is the right safety boundary for conflicting, dirty, stale, |
| 32 | or independent work — and for anything that would otherwise fight the dirt |
| 33 | you found in [cw-orient](../cw-orient/SKILL.md). |
| 34 | - **An integration branch** — `integration/<topic>-<pr>-<date>` — is the |
| 35 | normal path for anything with conflicts or several moving PRs. It is |
| 36 | cheaper than rebasing onto a `main` that keeps moving, and it leaves the |
| 37 | contributor's branch untouched. |
| 38 | |
| 39 | 2. **Commit narrow and build-green.** One coherent change per commit; the tree |
| 40 | builds at every commit. Put the real verification in the message — actual |
| 41 | pass/fail counts, not "tests pass". |
| 42 | |
| 43 | 3. **Preserve credit mechanically, not just politely.** Commit authorship and |
| 44 | `Co-authored-by:` trailers must use the contributor's own GitHub-linked |
| 45 | address — GitHub reads neither `.github/AUTHOR_MAP` nor `.mailmap` for the |
| 46 | contribution graph; those are project conventions on top. When a |
| 47 | contributor's work lands as our commit, it carries both: |
| 48 | ```text |
| 49 | Harvested from PR #N by @handle |
| 50 | |
| 51 | Co-authored-by: Name <github-linked-email> |
| 52 | ``` |
| 53 | That trailer is what lets `auto-close-harvested.yml` close their PR with |
| 54 | credit. Canonical human identities live in `.github/AUTHOR_MAP`. |
| 55 | |
| 56 | Whether a bot or agent also appears in a trailer no longer matters — the CI |
| 57 | check that policed trailer identities was removed because it rejected |
| 58 | ordinary agent commits. Give humans their credit; don't spend time scrubbing |
| 59 | tool trailers. |
| 60 | |
| 61 | 4. **Landing someone else's work: their time is more expensive than ours.** |
| 62 | - Never make a contributor rebase around our churn. If their PR conflicts |
| 63 | only because `main` moved, a maintainer resolves it. |
| 64 | - Read their diff against the **merge base** first, so you know exactly what |
| 65 | they added, then re-apply that — rather than hand-merging two large sides |
| 66 | and hoping: |
| 67 | ```bash |
| 68 | git diff $(git merge-base main <pr-head>)..<pr-head> |
| 69 | ``` |
| 70 | - **Conflicts that split mid-function do not resolve by keeping both sides.** |
| 71 | Git's markers can land inside a body, so a both-sides resolution produces |
| 72 | unbalanced braces that look plausible and do not compile. Default: take |
| 73 | one side whole, then re-insert the other side's additions at their |
| 74 | original anchor; when the conflict doesn't fit that pattern, resolve it |
| 75 | however is correct and let the compiler judge. |
| 76 | - `maintainerCanModify` does not guarantee push access to the fork. When the |
| 77 | push is refused, land the resolved merge on an integration branch here. |
| 78 | - **Check the contribution gate before assuming a PR is stalled.** An |
| 79 | unlisted author's workflow runs sit at `action_required` and never start, |
| 80 | so the PR looks abandoned when nobody has actually looked at it. Approve |
| 81 | the runs, then fix the cause: add them to `.github/APPROVED_CONTRIBUTORS` |
| 82 | (`all:username`), or comment `/lgtm` (PR scope) or `/lgtmi` (issue scope). |
| 83 | |
| 84 | 5. **Verify mergeability against the real head.** A PR that is clean against |
| 85 | `main` can still conflict with a release branch: |
| 86 | ```bash |
| 87 | git merge-tree $(git merge-base <base> <pr-head>) <base> <pr-head> |
| 88 | ``` |
| 89 | |
| 90 | 6. **Merging under a gate.** `AGENTS.md` ("Merging under a gate") owns this: |
| 91 | the artifact must literally say PASS, the review thread outranks the check |
| 92 | rollup, and ambiguity blocks the merge — never the reverse. |
| 93 | |
| 94 | 7. **Clean up your own lane.** When a worktree's branch lands on `main`, remove |
| 95 | the worktree (`git worktree remove <path>`). `scripts/worktree-gc.sh` |
| 96 | lists lanes by merged/dirty state; `--remove-merged --yes` prunes the |
| 97 | merged-and-clean ones. Worktree sprawl was a 560 GB problem here once. |
| 98 | |
| 99 | ## Red flags / don't |
| 100 | |
| 101 | - Don't push, merge, tag, create a release, or deploy without explicit |
| 102 | authorization. A local commit is not permission for any of those. |
| 103 | - Don't rewrite published history, retag a release, or force-push a shared ref. |
| 104 | - Don't commit `AGENTS.md` / `CLAUDE.md` operator controls that live outside the |
| 105 | product repository into a public repo. |
| 106 | - Don't stage another writer's dirty files to get a clean commit. |
| 107 | - Don't merge on a green rollup alone when a review thread has open findings. |
| 108 | - Don't harvest or close from a PR title or label — review the code, tests, |
| 109 | comments, and checks. |
| 110 | - Don't add another legacy call site for convenience once a replacement |
| 111 | architecture is adopted. Declared migrations are one-way. |
| 112 | - Don't leave new enforcement live: keep it dry-run/advisory unless approved. |
| 113 | |
| 114 | ## Output |
| 115 | |
| 116 | - The landing shape you chose and why (direct main / worktree / integration). |
| 117 | - Commit SHAs, branch name, and whether the branch is local-only or pushed. |
| 118 | - The credit trailers applied and to whom. |
| 119 | - The gate artifact's literal verdict at merge time, if a gate applies. |
| 120 | - Exactly which public actions you took, and which you deliberately did not. |
| 121 |