Gated Dual Clone
ASecurityDual-repo git workflow bootstrapper for projects where upstream branches are protected (MR/PR required) and builds are heavy. Creates a gateway repo (push source) and a satellite repo (fetch-only build tree), with three safety gates verified post-setup and a daily-workflow cheatsheet. 双仓库 MR/PR 流 git 工作流搭建器。适用于上游分支受保护 + 编译重 + 需物理隔离防 误推的项目。 TRIGGER: "dual clone workflow", "gateway repo", "verify repo", "compile sandbox", "protected branch workflow", "双仓库工作流", "编译仓库", "gateway 仓库", "set up dual...
- 2 stars
- 0 votes
- 0 copies
- 3 views
- Added September 23, 2026
Works with
Security analysis
100/100Pro scans all 13 files and shows the line behind each finding
npx -y skills add TbusOS/sky-skills --skill gated-dual-clone --agent claude-codeAre you the author of Gated Dual Clone?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tbusos-gated-dual-clone)---
name: gated-dual-clone
description: >
Dual-repo git workflow bootstrapper for projects where upstream branches are
protected (MR/PR required) and builds are heavy. Creates a gateway repo
(push source) and a satellite repo (fetch-only build tree), with three
safety gates verified post-setup and a daily-workflow cheatsheet. 双仓库
MR/PR 流 git 工作流搭建器。适用于上游分支受保护 + 编译重 + 需物理隔离防
误推的项目。
TRIGGER: "dual clone workflow", "gateway repo", "verify repo", "compile
sandbox", "protected branch workflow", "双仓库工作流", "编译仓库",
"gateway 仓库", "set up dual clone".
DO NOT TRIGGER: single-repo direct-push flow, pure worktree setup, monorepo
package management, small projects where one clone is enough.
last-verified: 2026-04-24
---
# Gated Dual-Clone Workflow
## One-liner · 一句话
**EN** — Clone the upstream twice: a **gateway** repo that pushes, and a
**satellite** repo that builds. The satellite's `origin` points at the local
gateway path — so a stray `git push` from the compile tree is physically
unable to reach the remote.
**ZH** — 把上游仓库 clone 两份:一个 **gateway** 仓库负责 push,一个
**satellite** 仓库只读编译。satellite 的 `origin` 指向本地 gateway 路径,
编译树里误跑一条 `git push` 在物理上也够不到远程。
## Should I use this? · 该不该用
→ See **[references/decision-checklist.md](references/decision-checklist.md)**
Four yes/no questions. Three or more "yes" → use this skill. Otherwise fall
back to a single repo or `git worktree`.
**四道是非题**:≥ 3 个 yes 用本 skill,否则单仓库或 `git worktree` 更合适。
## Minimal bootstrap · 最小搭建
```bash
scripts/bootstrap.sh \
--remote git@gitlab.example.com:team/project.git \
--upstream-branch release \
--push-branch feature/alice-auth \
--gateway-dir ~/projects/foo-work \
--satellite-dir ~/projects/foo-verify \
--user-email alice@example.com \
--user-name alice
```
All 7 flags are required. `--dry-run` prints the command sequence without
executing. `--force` is only valid for empty target dirs (non-empty is always
rejected; clean up by hand first). See `scripts/bootstrap.sh --help` for
detail.
## Post-setup · 搭建完成后(3 道检查)
`bootstrap.sh` verifies three safety layers before exiting 0:
- **Gate A · Protocol wall** — `cd satellite && git push` rejected
("DISABLED" in error). Satellite's `origin` is a local path; no network
route to upstream exists.
- **Gate B · Explicit disable** — Satellite's push URL is literally set to
`DISABLED`, so even malformed config still errors fast instead of silently
trying.
- **Gate C · Pre-push hook** — Gateway's `pre-push` hook rejects any push
to a protected-branch regex (default: the upstream branch passed in).
Gate failures halt bootstrap with a clear reason — nothing is left in a
partial state that the user has to hand-clean.
**三道检查都过才算 bootstrap 成功**。任一失败会明确说明原因,不留一半成品。
## Daily operations · 日常操作
→ See **[references/daily-workflow.md](references/daily-workflow.md)**
The core loop: edit in gateway, sync satellite with `scripts/sync-satellite.sh`,
build in satellite, push from gateway, open MR/PR. Four commands, copy-paste
ready.
**日常 4 步**:在 gateway 里改 → `sync-satellite.sh` 同步到 satellite →
satellite 里编译 → gateway 里 `git push` → GitLab / GitHub 上发 MR/PR。
cheatsheet 里每步都是现成命令。
## Safety model · 安全模型
**Three layers, each independent**. Any one holds; all three together is
belt, braces, and shoulder strap.
1. **Protocol layer** — satellite's `origin` is a file path; no TCP/SSH
route to upstream exists from the compile tree.
2. **Config layer** — satellite's push URL = literal `DISABLED`. Explicit
failure mode.
3. **Hook layer** — gateway's `pre-push` hook rejects protected-branch refs.
**Critical caveat · 关键注意**: Client-side git hooks are **advisory, not
enforcement**. `--no-verify` bypasses them. Real protection = server-side
protected-branch rules in GitLab / GitHub / Gerrit. This skill's hook is a
second layer — catches finger-slips, not determined bypass. Enable
server-side branch protection alongside.
**客户端 hook 只是提醒,不是强制边界**。`--no-verify` 可以绕过。真正的保护
在托管平台的 protected-branch 规则上。本 skill 的 hook 是第二层,接手滑,
不防恶意。服务端保护一起开。
## Variants · 变体
- **1 gateway + N satellites** — run `bootstrap.sh` again with
`--skip-gateway` + a new `--satellite-dir`. Useful for `verify` / `debug`
/ `test` trees.
- **3-clone with reproducibility gate** (see below) — add a `clean-verify`
clone on separate disk/machine, with a pre-push hook that refuses to push
anything clean-verify hasn't stamped. Trade extra disk + extra build time
for catching "works on SSD, fails on HDD / CI" bugs before they reach
upstream.
- **Worktree fallback** — if disk is tight (< 2× source size) and single
developer, single machine: `git worktree` trades isolation for disk. See
`decision-checklist.md` for when worktree beats this skill.
- **Hosting differences** — GitLab MR, GitHub PR, Gerrit push-to-`refs/for/*`.
The skill is host-neutral; protected-branch regex is a per-project flag.
## Optional 3rd clone · reproducibility gate · 可选 第 3 仓 · reproducibility 关卡
For projects where a failed build on CI (different filesystem, different
disk speed, different filesystem cache state) has a real cost — add a
**clean-verify** clone on a separate disk (or separate machine) and gate
every push on a from-scratch full-build in it.
**When to use** (all four should be true):
1. Daily dev happens on SSD; CI / shipping happens on HDD or remote machine.
2. The project has reproducibility bugs that only surface from a cold, clean
tree (SSD cache / generated files / stale build artefacts hide them on
the iteration clone).
3. The push path is high-stakes (production branch, signed release, audit
trail required).
4. The team already has discipline to run a pre-push command.
**Topology**:
```
┌──────────┐ ┌──────────┐ ┌───────────────────┐
upstream ───► │ gateway │ ────► │satellite │ │ clean-verify │
(push only │ (dev + │ sync │ (build · │ │ (pre-push gate · │
from gateway) │ push) │ via │ disabled│ │ HDD / diff disk)│
│ SSD │ local │ push) │ │ │
└──▲───────┘ path └──────────┘ └───▲───────────────┘
│ │
│ pre-push hook reads .git/last-clean-verify
│ and refuses to push a commit whose sha ≠ stamped
│ │
└─── clean-verify-run.sh stamps on success ─┘
```
**Bootstrap it**:
```bash
scripts/bootstrap.sh \
--remote git@gitlab.example.com:team/project.git \
--upstream-branch release \
--push-branch feature/alice-auth \
--gateway-dir ~/projects/foo-work \
--satellite-dir ~/projects/foo-verify \
--clean-verify-dir /mnt/hdd/foo-clean-verify \
--user-email alice@example.com \
--user-name alice
```
Same as the 2-clone bootstrap, plus `--clean-verify-dir=<path>`. The
script adds:
- **Step 5b** — `git clone` the clean-verify from gateway (same local-path
trick as satellite · origin on a local path, never the real remote).
- **Step 6b** — set `pushurl = DISABLED` on both `origin` and the
diagnostic `upstream` remote. Check out `<push-branch>`.
- **Gate D** — in Step 7 post-setup, verify clean-verify push is DISABLED.
- **Pre-push hook gets a 2nd gate** — `install-hooks.sh` is invoked with
`--enforce-clean-verify`, which adds a "stamp match" check alongside the
protected-branch check.
**Daily flow** (5 steps instead of 4):
1. Edit in gateway, commit.
2. `sync-satellite.sh` → satellite → build + test there (fast iteration).
3. When ready to push, run:
```bash
scripts/clean-verify-run.sh \
--gateway-dir=<gw> --clean-verify-dir=<cv> \
--push-branch=<br> --build-cmd='<full-build command>' --yes
```
This syncs clean-verify from gateway, runs `git clean -fdx` (drops
every untracked/ignored file), runs your full build end-to-end, and on
success writes `gateway/.git/last-clean-verify`.
4. `git push origin <push-branch>` — the hook reads the stamp, refuses if
commit doesn't match. Emergency bypass: `git push
--push-option=allow-unverified` (use sparingly; the point of the gate
is that it holds).
5. Raise MR/PR.
**What this catches that 2-clone doesn't**:
- SSD-only bugs: code depends on files that happen to be in OS filesystem
cache on the dev SSD but not on a cold HDD.
- Stale-artefact bugs: satellite has build products from an earlier commit
that accidentally satisfy a missing `#include` / missing codegen that the
current commit wouldn't produce fresh.
- Dirty-tree bugs: satellite has hand-edits the author forgot about; they
pass the build; clean-verify starts from git HEAD and fails.
- Build-command drift: `--build-cmd` is sha256-hashed into the stamp; if
team changes build command out from under you, next push asks for a
re-verify.
**Paired evaluator**: `gated-dual-clone-audit` auto-detects 3-clone mode
when you pass `--clean-verify-dir`, and runs 4 extra gates (S9-S11 + C9 +
B4) to re-verify the topology on demand.
## Files · 文件
- `scripts/bootstrap.sh` — the main setup command, runs all 8 steps + 3 gates (4 gates in 3-clone mode) · accepts optional `--clean-verify-dir`
- `scripts/sync-satellite.sh` — fetch / reset-hard / merge-ff modes for
syncing satellite from gateway
- `scripts/clean-verify-run.sh` — sync + clean + full-build + stamp · the pre-push reproducibility gate for 3-clone mode
- `scripts/install-hooks.sh` — writes the `pre-push` hook on the gateway · `--enforce-clean-verify` adds the stamp-match gate
- `scripts/check_before_mr.sh` — 5 checks to run **right before opening the MR** (clean tree · clean-verify repo exists · stamp present · stamp sha == branch head · remote == local). For push-early / MR-late projects — see below
- `references/decision-checklist.md` — when to use / when not to use
- `references/daily-workflow.md` — 4-step cheatsheet
- `references/patterns.md` — N-satellite / worktree fallback / GitHub-GitLab-Gerrit shapes
- `references/guardrails.md` — why the three gates work / when they break / how to verify
- `references/server-side-enforcement.md` — GitLab / GitHub / Gerrit / pre-receive / Actions templates (real enforcement beyond advisory client-side hook)
- `references/troubleshooting.md` — 10 common failures, symptom → diagnose → fix → prevent
- `references/comparison.md` — dual-clone vs worktree vs single-repo, 11-dimension table
## Push-early / MR-late · 先推分支,最后才开 MR
有些项目这样走:**个人分支随时 push 到远端当备份,一整个主题做完才开 MR**。
这时 `install-hooks.sh --enforce-clean-verify` 那道会碍事 —— 它**不看分支名,
任何 push 都拦**,于是每次备份性质的 push 都要 `--push-option=allow-unverified`。
**绕过一旦变成肌肉记忆,哪天真该拦的那次也会顺手绕过** —— 比关掉更糟,
因为还以为有人看着。
而真正该卡的是**开 MR 那一刻**,那是托管平台上的动作,不是 git 事件,pre-push hook
根本接不到。所以这类项目应该:
```bash
# 1. 建仓时【不加】 --enforce-clean-verify(或事后把 hook 里 enforce_cv 改 0)
# Gate 1(保护分支)照旧生效,个人分支随便推
# 2. 开 MR 之前跑这个,五项全过才去点开 MR
scripts/check_before_mr.sh \
--gateway-dir=<gateway> \
--clean-verify-dir=<clean-verify> \
--branch=<待 MR 的分支>
```
五项:
| | 查什么 | 漏了会怎样 |
|---|---|---|
| M1 | gateway 工作区干净 | 要 MR 的不是手上这份 |
| M2 | clean-verify 仓在位且是 git 仓 | 空目录 = 那道关卡从来没建起来过 |
| M3 | 盖章文件存在 | 压根没跑过 `clean-verify-run.sh` |
| M4 | 盖章 sha == 待 MR 分支 HEAD | **跑过,但之后又提交了几笔** —— 最容易漏的一种 |
| M5 | 远端分支 == 本地 HEAD | 本地验过没推,MR 提的是远端那份旧的 |
**怎么选**:每次 push 都该验 → 用 `--enforce-clean-verify`;
先推后 MR → 关掉它,改用 `check_before_mr.sh`。**两个都不用 = 那道关卡不存在。**
## Reference · 参考
- [Anthropic · harness design for long-running apps](https://www.anthropic.com/engineering/harness-design-long-running-apps)
- Full design spec: [`docs/design-mr-gated-dual-repo.md`](../../docs/design-mr-gated-dual-repo.md)
- Live demo: [`demos/gated-dual-clone/index.html`](../../demos/gated-dual-clone/index.html)
Files in this skill
- SKILL.md
- references/comparison.md
- references/daily-workflow.md
- references/decision-checklist.md
- references/guardrails.md
- references/patterns.md
- references/server-side-enforcement.md
- references/troubleshooting.md
- scripts/bootstrap.sh
- scripts/check_before_mr.sh
- scripts/clean-verify-run.sh
- scripts/install-hooks.sh
- scripts/sync-satellite.sh
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.