dogfood-worktree · git:20260625.1d84427 · 2026-06-25 · sha256 1a8fae4713ffbf23
dogfood-worktree git:20260625.1d84427A
Immutable. This exact content is served forever at /api/v1/blob/1a8fae4713ffbf23.
---
name: dogfood-worktree
description: Procedure for dogfooding Myco changes inside a git worktree so capture, MCP, and CLI route to the worktree's own build instead of the production binary. Use when developing Myco in a git worktree, when capture/MCP in a worktree behaves like production or points at the wrong build, or when wiring up `make dev-link-worktree` / `make dev-unlink-worktree`. Covers why `.myco/runtime.command` does not travel with `git worktree add`, why a build must happen first, the direct-CLI `MYCO_HOME` gotcha, the shared-vault schema rollup hazard across worktrees, and the vendor-asset build gotcha.
---
# Dogfooding Myco in a Git Worktree
This is a **dogfood-only** concern — myco using myco to build myco. A regular
user just has one `myco` installed; their own worktrees "just work" because
everything resolves to that single binary. The complexity here exists only
because we run a **dev** binary (`myco-dev`) alongside the **prod** binary
(`myco`) and need capture to keep working while we change Myco itself.
## The core gotcha: a fresh worktree is not myco-dev aware
Binary resolution (global launcher `~/.myco/launcher.cjs` and `bin/myco-run`)
walks **up from the working directory** looking for `<dir>/.myco/runtime.command`,
then the machine pin, then the vendored binary, then PATH `myco`.
`.myco/runtime.command` is **gitignored** (`.myco/.gitignore`). `git worktree add`
only materializes *tracked* files, so a new worktree starts with **no pin**.
With no pin:
- A worktree **nested** under the main checkout (e.g. `.worktrees/foo`) walks up
and finds the *main checkout's* pin → runs **main's `myco-dev`** (stale vs. the
worktree's changes).
- A **sibling** worktree (e.g. `../myco-foo`) finds nothing → hooks fall through
to PATH `myco` = the **production** binary. Capture then hits the prod
daemon/vault. Unacceptable for dogfooding.
Either way a fresh worktree never uses **its own** build until you pin it.
## Procedure
1. **Create the worktree** off the branch you're developing:
```bash
git worktree add ../myco-<feature> <branch>
cd ../myco-<feature>
```
2. **Pin it to its own build:**
```bash
make dev-link-worktree
```
This depends on `dev-build`, so it **builds the worktree's binary first**,
then writes `<worktree>/.myco/runtime.command` → `packages/myco-<target>/bin/myco`.
It does **not** touch the shared `~/.local/bin/myco-dev` symlink (the main
checkout and other agents rely on it), and it does **not** write project-local
launchers (`.agents/myco-run.cjs` is retired — the global launcher + cwd-walk
handle routing through the pin).
3. **Verify binary routing and vault home separately:**
```bash
myco --version
myco doctor
```
`make dev-link-worktree` pins the **binary** only. It writes
`<worktree>/.myco/runtime.command` directly to
`packages/myco-<target>/bin/myco`; it does **not** write a wrapper that exports
`MYCO_HOME`, and adding `<worktree>/.myco/runtime.home` alone is not enough
for direct `myco` CLI calls. A sibling worktree can therefore run the
worktree binary while still talking to the production home/daemon
(`~/.myco`) for `myco tool call`, `myco doctor`, plan lookups, and session
lookups.
When you need direct CLI calls to read or mutate the dogfood dev vault, prefix
the command explicitly:
```bash
MYCO_HOME="$HOME/.myco-dev" MYCO_CLAIMS_HOME="$HOME/.myco" \
myco tool call myco_plans --json --input '{"op":"list","limit":5}'
```
Verify the result against the main checkout before mutating plan/session
state. Do not treat `git rev-parse --git-common-dir`, a matching
`.myco/project.toml`, or a URL/project slug as proof that the worktree is
using the same daemon or Grove DB; `myco doctor` and a known plan/session
lookup are the proof.
4. **Revert when done:**
```bash
make dev-unlink-worktree # removes the worktree's .myco/runtime.command
```
Resolution then falls back through the chain (→ prod `myco` for a sibling
worktree), so unlink only when you're finished dogfooding that worktree.
## Caveats — codified so we stop rediscovering them
### Shared-vault schema rollup (the big one)
Every worktree **and** the main checkout resolve to the **same** Grove vault
(`myco.db`) via `git-common-dir`. Each worktree pins to its **own** binary. So a
worktree whose binary runs a **schema migration** mutates the *shared* DB — and
the main checkout or another worktree on an **older** build can then break
(missing/renamed columns, `user_version` mismatch). This is the accepted cost of
the rollup-to-main-vault design; a per-worktree vault was rejected because it
fragments dogfood data and contradicts "worktrees attach to the main project."
- Run **one schema-changing worktree at a time**; rebuild the others to match.
- For genuinely risky schema work, use a temp `MYCO_HOME` sandbox so the shared vault is never mutated.
### A build must succeed first
The pin points at `packages/myco-<target>/bin/myco` *inside* the worktree, so that
binary has to exist — `make dev-link-worktree` builds it. **Worktree builds can
fail** when local, gitignored vendor assets (e.g.
`packages/myco/vendor-src/libsqlite3/<target>/libsqlite3.dylib`) exist in the main
checkout but didn't travel to the worktree. If `dev-build` fails on a missing
vendor asset, copy/symlink it from the main checkout (or rebuild it in the
worktree) and re-run `make dev-link-worktree`.
### Daemon-side changes: dogfood from the MAIN checkout, never the worktree
The worktree pin only routes **hooks, MCP, and CLI** to the worktree binary. The
dev **daemon** always runs the **main dev binary** — its launchd service points at
the main checkout's `packages/myco-<target>/bin/myco`, so a worktree pin does NOT
change which code the daemon runs.
To dogfood **daemon-side** changes (schema migrations, reconcile/daemon logic):
check out the feature branch on the **main checkout** and rebuild + restart there —
`make dev-build && myco-dev restart`. After a worktree teardown + rebase the
`~/.local/bin/myco-dev` symlink already points at the main binary, so **no
`make dev-link` is needed** — only re-link if the symlink was removed or you are
switching which branch the daemon tracks.
**The worktree daemon path no longer self-isolates.** The dev daemon variant has
no separate home — it writes to `~/.myco-dev` regardless of which binary runs it,
so starting the daemon from a worktree binary would share state with the main
dev daemon. **Never** `make dev-link` from a worktree, and
**never** run the daemon or migrate the shared vault from a worktree — a worktree
binary running a migration mutates the *shared* Grove vault and breaks the main/other
builds (the rollup hazard above). The only isolated path is exercising the merged
code against a **separate `MYCO_HOME`** (e.g. a temp git repo with
`MYCO_HOME=~/.myco-sandbox`) — that does not touch the shared vault.
> Myco is the most active source of truth: search the vault ("worktree dogfood")
> before trusting this skill if they disagree. See also the
> `daemon-process-lifecycle-management` skill for the canonical build/restart commands.
## Related
- `make dev-link` / `make dev-unlink` — the main-checkout dev pin (rewrites the
shared `~/.local/bin/myco-dev` symlink); never run these from a worktree