Skip to content

feat(dx): Phase 2 — worktree-aware development with worktrunk#35101

Open
spbolton wants to merge 1 commit intophase-1/development-environment-setupfrom
phase-2/development-environment-setup
Open

feat(dx): Phase 2 — worktree-aware development with worktrunk#35101
spbolton wants to merge 1 commit intophase-1/development-environment-setupfrom
phase-2/development-environment-setup

Conversation

@spbolton
Copy link
Member

@spbolton spbolton commented Mar 24, 2026

Summary

Layers worktree-specific features on top of Phase 1's universal dev setup. Requires worktrunk (wt) for full functionality.

Note: This PR preserves the worktree-aware features from the original branch for completeness. We may choose not to merge Phase 2 in its current form — the worktree integration may be revisited, simplified, or deferred depending on how Phase 1 lands and what the team's actual parallel development needs look like in practice.

  • worktrunk added to mise tools with shell integration in just setup
  • .config/wt.toml — post-create hooks: copy caches via reflink, run just init, re-tag Docker image, assign deterministic port
  • .worktreeinclude — scopes which gitignored files get copied between worktrees (Nx cache, Angular cache, .venv)
  • dotcms-worktree skill — branching patterns, sub-task workflows, agent spawning (3 options), merge/cleanup
  • Branch-based slugs (_worktree-slug) layered on folder-based (_project-slug) for richer container naming
  • worktree-init recipe wrapping init with worktree-specific steps
  • dev-shared-drop-worktree recipe for per-worktree shared data cleanup
  • AGENTS.md Worktrees section with EnterWorktree warning
  • DEV_ENVIRONMENT_SETUP.md Worktrunk section with warm-start docs

Stacked on

Phase 1: #35100

Test plan

  • just setup installs worktrunk and shell integration
  • wt switch --create test-branch creates warm-start worktree
  • .dev-port file created with deterministic port
  • just dev-run uses worktree-specific image tag
  • just dev-shared-drop-worktree cleans DB + indexes for current worktree

🤖 Generated with Claude Code

Fixes: #34722

Layers worktree-specific features on top of the Phase 1 universal dev
setup. Requires worktrunk (wt) for full functionality.

Adds:
- .config/wt.toml — post-create/pre-remove hooks for warm worktree starts
- .worktreeinclude — files copied between worktrees via reflink
- dotcms-worktree skill — branching, merging, agent spawning patterns
- worktrunk tool in .mise.toml with shell integration in setup
- Worktrees section in AGENTS.md with EnterWorktree warning
- Worktrunk section in DEV_ENVIRONMENT_SETUP.md
- Branch-based slugs (_worktree-slug) layered on folder-based (_project-slug)
- worktree-init recipe wrapping init with worktree-specific steps
- dev-shared-drop-worktree recipe for worktree cleanup
- Worktree references in dev-services skill and CONTEXT_ARCHITECTURE.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link

❌ Issue Linking Required

This PR could not be linked to an issue. All PRs must be linked to an issue for tracking purposes.

How to fix this:

Option 1: Add keyword to PR body (Recommended - auto-removes this comment)
Edit this PR description and add one of these lines:

  • This PR fixes #123 or Fixes: #123

  • This PR closes #123 or Closes: #123

  • This PR resolves #123 or Resolves: #123

  • Other supported keywords: fix, fixed, close, closed, resolve, resolved
    Option 2: Link via GitHub UI (Note: won't clear the failed check)

  1. Go to the PR → Development section (right sidebar)

  2. Click "Link issue" and select an existing issue

  3. Push a new commit or re-run the workflow to clear the failed check
    Option 3: Use branch naming
    Create a new branch with one of these patterns:

  • 123-feature-description (number at start)

  • issue-123-feature-description (issue-number at start)

  • feature-issue-123 (issue-number anywhere)

Why is this required?

Issue linking ensures proper tracking, documentation, and helps maintain project history. It connects your code changes to the problem they solve.---

This comment was automatically generated by the issue linking workflow

@claude
Copy link
Contributor

claude bot commented Mar 24, 2026

Claude finished @spbolton's task in 2m 37s —— View job


PR Review — Phase 2: Worktree-Aware Development

  • Read changed files
  • Review justfile changes
  • Review .config/wt.toml
  • Review skill files
  • Review docs and AGENTS.md
  • Post findings

Issues Found

1. dotcms-dev-services/SKILL.md has stale references (not updated)

The SKILL.md was modified in this PR (+39/-37) but two broken recipe names survived:

  • Line 106 & 124: just dev-shared-drop-project — renamed to just dev-shared-drop-worktree
  • Line 150: just project-init — this never existed and presumably should be just worktree-init

These will cause agents following the cleanup lifecycle to run non-existent recipes. Fix this →

2. DEV_ENVIRONMENT_SETUP.md warm-start table contradicts .worktreeinclude

The added documentation lists these as being copied:

Pattern Size Claimed
target/ ~3GB Maven build output
core-web/node_modules/ ~2.8GB Frontend dependencies
.cache/ varies Maven build cache

But .worktreeinclude explicitly says the opposite:

# Intentionally excludes target/ and .cache/...
# node_modules is NOT copied — yarn install must run fresh...

And the wt.toml comment confirms: "Nx/Angular caches only, NOT node_modules". The docs describe warm-start as avoiding a rebuild, but without target/ being copied that claim doesn't hold. This will mislead anyone reading the docs about what actually gets copied and whether a rebuild is needed. Fix this →

3. wt.toml template filters sanitize and hash_port need verification

image = """
docker tag "dotcms/dotcms-test:{{ base | sanitize }}" "dotcms/dotcms-test:{{ branch | sanitize }}" ...
"""
port = "echo {{ branch | hash_port }} > {{ worktree_path }}/.dev-port"

If sanitize or hash_port are not valid worktrunk template filters, {{ branch | hash_port }} will be written literally to .dev-port. Then dev-run reads that file as PORT, and Maven receives a non-numeric port — hard failure. The image hook is less critical since it falls through to || true, but the port hook has no fallback (other than the default 8082, which won't be used since .dev-port will exist with garbage content). Worth confirming these filters exist in the worktrunk docs before merging.

4. _worktree-slug slug collision: same branch, two local directories

Phase 1's _project-slug used basename "$(pwd)" — folder-based, unique on a single machine. Phase 2 uses git rev-parse --abbrev-ref HEAD — branch-based. If a developer has the same branch checked out in two directories (e.g., testing a rebase), both get the same slug → same container name dotbuild_dotcms-core_${WSLUG}_dotcmsdocker run fails on the second one with a name conflict. Phase 1 didn't have this problem. Low probability but worth documenting as a gotcha.

5. Slug sanitization duplicated between justfile and wt.toml

The post-remove cleanup in wt.toml duplicates the slug sanitization:

# wt.toml post-remove
SLUG=$(echo "{{ branch }}" | sed 's/[^a-zA-Z0-9._-]/-/g; s/^[.-]*//' | cut -c1-64)
# justfile _worktree-slug
@git rev-parse --abbrev-ref HEAD 2>/dev/null \
    | sed 's/[^a-zA-Z0-9._-]/-/g; s/^[.-]*//' | cut -c1-64 \

These are identical today, but if one diverges the cleanup will target the wrong container. This is unavoidable (the worktree may already be removed during post-remove, so just _worktree-slug can't run). Adding a comment noting this coupling would reduce future breakage risk.


Minor

  • dotcms-dev-services/SKILL.md still uses "project" terminology internally (lines 46, 84, 88, 90, etc.) after the rename wave — inconsistent with the new "worktree" language, though functionally harmless.
  • The just worktree-init recipe comment says "Called by wt.toml post-create hook — keeps logic in one place" — good, but the setup dependency it chains means every new worktree creation re-runs the worktrunk shell integration install (wt config shell install). This is idempotent per the || true, so no real harm.

@claude
Copy link
Contributor

claude bot commented Mar 24, 2026

Claude finished @spbolton's task in 1m 11s —— View job


Rollback Safety Analysis

  • Read rollback-unsafe categories reference
  • Get full PR diff
  • Analyze diff against unsafe categories
  • Applied label: AI: Safe To Rollback

All 10 changed files are developer experience / tooling changes only:

File Type
justfile Recipe renames (_project-*_worktree-*, initworktree-init, dev-shared-drop-projectdev-shared-drop-worktree) + comment updates
.mise.toml Adds worktrunk tool
.config/wt.toml New worktree post-create hook config
.worktreeinclude New file scoping gitignored files copied between worktrees
docker/docker-compose-shared-services.yml Comment-only change
AGENTS.md / docs/** Documentation updates
.claude/skills/** AI assistant skill files

No matches found against any unsafe category (C-1 through C-4, H-1 through H-7, M-1 through M-4):

  • ❌ No database migrations or runonce tasks
  • ❌ No Elasticsearch mapping changes
  • ❌ No content JSON model versioning
  • ❌ No REST/GraphQL API contract changes
  • ❌ No OSGi interface changes
  • ❌ No storage provider changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant