How General Translation work moves from a worktree to main.
pnpm skills:install gt-ship --project <dir>Run it from a Prototemplate checkout. It links skills/gt-ship into the project’s .claude/skills and .agents/skills; --copy vendors the folder instead, and --dry-run prints each step first.
Kevin Liu (GitHub Kevin-Liu-01) lands General Translation (GT) work through two repositories with different rules. github.com/generaltranslation/gt-cloud is the private monorepo of the product and the website; it squash-merges, requires three checks, is reviewed by three bots, and takes small PRs from k/<topic> worktrees. github.com/Kevin-Liu-01/Prototemplate is public and Kevin's own; it takes commits on main after he has reviewed the work on localhost.
$GT_CLOUD is a gt-cloud checkout (~/gt/gt-cloud on Kevin's machine) and $PROTOTEMPLATE a Prototemplate checkout (~/repos/Prototemplate). The PR body and its screenshots are detailed in references/pr-body.md; the bots, the checks and Linear in references/review-loop.md; the work around a PR (approval, grouping, release hygiene, closing, teammates, upstream, cleanup) in references/beyond-the-pr.md, and Prototemplate's landing and deploys in references/prototemplate.md. scripts/ holds two read-only scripts, pr-size.mjs (a branch's diff by kind) and pr-bots.mjs (a PR's review state), and three for the PR body: pr-assets.sh (uploads screenshots), patch-body.py (replaces the marked screenshots section) and contact-sheet.py (many states on one image). The commands below call them at $PROTOTEMPLATE/skills/gt-ship/scripts/; an installed copy of this skill carries the same files in its own scripts/ folder.
motion/ belongs to the Videos session and is untracked in the shared checkout: never stage, edit or delete it. The onboarding and dashboard session works in deck/, src/components/plate, src/app/craft and public/brand/mood, and pushes main from its own worktree. The prototemplate skill (section 8) keeps the full lane map.git -C $GT_CLOUD fetch origin, then git -C $GT_CLOUD worktree add -b k/<topic> <path> origin/main and pnpm install --frozen-lockfile --prefer-offline in the new worktree. Kevin's branches are named k/<topic>. On Kevin's machine the primary gt-cloud checkout sits on codex/website-redesign with old uncommitted work; leave it as it is and never switch its branch. Read gt-cloud facts from origin/main or a fresh worktree, never from that checkout.git branch --show-current before every commit. Before reporting a push, compare gh pr view <n> --json headRefName,headRefOid with the current branch and git rev-parse HEAD. When HEAD descends from the PR head, repair with git branch -f <pr-branch> HEAD && git switch <pr-branch> && git push origin <pr-branch>.gt-cloud-wt-docs and gt-cloud-wt-docs-main hold stale local copies of k/docs-locale-switch-rewrite and k/docs-perf.node_modules. On 2026-10-05 a session's scratchpad held 259 GB, most of it 48 leftover gt-cloud worktrees, the Mac was down to 27 GB free, and Kevin had to ask for the cleanup. Use one per lane or per stack, and remove it as soon as its work is pushed:git -C <wt> status --short prints nothing. · git -C <wt> branch -r --contains HEAD names a remote branch, or git -C <wt> cherry origin/main shows no + lines. · git worktree remove <wt>, then git worktree prune.For many at once, pass the paths that passed both checks to xargs -P 6 -n 1 git worktree remove --force --force in the background (git worktree remove takes one path per call). apps/admin/src/routeTree.gen.ts rewrites itself during type checks; restore it in your own worktree and never count it as work.
--global: Prototemplate and other repositories keep the global one. Check with git log -1 --format='%an <%ae>' against git config user.email, and fix a wrong author with git commit --amend --reset-author before pushing.require_extra_approval_for_unattributed_changes (read 2026-10-05). A Co-Authored-By trailer for Claude adds an author GitHub cannot attribute, and the PR then needs a second human approval. The October 2026 branches carry the trailer. When Kevin wants a PR merged on one approval, reword the commits without it and push with a lease; standing approvals survive because dismiss_stale_reviews_on_push is off (Kevin, #4795, 2026-09-11). The squash commit on main is the PR title with its number, plus a Co-authored-by line for each co-author on the branch's commits.git commit publishes all of it (their half-done deletions rode into a landing commit on 2026-08-07):sh git status --short git add src/app/skills/page.tsx skills/gt-ship git commit -F <scratch>/msg.txt -- src/app/skills/page.tsx skills/gt-ship git status --short
Never run git add -A or git add . in a shared tree: Prototemplate's b56e64c swept 229 files (92 MB) of motion/ onto main (2026-10-01). Never run git checkout <commit> -- <file> or git restore on a file another live session may be editing.
git ls-tree origin/main -- <path> and test -f <path>, and never cut the listing with head. On #4703 a write to apps/landing/__tests__/proxy.test.ts replaced seven attribution tests because a truncated listing hid the file; Greptile caught it. Extend an existing file.style(landing): hero buttons side by side on phones, perf(docs): turn off sidebar prefetch and warm rows on intent. Write the message to a file and pass -F. zsh feeds heredocs on one && chain in operator order, and once put a script into a pushed message (#4689).git fetch first and read git log --oneline HEAD..origin/<branch> for a collaborator's commits. Then push with an explicit lease, git push --force-with-lease=<branch>:<expected sha> origin HEAD:<branch>. A lease against a stale tracking ref erased a collaborator's five commits on 2026-08-26. gt-cloud main refuses force pushes.pnpm lint ends in oxfmt --check ., which the app lint scripts skip, so run pnpm exec oxfmt <changed files>. The lint rules themselves are in gt-lints.Kevin reads a PR's line count first, and so do the reviewers: "why are there dashboard css additions in 5063? and why is it so many lines?" (Kevin, 2026-10-01), then "why is 5063 39.5k lines? fix this." (Kevin, 2026-10-02).
sh git fetch origin node $PROTOTEMPLATE/skills/gt-ship/scripts/pr-size.mjs # origin/main...HEAD node $PROTOTEMPLATE/skills/gt-ship/scripts/pr-size.mjs --base origin/<branch below> # in a stack
It runs git diff --numstat over the range, groups the files as product, tests, fixtures, scripts, assets, docs, lockfile and generated, and prints the comment share of added product code, the test lines per product line, the largest files and a note per group a reviewer will ask about. Justify every large group in the body, or cut it.
k/onboarding-parity-suite) or in the scratchpad. #5063 carried 24k lines of parity suite, 18k of them pretty-printed recorded JSON. A review gallery Kevin asks for lives outside the PR: the sign-in and onboarding states run in Prototemplate at /d/production/signin?state=<id>.gt-aesthetic holds the principle).check-planning-files check fails on a new Markdown file that reads as a plan; specs and context files stay in the scratchpad. Run node scripts/check-plan-files.mjs --base origin/main.type(scope): sentence, with the app as scope (landing, dashboard, docs, blog). The allowed types are build, chore, ci, docs, feat, fix, perf, refactor, revert, style and test. A feat PR needs a linked Linear issue; the other types pass without one. The title becomes the squash commit's subject on main.references/beyond-the-pr.md).Full rules, an example and the upload commands are in references/pr-body.md.
gt-voice.| Before (main) | After (this branch) | table with one bold caption line. Both themes where the change has a theme.pr-assets orphan branch under screenshots/pr-<n>/ and are linked with blob/pr-assets/...?raw=true: sh scripts/pr-assets.sh --repo generaltranslation/gt-cloud --pr <n> <files> uploads them without touching the worktree and prints the links, and python3 scripts/patch-body.py --repo generaltranslation/gt-cloud --pr <n> --section <file> swaps the section between ` and ` and keeps the rest byte for byte., or ), through gh pr view <n> --json body and gh pr edit <n> --body-file. A body can hold markers of its own above them, such as `.Commands and the full check list are in references/review-loop.md.
@greptile review the first time and @greptile review again after; it takes about five minutes. The target is 5/5 on the head commit with every Greptile thread resolved.bugbot run re-triggers it. Devin and the Cursor Approval Agent comment on open; the Approval Agent's risk label needs no reply.addPullRequestReviewThreadReply, then call resolveReviewThread. A thread resolved without a reply still reads as unanswered.sh node $PROTOTEMPLATE/skills/gt-ship/scripts/pr-bots.mjs <n>
It prints the title type, each bot summary with the commit it reviewed against the head, the unresolved and unanswered threads with their ids, and the standing run of each required check. It exits 0 only when Greptile reads 5/5 on the head, no bot thread is open, the branch has no conflict with its base and the three required checks are present and green.
Validate PR title and Linear issue, check-planning-files and run-tests. run-tests aggregates lint, build, the four unit_tests shards, validate, integration, e2e and db (ci.yml on main, 2026-10-05). mergeStateStatus: BLOCKED with every check green means the code-owner review is missing; DIRTY means the branch conflicts with its base.gh run list --branch <branch> --workflow "CI - Run Tests".generaltranslation/content) has no Greptile and no Bugbot; a score there cannot be reached.gh pr edit <n> --add-reviewer <login>) so Linear notifies them through its Slack app; review requests in Slack stopped with the team announcement of 2026-09-08. Kevin chooses who reviews, so ask him first; APPROVAL_POLICY.md is the routing table.Stack PRs that share files, so the same conflicts are resolved once: the 2026-10-05 dashboard PRs shared up to 37 files with each other.
Stacked on #<n>. Merge that first.github/gh-stack extension from any checkout whose origin is gt-cloud:sh gh stack link --base main <bottom> <next> <top> # PR numbers, bottom first gh stack link <stack-number> <pr> # adds a PR to the top of a stack gh stack merge <stack-number | pr-number> # merges every PR up to that one, all or nothing
Pass PR numbers for PRs that exist: a branch argument is pushed first and gets a new PR if it has none. A native stack merges atomically, so it needs no restack between merges. gh stack merge asks for confirmation only in an interactive terminal; from an agent's shell it merges at once, so run it only when Kevin says to merge (section 5).
git rebase --onto per PR bottom first, conflicts resolved toward the lower PR and recorded, git range-diff and gh pr diff --name-only checked, then a lease push and gh pr edit --base. After a squash merge of the bottom, rebase the next branch onto origin/main past the old bottom head. The full recipe is in references/stacks.md.bugbot run."i also really really want to emphasize that we need the new onboarding to keep all the tracking and backend stuff that the old onboarding did" (Kevin, 2026-10-02). Parity with production is a release gate for any onboarding or auth redesign.
origin/main worktree, replay the same scenarios on the release, and diff the two ledgers. Re-run the diff after every fix: the first audit of #5063 called the organization audit event preserved, and a later fix dropped projectId from its scope. A reviewer's list of intended changes is not evidence.k/onboarding-parity-suite and in the scratchpad (section 3).Commands, incidents and the deploy checks are in references/prototemplate.md.
$PROTOTEMPLATE is shared by several sessions. Reuse the dev server at http://localhost:3005 and never stop it.grep -rln '^<<<<<<< ' src docs deck scripts skills.prototemplate section 9. The build gate runs in a scratch worktree, chained with && and unpiped, never in the shared tree whose .next the dev server owns.motion/ is never staged.dpl_ id on www equals the team deployment of your commit.readyStateReason and retried with vercel redeploy, never with an empty commit.vercel --prod on the team scope unless Kevin says so.motion/ in Prototemplate).git branch --show-current equals the PR's headRefName, and after the push headRefOid equals HEAD.git status read before and after.origin/main.pr-size.mjs read and every large group justified; no fixtures, harnesses, galleries or planning Markdown in the diff.feat PR is linked to a Linear issue.pr-assets, Checks with counts, bot blocks byte for byte.pr-bots.mjs exits 0 (Greptile 5/5 on the head, no open bot thread, no conflict, required checks green) and lists no unanswered bot thread; the cancelled CI runs on the branch were read.references/beyond-the-pr.md).lint:all and check:pages pass; the build gate passed with && in a scratch worktree; deployment statuses green; www's dpl stamp equals the team deployment.Prototemplate: gt-voice (commit and PR prose), gt-lints (the gates in both repositories), gt-graphics (capture recipes for PR screenshots), gt-reporting (the PR slate), gt-verify (done means deployed), prototemplate (the repository and its viewer). Wiki: agent-iteration-loop (the general implement, verify, review loop), agent-browser, linear, split-to-prs, resolving-merge-conflicts, gh-address-comments. gt-cloud: pr-desc, gt-testing.
Dated provenance for every rule, script and number in this skill is in references/sources.md.
The folder skills/gt-ship as agents fetch it. Each file opens raw.
SKILL.mdreferences/beyond-the-pr.mdreferences/pr-body.mdreferences/prototemplate.mdreferences/review-loop.mdreferences/sources.mdreferences/stacks.mdscripts/contact-sheet.pyscripts/contact-sheet.test.pyscripts/patch-body.pyscripts/patch-body.test.pyscripts/pr-assets.shscripts/pr-assets.test.shscripts/pr-bots.mjsscripts/pr-size.mjs