cw-land
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.
- License 许可
- MIT
- 最近更新
- 2026-11-12
- Stars
- ★ 4.1w
- Forks
- 3.6k
01 前言 Front Matter
- 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.
03 SKILL.md 正文
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
main.AGENTS.mdowns this: work in your own short-lived worktree, rebase ontoorigin/main, pushHEAD:main, then remove the worktree. No maintainer PR branches, 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. Every push tomainstarts full hosted CI on that commit through the landing gate (main-landing.yml): never add[skip ci], watch the run and repair what it finds. 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 bash scripts/release/check-versions.shThe runtime-contract budget checker starts a native Cargo build by default; it is not a cheap drift check. Use an applicable existing measurement with
--receipt, or run a new measurement through the required build-lock and SSD cache workflow when the changed contract or final validation needs it. Add 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 and agent docs, which embed the docs), andnode web/scripts/check-runtime-routes.mjs --write(a Runtime API route added or removed). Regenerate those two files after every rebase or cherry-pick, even a clean one: git can mergedocs/RUNTIME_ROUTES.mdwrongly with no conflict marker. 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.Record it in the same commit. A user-visible change, usually a
featorfixbut also user docs, help text, defaults or security behavior, carries its line at the top of the matching[Unreleased]section (Added, Changed or Fixed): what changed for the user, what is still unproved,(#N)for a public issue or PR (never an internal tracker id), and for reported or contributed workThanks [@handle](https://github.com/handle). Tests, CI, refactors and internal docs need no line. Work by someone outside the maintainers also goes on the three credit surfaces in that commit: the CHANGELOG### Contributorsblock,docs/CONTRIBUTORS.md, andUNRELEASED_CONTRIBUTORSinweb/lib/release-credits.ts. A contributor PR merged as itself gets that commit right after the merge. Before the push:sh scripts/sync-changelog.sh # regenerates crates/tui/CHANGELOG.md python3 scripts/check-contributor-credit.py # since the last tag git log --format='%h %s' "$(git log -1 --format=%H -- CHANGELOG.md)"..HEAD | grep -E '^[0-9a-f]+ (feat|fix)'The last command must print nothing for commits you are landing.
check-feature-release-notes.shcovers only issue-linkedfeatcommits; fixes slip past it. A catch-up "changelog: record landed work" commit is the failure this step prevents, not the routine. -
Preserve credit mechanically, not just politely. GitHub reads neither
.github/AUTHOR_MAPnor.mailmapfor the contribution graph, so authorship must use the contributor's own GitHub-linked address; those files are project conventions on top. When a contributor's work lands as our commit, the contributor is its author and it carries the harvest line (AGENTS.md, "Harvested contributor credit"):git commit --author="Name <ID+handle@users.noreply.github.com>" ... Harvested from PR #N by @handle Co-authored-by: <maintainer or agent identity>GitHub's contributor list counts authors only, and
check-contributor-credit.pyflags a harvested handle who is not credited. Resolve the address from.github/AUTHOR_MAP, elsegh api users/<handle> --jq '"\(.id)+\(.login)@users.noreply.github.com"'. A clean cherry-pick keeps the author by itself. This step is the single owner of credit mechanics; other skills link here. Close their PR by hand with a thank-you naming the commit; nothing closes a PR automatically. 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 for runs awaiting approval before assuming a PR is stalled. A
first-time contributor's workflow runs can sit at
action_requireduntil a maintainer approves them, so the PR looks abandoned when nobody has actually looked at it. Approve the runs.
- Never make a contributor rebase around our churn. If their PR conflicts
only because
-
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 CHANGELOG line and credit-surface entries added, or why none was owed.
- The Linear/GitHub status written after the push, or why none was owed.
- 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.
04 同仓库更多 Skills
gh-find-prs
Survey the open Codewhale PR and issue queue read-only: fetch each item, check it against current code, and produce one coverage and disposition matrix with cited evidence and credit owed.
gh-file-issue
Use when filing a new Codewhale GitHub issue: turn a bug or idea into a well-formed, actionable issue with repro, acceptance criteria, labels, and milestone.
gh-close-issues
Close resolved Codewhale issues only after verifying the landed behavior: Refs #N per landing, Fixes #N only when the reporter's scenario was reproduced, closure at the release step or on the reporter's confirmation, always with a crediting comment.
gh-assign-issues
Use to assign GitHub issues to a milestone and/or owners in bulk, verifying each.
feedback
暂无简介
cw-slice
Use before writing code for any Codewhale feature, upgrade, or refactor: find the existing owner of the behavior, bound the change to one reviewable slice, and fix the evidence bar before you start.