Ivan's Blog
主题

Worktree bootstrap

Worktree bootstrap 表示仓库把 linked worktree 的“首次进入可开发状态”当成正式 contract 来维护,而不是依赖维护者记忆、散落且无统一入口的手工 checklist,或假定只有主工作区才值得被照顾。

  • 工具
  • 运维

目录

Definition

Worktree bootstrap 表示仓库把 linked worktree 的“首次进入可开发状态”当成正式 contract 来维护,而不是依赖维护者记忆、散落且无统一入口的手工 checklist,或假定只有主工作区才值得被照顾。它关注的是:新 worktree 在首次 checkout 后,怎样通过自动 hook 或明确要求的 repo-owned setup 恢复最小必要的本地运行态,并且在历史 revision、奇怪 Git 布局和残留本地状态下仍然安全。

这个 Topic 既包含 octo-rill 那种“shared hooks + copy-missing-only local resources + smoke gate”的轻量同步模式,也包含 codex-vibe-monitor 已收敛的 Lefthook-only canonical bootstrap,blog-26 那种由维护文档强制要求、统一准备 dependencies / hooks / ports / dev DB 并可选安装 browser runtime 的显式 setup 模式,flux-purr 那种偏 repo-managed dependencies recovery 的模式,以及 tavreg-hikari 那种带 SQLite snapshot / browser runtime repair 的运行态补齐模式;dockrev 和 tavily-hikari 代表多层 Bun/Rust 依赖与 env copy-missing 的 hook-driven recovery,tuckmark 代表 Bun workspace 中由 Lefthook 驱动的幂等资源同步(projects/blog-26.md、projects/octo-rill.md、projects/codex-vibe-monitor.md、projects/flux-purr.md、projects/tavreg-hikari.md、projects/dockrev.md、projects/tavily-hikari.md、projects/tuckmark.md)。这些样本说明触发方式和恢复强度可以不同;实现选择仍须服从仓库已经采用的 hook/tooling surface,不能反过来改变 Topic 的命中条件。

它通常会和 Dockerized dev、Browser automation、Quality gates、PR label release 或 Playwright e2e 一起出现,但不替代这些 Topic:Worktree bootstrap 解释的是 linked worktree onboarding / environment recovery contract;相邻 Topic 解释具体 runtime、发布流程、浏览器自动化或门禁策略。这个 Topic 不包含端口管理或端口租约 contract 本身;setup 可以检查或准备端口前提,但端口分配规则仍应落在 Service ports 或更具体的环境约束里(projects/blog-26.md、projects/octo-rill.md)。

When to use

当 project snapshot、脚本、hooks 或 specs 明确表明“新 linked worktree 必须通过统一路径获得 hooks、本地资源、repo-managed 依赖、运行时资产或最小启动前提”时使用。命中条件不是“仓库支持 git worktree”,而是仓库已经把 readiness 写成正式 contract,并提供 repo-owned checked-in entrypoint;它可以由 post-checkout 自动触发,也可以是 README.md / AGENTS.md 明确要求新 worktree 执行的 shell script、Make/Just target、package.json script 或 task runner(projects/blog-26.md、projects/codex-vibe-monitor.md、projects/dockrev.md、projects/tavily-hikari.md、projects/tuckmark.md)。

如果一个改动会影响 shared hook 安装、共享 Git 层资源、post-checkout 行为、first-checkout trigger、copy-missing / no-overwrite 语义、worktree setup 与 bootstrap 的职责边界、repo-managed 依赖恢复、SQLite snapshot / runtime asset repair、历史 revision 的安全 no-op,或 linked worktree smoke test,就应该命中本 Topic(projects/octo-rill.md、projects/codex-vibe-monitor.md、projects/flux-purr.md、projects/tavreg-hikari.md、projects/dockrev.md、projects/tavily-hikari.md、projects/tuckmark.md)。

若仓库只是偶尔提一句“先 git worktree add 再自行准备环境”,没有唯一的 checked-in setup/bootstrap/install/sync 入口,也没有明确列出该入口恢复的 readiness 状态,则不应命中。若改动讨论的是端口分配、服务监听、preview URL 选择或 port registry,而不是 linked worktree 的 bootstrap/recovery contract,也不应命中这里(projects/blog-26.md、projects/octo-rill.md)。

Topic 一旦按上述标准命中,才进入实现选择:若仓库已经使用 Lefthook,默认直接采用 codex-vibe-monitor 展示的 Lefthook-only canonical bootstrap,不再让 Agent 自行选择 custom wrapper、dual entrypoint 或 weakened variant;任何偏离都需要主人明确决定。若仓库没有使用 Lefthook,应先依据现有 hook/tooling surface 提出可执行方案,再由主人决定引入 Lefthook 还是保留现有工具。Lefthook presence 是实现选择器,不是第二个 linked-worktree eligibility test(projects/codex-vibe-monitor.md)。

Habits / defaults

  • hooks 安装应通过 repo 内稳定入口收敛到 shared Git 层,这个入口可以是 checked-in shell script、Make/Just target、package.json script 或其他仓库自管 runner;重点不是放在哪个工具里,而是让所有 linked worktrees 继承同一条受维护的 hook chain,而不是在每个 worktree 各自漂移。这通常意味着要处理 core.hooksPath、common git dir、旧 hook 链串接和当前 revision 缺失脚本时的安全回退(projects/octo-rill.md、projects/flux-purr.md、projects/codex-vibe-monitor.md)。
  • 已使用 Lefthook 的仓库默认沿用 Lefthook-only canonical path:由 repo-owned install command 生成 standard shared hooks,post-checkout command 调用当前 revision 的 runner,再由同一 bootstrap/setup chain 完成本地资源与依赖恢复。Agent 不应额外生成 custom wrapper、保留双入口,或把 smoke/失败隔离降级成较弱变体;需要偏离时先取得主人明确决定(projects/codex-vibe-monitor.md)。
  • 未使用 Lefthook 的仓库不自动迁移。先盘点其既有 hook manager、task runner、shared Git layer 和安装入口,给出基于当前工具面的实现,再让主人在“引入 Lefthook”和“保留现有工具”之间作决定;不要仅因本 Topic 命中就擅自增加工具链(projects/octo-rill.md、projects/flux-purr.md)。
  • 采用自动触发时,应围绕首次 checkout / post-checkout 组织,并保持“当前 revision 缺脚本则 no-op、主工作区可安全跳过、重复 checkout 不做无意义重跑”的语义;worktree bootstrap 不应把日常 branch checkout 变成神秘副作用源(projects/octo-rill.md、projects/flux-purr.md)。采用显式 setup 时,则应由维护文档把同一个 checked-in entrypoint 标成新 worktree 的必需步骤,并让它一次性收敛所有 readiness 前提(projects/blog-26.md)。
  • “copy missing, never overwrite” 仍是最稳的默认值,尤其适用于 .env.local、本地 secrets、worktree-local overrides 和现有 ledger/runtime state。若仓库需要补齐本地资源,优先补缺、保留现有内容,而不是把 bootstrap 做成覆盖式同步(projects/octo-rill.md、projects/codex-vibe-monitor.md、projects/tavreg-hikari.md)。
  • 可以存在多种恢复层级,但职责要写清楚。codex-vibe-monitor 的 Lefthook post-checkout 会自动运行 copy-missing resource sync,并 best-effort 恢复 repo root、web、docs-site 与 Rust 依赖;手动 bootstrap 复用同一 setup chain 并保留聚合失败码。blog-26 的必需 setup 默认准备 dependencies、hooks、port preflight 和 dev DB seed,Playwright browsers 由 --with-e2e 显式启用;flux-purr、tavreg-hikari 则分别覆盖 device mono-repo dependencies、SQLite snapshot 或 browser runtime。重要的不是都做成同一触发方式或恢复强度,而是仓库要明确入口做什么、自动失败是否阻断 checkout、手动入口如何暴露失败(projects/blog-26.md、projects/codex-vibe-monitor.md、projects/flux-purr.md、projects/tavreg-hikari.md)。
  • odd Git layouts、历史 revision 和失效 hook runner / shim 要被当成一等约束。separate git dirs、custom core.hooksPath、stale pinned hook binary、旧 commit 缺 bootstrap 脚本、源 worktree 已删、主工作区路径已变、SQLite 工具能力不一致等场景,默认都应退化为 safe fallback / no-op / warning,而不是破坏 checkout(projects/octo-rill.md、projects/flux-purr.md、projects/tavreg-hikari.md)。
  • smoke gate 是高价值成熟度证据,因为这个 Topic 的价值不在脚本看起来“像是有 bootstrap”,而在真实 git worktree add 后真的能恢复到声明的状态。自动实现应优先用 linked worktree fixture 锁住 first-run bootstrap、历史 revision no-op、重复 rerun skip、已有本地文件 preservation 和依赖恢复边界;显式 setup 至少要让入口、恢复清单和失败状态可测试(projects/blog-26.md、projects/octo-rill.md、projects/codex-vibe-monitor.md、projects/flux-purr.md、projects/tavreg-hikari.md)。
  • 多层 Bun/Rust 仓库可以用 lockfile hash 或 worktree-local marker 做幂等跳过,但应把系统工具前置条件留在维护者环境中;dockrev 的 scripts/bootstrap-worktree.sh 和 tavily-hikari 的 strict repair 都证明了依赖恢复可以被测试而不扩大 hook 的职责(projects/dockrev.md、projects/tavily-hikari.md)。Bun workspace 也可以只同步缺失 .env.local 与本地资源,但必须保留重复执行安全性(projects/tuckmark.md)。
  • 回答或 review 这个 Topic 时,要优先问:linked worktree 的可用性是否被写成了 contract、自动路径和显式 setup 边界是否清楚、是否会误伤本地状态、历史 revision 是否安全、smoke test 是否真实覆盖。只讨论“脚本长得优不优雅”通常抓不到真正风险。

Reference implementations

  • projects/octo-rill.md:轻量 canonical 样本。它适合解释 shared hooks、post-checkout 首次触发、manifest 驱动的 copy-missing local resources、odd Git layout 回退与 smoke gate 怎样一起构成“linked worktree 自动可用”的基础 contract。
  • projects/codex-vibe-monitor.md:Lefthook 仓库的 canonical implementation。它用 Lefthook 生成 standard shared hooks,由 post-checkout command 调用当前 revision runner,并在 linked worktree 自动执行 copy-missing resource sync 与 best-effort dependency recovery;真实 linked-worktree smoke 覆盖全局 Lefthook 前置条件、unmanaged hook 保留、历史 revision no-op、依赖顺序和自动/手动失败边界。
  • projects/blog-26.md:显式 setup 型样本。README.md 与 AGENTS.md 要求 fresh checkout 或新 worktree 运行 repo-owned scripts/setup.sh,由一个入口统一依赖、hooks、port preflight 和 dev DB reset/seed,并以 --with-e2e 可选安装 Playwright browsers;它说明 Topic applicability 不要求所有仓库都采用隐式 post-checkout。
  • projects/flux-purr.md:适合说明设备 mono-repo 的 repo-managed dependency recovery。它强调 shared hooks、root/web dependency install、Cargo fetch 预热、历史 revision no-op 和 required smoke gate,能代表“worktree bootstrap 不止是 copy files”的一面。
  • projects/tavreg-hikari.md:适合说明运行态资产恢复型 bootstrap。它把 .env.local、SQLite ledger snapshot、dependency bootstrap 与 browser runtime repair 组合在一起,同时保持 best-effort、不覆盖已有本地状态和 checkout 不阻断,是高强度 environment recovery 的样本。
  • projects/dockrev.md:代表 Bun/Rust 多 surface 的依赖 bootstrap。它通过 shared post-checkout 恢复根目录、web/、docs-site/ 依赖并执行 cargo fetch --locked,以 lockfile hash stamp 避免无意义重复安装。
  • projects/tavily-hikari.md:代表带 env copy-missing、依赖恢复和 strict repair 的 proxy 仓库实现;自动路径 best-effort,手动路径才暴露聚合失败。
  • projects/tuckmark.md:代表 Bun workspace 的 Lefthook 资源同步。它用 scripts/setup.ts 和 scripts/sync-worktree-resources.ts 统一初始化 submodule、hooks 与缺失本地资源,并由真实 linked-worktree smoke 验证幂等性。
  • skills/policies/worktree-bootstrap/SKILL.md:Policy Skill 的价值在于给后续 Agent 一个稳定消费面,让它先确认项目是否有 linked-worktree readiness contract,再执行“Topic classification → tooling-based implementation selection → owner decision on exceptions”的规则。

Failure modes

  • 把任意 hooks 脚本、一次性 setup 命令或“README 里提到 worktree”都叫 Worktree bootstrap,会让 Topic 失去边界;关键是 linked-worktree readiness 是否由唯一 repo-owned 入口和明确恢复清单形成正式 contract,而不是命令名称本身。
  • 把“仓库使用 Lefthook”重复写进 Topic applicability,会混淆分类与实现选择:仓库先因正式 linked-worktree readiness contract 命中 Topic,Lefthook presence 只在命中后选择 canonical implementation。反过来,使用 Lefthook 本身不代表仓库拥有 Worktree bootstrap。
  • 已使用 Lefthook 时仍让 Agent 即兴选择 custom wrapper、dual entrypoint 或弱化 smoke/failure contract,会重新制造多个真相来源;未获主人明确决定时应保持 Lefthook-only canonical path。对于没有 Lefthook 的仓库,直接自动迁移同样越过了工具链决策边界。
  • 把这个 Topic 当成“所有本地开发环境问题”的总括标签,会吞掉 Service ports、Dockerized dev、Browser automation、Quality gates 等相邻主题。尤其端口管理不应混进来,否则以后遇到 worktree-local port leases 还是 hooks/bootstrap 语义,Agent 会判不清。
  • 覆盖本地 secrets、覆盖已有 .env.local / ledger / runtime assets、或把 forced rerun 做成 destructive rewrite,会让维护者很快失去信任,不再敢用自动 bootstrap(projects/octo-rill.md、projects/tavreg-hikari.md)。
  • 只在主工作区能跑、linked worktree 一创建就缺依赖/缺脚本/缺本地状态,说明仓库仍在依赖维护者记忆;这类实现即使脚本很多,也不应被误判为成熟 Worktree bootstrap。
  • 历史 revision 缺脚本、主工作区已删除、core.hooksPath 自定义、旧二进制失效、或本机工具能力不一致时直接报错,会让 hook-based bootstrap 在真实世界里迅速坏掉;好的实现默认要能安全跳过或降级。
  • 没有真实 linked worktree smoke test 的 bootstrap 很容易长期漂移成“脚本还在、契约已坏”;当仓库把 Worktree bootstrap 当成正式 taxonomy 时,这类 smoke gate 基本应被视为高价值佐证。

Evidence index

  • projects/blog-26.md
  • projects/octo-rill.md
  • projects/codex-vibe-monitor.md
  • projects/flux-purr.md
  • projects/tavreg-hikari.md
  • projects/dockrev.md
  • projects/tavily-hikari.md
  • projects/tuckmark.md
  • skills/style-playbook/references/data/topics/worktree-bootstrap.json
  • skills/policies/worktree-bootstrap/SKILL.md