Skip to content

feat(worktree-isolation): refresh the wtg reference to the current engine#137

Open
KailasMahavarkar wants to merge 1 commit into
mainfrom
feat/wtg-refresh
Open

feat(worktree-isolation): refresh the wtg reference to the current engine#137
KailasMahavarkar wants to merge 1 commit into
mainfrom
feat/wtg-refresh

Conversation

@KailasMahavarkar

Copy link
Copy Markdown
Collaborator

The problem

references/wtg.reference.sh is the adoption artifact for the Multi-Repo Feature Groups pattern, but it had drifted well behind the tool it documents. Adopters copying it got a version missing the things that make the pattern actually survive daily use, and one that leaves seeded secrets world-readable.

What a member needs to be runnable

flowchart TB
    A[git worktree add] --> B[tracked files only]
    B --> C{runnable?}
    C -->|no| D[gitignored config absent<br/>service boots mis-configured]
    C -->|no| E[dep dir absent<br/>node_modules / .venv]
    D --> F[seed config -- install -m 600]
    E --> G[build deps from WTG_SETUP]
    F --> H[runnable member]
    G --> H
Loading

Note

git worktree add checks out tracked files only. Config and dependencies are both invisible to it, so creation has to supply both or the failure is just deferred to first run.

Why these changes

change buys picked
deps + auto-seed on create creation leaves a runnable tree instead of one that dies on first run yes
explicit bind a typo can no longer create a group and rebind the tree away from its real one yes
--base <ref>, bare name -> origin/<name> always cut from the latest remote tip, never a stale local branch yes
st table + warnings block see the state of a feature-set, with the fix command for each problem yes
process-group kill on down orphaned children no longer squat ports and serve stale code yes
install -m 600 when seeding secrets stop inheriting the caller's umask yes
copy the local tool verbatim fastest no - it carries one stack's repos, ports and OAuth URLs

Warning

Killing only the recorded pid left the pnpm->vite and uvicorn-reloader children alive holding the ports. Every later up then failed with EADDRINUSE while the orphans kept serving stale code. Members now launch in their own process group and down kills the group.

What changed

  • references/wtg.reference.sh - engine refresh; new deps and bind verbs, --base / --no-env / --no-deps, st --fetch, help, richer st renderer, process-group up/down, and WTG_WORKDIR / WTG_DEPS / WTG_SETUP / WTG_LAUNCHER_ARGS / WTG_OAUTH_ROLES config knobs. WTG_API_ROLE splits from WTG_PRIMARY_ROLE, since the backend a frontend calls is not always the tree the agent opens in nor the one holding the OAuth redirect (%PRIMARY_PORT% -> %API_PORT%).
  • references/SETUP.md - config block, placeholder table, quickstart and command reference brought in line.
  • references/multi-repo-feature-groups.md - deps verb, the dependencies-are-not-carried gap, and the seeding-mode requirement.
  • SKILL.md - two quick-reference rows and the matching runtime-hazard bullets.

Defaults stay tool-agnostic: XDG paths, a generic api/web example, and no launcher arguments.

Verifying

bash -n clean. Exercised end to end against throwaway repos with real origin remotes:

wtg new demo api web      worktrees cut from origin/main, dev.sh generated,
                          config seeded, deps built, table renders
slot 1 group              api :8090 / web :3010, OAuth warning in table and
                          in the generated dev.sh header
wtg claim-oauth billing   swapped billing -> slot 0, demo -> slot 1
wtg bogusname             exit 1, no group created
wtg up / down             both members spawned, killed by pgid, none left alive
generated dev.sh          bash -n clean; OAuth prelude only on OAuth roles;
                          WTG_WORKDIR cd and %API_PORT% substituted
seeded config             0600 under umask 0002 (cp previously gave 0644)

Important

bun run build was not run - tsc is absent in a fresh clone without bun install. This change touches only .sh and .md, no TypeScript.

…gine

The reference implementation had drifted well behind the working tool. Brings
across the engine improvements, keeping the same shape: a CONFIG block of pure
data and a stack-agnostic engine that hardcodes no role, port, or path.

New surface:
- deps: declare a dep dir per role (node_modules, .venv) and the command that
  builds it. A worktree is only a checkout, so without this a fresh member
  starts and immediately dies. new/add now seed config and build deps, leaving
  a runnable tree; --no-env/--no-deps opt out.
- bind: creating a group from the current tree is now explicit. A bare
  `wtg <name>` binds only into an existing group, so a typo such as
  `wtg downfoo` can no longer create a group, rebind the tree away from its
  real one, and overwrite its dev.sh.
- --base <ref>: per-run start point. Repos are fetched first and a bare name
  resolves to origin/<name>, so a worktree is cut from the latest remote tip
  rather than a stale local branch.
- st: one table carrying branch, clean/DIRTY, upstream, commits behind base,
  port, config and dep state, followed by a warnings block that prints the
  exact command to fix each problem. --fetch refreshes first.
- up/down: members launch in their own process group and down kills the group.
  Killing only the recorded pid left the pnpm->vite and uvicorn-reloader
  children alive holding the ports, so every later up died with EADDRINUSE
  while orphans kept serving stale code.
- WTG_WORKDIR, WTG_LAUNCHER_ARGS, WTG_OAUTH_ROLES, and WTG_API_ROLE split from
  WTG_PRIMARY_ROLE, since the backend a frontend calls is not always the tree
  the agent opens in nor the one holding the OAuth redirect.

Seeded config is written with install -m 600 rather than cp. These files carry
live secrets and cp takes the caller's umask, which on a common 0002 leaves
them world-readable at 0644.

Defaults stay tool-agnostic: XDG paths, a generic api/web example, and no
launcher arguments.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant