docs(skills): cw-land lands on main, with the pre-push drift checks

The engine's cw-land still offered worktrees and integration branches as
landing shapes, and said not to push without explicit authorization.
That contradicts AGENTS.md since 2026-10-08: one canonical checkout on
main, no maintainer branches or worktrees, and verified slices are pushed
directly. codewhale-ops/skills/cw-land defers to this file for Engine
specifics, so the stale copy was the one agents read.

- Landing shape: the canonical checkout's main, stage only your paths,
  push verified main.
- The four cheap checks that have turned main red most often (fmt,
  sync-changelog --check, release/check-versions.sh, runtime-contract
  budget), plus the path-specific ones. New CHANGELOG entries go at the
  top of [Unreleased]: our appends at the end conflicted with open
  contributor PRs (#7013 went DIRTY twice that way).
- A contributor branch that conflicts only because main moved is
  resolved on their branch with merge-tree, commit-tree and a refspec
  push, which needs no local branch. This replaces the integration-branch
  fallback, with the zsh `${sha}:refs` pitfall noted.
- Before a merge, list PRs based on the source branch (root AGENTS.md).
- The worktree cleanup step is dropped. The red flag now limits only
  tag, release, publish and deploy.

Docs only; every script path named was checked to exist.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NBKbhx19BRbZtvWK8rVKjz
This commit is contained in:
CodeWhale BotandClaude Opus 5.5 committed 2026-10-17 15:12:20 -07:00
1 parent 2a7149a803
commit f53d9a4d4d
1 file changed
+40 -28
+40 -28
View File
@@ -1,6 +1,6 @@
---
name: cw-land
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."
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
@@ -24,26 +24,35 @@ Stage 5 of the loop: [cw-orient](../cw-orient/SKILL.md) →
## Workflow
1. **Choose the landing shape.**
- **The checkout that already exists** is the default. Direct to `main` is
permitted for a small coherent change when that checkout is current and
owns the affected files; when several agents share it, partition by file,
stage only your paths, and retry a commit that fails on `index.lock`.
Local commit permission never implies push, merge, tag, release, or
deploy permission.
- **No maintainer PR branches** (`AGENTS.md`): verified slices land on
`main` directly and hosted CI runs there. PRs are for contributors.
- **A worktree** is for a lane that genuinely conflicts with the dirt you
found in [cw-orient](../cw-orient/SKILL.md), or an experiment you may
throw away — not for parallel agents on the same lane.
- **An integration branch** (`integration/<topic>-<pr>-<date>`) is for
resolving a contributor PR that conflicts with a moving `main` when you
cannot push to their fork. It leaves their branch untouched.
1. **Land on the canonical checkout's `main`.** `AGENTS.md` owns this: no
maintainer PR branches, worktrees, nested clones or integration lanes.
Several agents share the checkout, so partition by file, check
`git status` before staging, stage only your paths (never `git add -A`),
and retry a commit that fails on `index.lock`. Push verified `main`
directly; hosted CI runs there. PRs are for contributors.
2. **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
`main` red most often. They take seconds:
```bash
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.py
```
Add the one that matches what you touched: `check-tui-locale-parity.py`
and `check-tui-product-vocabulary.sh` (locale strings),
`check-dead-code-budget.py` (`#[allow(dead_code)]`),
`check-blocking-calls-budget.py` (async code),
`check-readme-translations.py` and `check-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.
3. **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_MAP` nor `.mailmap` for the
@@ -77,8 +86,13 @@ Stage 5 of the loop: [cw-orient](../cw-orient/SKILL.md) →
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.
- `maintainerCanModify` does not guarantee push access to the fork. When the
push is refused, land the resolved merge on an integration branch here.
- Resolve on their branch without creating a local branch. Build the merge
commit with `git merge-tree --write-tree origin/main <pr-head>` and
`git commit-tree <tree> -p <pr-head> -p origin/main`, then push it with
`git push <fork-url> "${sha}:refs/heads/<their-branch>"`. In zsh, write
`${sha}`, not `$sha:refs`, because `:r` is a history modifier.
`maintainerCanModify` does 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_required` and never start,
so the PR looks abandoned when nobody has actually looked at it. Approve
@@ -93,17 +107,15 @@ Stage 5 of the loop: [cw-orient](../cw-orient/SKILL.md) →
6. **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.
7. **Clean up your own lane.** When a worktree you created lands on `main`,
remove it (`git worktree remove <path>`) and delete its merged branch.
Leave other writers' worktrees alone; `git worktree list` shows them.
Worktree sprawl was a 560 GB problem here once.
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 push, merge, tag, create a release, or deploy without explicit
authorization. A local commit is not permission for any of those.
- Don't tag, create a release, publish, or deploy without explicit
authorization. Pushing verified `main` is 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.md` operator controls that live outside the
product repository into a public repo.
@@ -117,8 +129,8 @@ Stage 5 of the loop: [cw-orient](../cw-orient/SKILL.md) →
## Output
- The landing shape you chose and why (direct main / worktree / integration).
- Commit SHAs, branch name, and whether the branch is local-only or pushed.
- Commit SHAs, the paths committed, the drift checks run, and the resulting
`origin/main` SHA.
- 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.