cw-land
GitHub用于将已验证的代码变更安全地合并到主分支。执行窄化提交、推送前漂移检查以维持构建绿色,并保留贡献者署名。适用于直接推送到main或合并PR的场景。
Trigger Scenarios
Install
npx skills add codewhale-hq/Codewhale --skill cw-land -g -y
SKILL.md
Frontmatter
{
"name": "cw-land",
"description": "Use when turning verified Codewhale work into commits on main and pushing them, or merging a contributor PR: staging only your paths, the pre-push drift checks, preserving contributor credit, and honoring the gate artifact before merging."
}
cw-land
Verified work still has to land without stepping on other writers, losing
contributor credit, or merging past a gate that has not actually passed. This
stage is about the boundary between "it works" and "it is in main" — and about
which of those steps you are allowed to take.
Stage 5 of the loop: cw-orient → cw-slice → cw-gates → cw-dogfood → land → cw-handoff.
When to use
- The change is verified and needs to become a commit on
main. - You are landing someone else's PR, harvesting a contributor's work, or
resolving a conflict caused by
mainmoving. - You are about to merge something behind a required gate.
Workflow
-
Land on the canonical checkout's
main.AGENTS.mdowns this: no maintainer PR branches, worktrees, nested clones or integration lanes. Several agents share the checkout, so partition by file, checkgit statusbefore staging, stage only your paths (nevergit add -A), and retry a commit that fails onindex.lock. Push verifiedmaindirectly; hosted CI runs there. PRs are for contributors. -
Commit narrow and build-green. One coherent change per commit; the tree builds at every commit. Put the real verification in the message — actual pass/fail counts, not "tests pass".
Before every push, run the cheap drift checks that have turned a green
mainred most often. They take seconds:cargo fmt --all -- --check sh scripts/sync-changelog.sh --check # after any CHANGELOG.md edit bash scripts/release/check-versions.sh python3 scripts/check-runtime-contract-budget.pyAdd the one that matches what you touched:
check-tui-locale-parity.pyandcheck-tui-product-vocabulary.sh(locale strings),check-dead-code-budget.py(#[allow(dead_code)]),check-blocking-calls-budget.py(async code),check-readme-translations.pyandcheck-readme-locales.sh(READMEs),node web/scripts/derive-facts.mjs && node web/scripts/check-facts.mjs(public facts). Put a new CHANGELOG entry at the top of[Unreleased]. Open contributor PRs append at its end, and an entry of ours there conflicts with every one of them. -
Preserve credit mechanically, not just politely. Commit authorship and
Co-authored-by:trailers must use the contributor's own GitHub-linked address — GitHub reads neither.github/AUTHOR_MAPnor.mailmapfor the contribution graph; those are project conventions on top. When a contributor's work lands as our commit, it carries both:Harvested from PR #N by @handle Co-authored-by: Name <github-linked-email>That trailer is what lets
auto-close-harvested.ymlclose their PR with credit. Canonical human identities live in.github/AUTHOR_MAP.Whether a bot or agent also appears in a trailer no longer matters — the CI check that policed trailer identities was removed because it rejected ordinary agent commits. Give humans their credit; don't spend time scrubbing tool trailers.
-
Landing someone else's work: their time is more expensive than ours.
- Never make a contributor rebase around our churn. If their PR conflicts
only because
mainmoved, a maintainer resolves it. - Read their diff against the merge base first, so you know exactly what
they added, then re-apply that — rather than hand-merging two large sides
and hoping:
git diff $(git merge-base main <pr-head>)..<pr-head> - Conflicts that split mid-function do not resolve by keeping both sides. Git's markers can land inside a body, so a both-sides resolution produces unbalanced braces that look plausible and do not compile. Default: take one side whole, then re-insert the other side's additions at their original anchor; when the conflict doesn't fit that pattern, resolve it however is correct and let the compiler judge.
- Resolve on their branch without creating a local branch. Build the merge
commit with
git merge-tree --write-tree origin/main <pr-head>andgit commit-tree <tree> -p <pr-head> -p origin/main, then push it withgit push <fork-url> "${sha}:refs/heads/<their-branch>". In zsh, write${sha}, not$sha:refs, because:ris a history modifier.maintainerCanModifydoes not guarantee that the push is accepted. When the fork refuses it, ask on the PR. Harvesting is the last resort. - Check the contribution gate before assuming a PR is stalled. An
unlisted author's workflow runs sit at
action_requiredand never start, so the PR looks abandoned when nobody has actually looked at it. Approve the runs, then fix the cause: add them to.github/APPROVED_CONTRIBUTORS(all:username), or comment/lgtm(PR scope) or/lgtmi(issue scope).
- Never make a contributor rebase around our churn. If their PR conflicts
only because
-
Verify mergeability against the real head. A PR that is clean against
maincan still conflict with a release branch:git merge-tree $(git merge-base <base> <pr-head>) <base> <pr-head> -
Merging under a gate.
AGENTS.md("Merging under a gate") owns this: the artifact must literally say PASS, the review thread outranks the check rollup, and ambiguity blocks the merge — never the reverse. Before you merge, list the open PRs whose base is the PR's source branch (gh pr list --base <branch>) and retarget them first. Otherwise they close when that branch goes away.
Red flags / don't
- Don't tag, create a release, publish, or deploy without explicit
authorization. Pushing verified
mainis allowed; it is none of those. - Don't rewrite published history, retag a release, or force-push a shared ref.
- Don't commit
AGENTS.md/CLAUDE.mdoperator controls that live outside the product repository into a public repo. - Don't stage another writer's dirty files to get a clean commit.
- Don't merge on a green rollup alone when a review thread has open findings.
- Don't harvest or close from a PR title or label — review the code, tests, comments, and checks.
- Don't add another legacy call site for convenience once a replacement architecture is adopted. Declared migrations are one-way.
- Don't leave new enforcement live: keep it dry-run/advisory unless approved.
Output
- Commit SHAs, the paths committed, the drift checks run, and the resulting
origin/mainSHA. - The credit trailers applied and to whom.
- The gate artifact's literal verdict at merge time, if a gate applies.
- Exactly which public actions you took, and which you deliberately did not.
Version History
-
6f95551
Current 2026-10-19 04:41
修正了与 AGENTS.md 的冲突:移除了 worktrees 和 integration branches,规定使用规范 checkout 直接推送到 main;更新了预推送检查脚本及 CHANGELOG 条目位置规则。
- 94130d9 2026-09-27 21:50
- aedb88b 2026-09-09 04:22


