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
Copy Markdown
Contributor

@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
Copy Markdown
Contributor

❌ 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
Copy Markdown
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
Copy Markdown
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

@github-actions
Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions Bot added the stale label Apr 24, 2026
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