Skip to content

Round 44: parallel-worktree-safety cartographer research#35

Merged
AceHack merged 1 commit intomainfrom
research/parallel-worktree-safety
Apr 21, 2026
Merged

Round 44: parallel-worktree-safety cartographer research#35
AceHack merged 1 commit intomainfrom
research/parallel-worktree-safety

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 21, 2026

Summary

  • Lands docs/research/parallel-worktree-safety-2026-04-22.md (223 lines).
  • Cartographer-before-walk research doc for parallel worktree use in this factory.
  • Eight hazard classes, each paired with preventive + compensating mitigations per the discovered-class-outlives-fix principle.

Hazard classes

  1. Live-lock between parallel worktrees
  2. Merge conflicts as expected cost
  3. Build-speed ceiling (parallelism bounded by CI latency)
  4. Stale-branch accumulation
  5. Memory bifurcation (session-slug semantics)
  6. Tick-clock CWD inheritance
  7. Split state files
  8. Unknown unknowns (the cartographer discipline itself)

Outcome

Test plan

  • Markdownlint clean.
  • CI green.
  • Doc lands under docs/research/ — inherits first-draft status per research-doc norms.

🤖 Generated with Claude Code

Research doc enumerating eight hazard classes for parallel
worktree use, each paired with preventive + compensating
mitigations per the discovered-class-outlives-fix principle:

1. Live-lock between parallel worktrees
2. Merge conflicts as expected cost
3. Build-speed ceiling
4. Stale-branch accumulation
5. Memory bifurcation
6. Tick-clock CWD inheritance
7. Split state files
8. Unknown unknowns (cartographer discipline)

Staging R45-R49 proposed for EnterWorktree-default flip.

Originates from Aaron 2026-04-22 nine-message sequence
captured in memory `feedback_parallel_worktree_safety_
cartographer_before_default.md`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 21, 2026 10:45
@AceHack AceHack merged commit 96c168a into main Apr 21, 2026
13 checks passed
@AceHack AceHack deleted the research/parallel-worktree-safety branch April 21, 2026 10:48
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a research “cartographer pass” documenting hazards and mitigations for making parallel Git worktrees the factory default, including a staged rollout proposal.

Changes:

  • Introduces an 8-class hazard map for parallel-worktree operation with preventive + compensating mitigations.
  • Proposes instrumentation/backpressure guidance tied to CI gate latency.
  • Outlines a Round 45–49 staging plan for a potential EnterWorktree default flip.


Claude Code's auto-memory lives at `~/.claude/projects/<slug>/memory/` where `<slug>` is the session's initial CWD with `/` replaced by `-`. Example: `~/.claude/projects/-Users-acehack-Documents-src-repos-Zeta/memory/`.

- **Single session that uses `EnterWorktree`:** the slug is set when the session starts, based on the initial CWD (the main repo root). `EnterWorktree` changes the session's CWD but does NOT re-keyed the slug. Memory continues to load/write from the original slug. Tool calls using absolute paths (which all of mine do) work identically across the boundary. **Verified**: this tick's session started in `/Users/acehack/Documents/src/repos/Zeta`, entered a worktree at `.claude/worktrees/pr32-markdownlint`, wrote three memory files from within the worktree, and `ls ~/.claude/projects/` shows only the main-repo slug — no worktree-specific slug was created.
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Grammar issue: “does NOT re-keyed the slug” is ungrammatical; it reads like a mix of active/passive voice. Rephrase to “does not re-key the slug” or “the slug is not re-keyed” to keep the statement clear.

Suggested change
- **Single session that uses `EnterWorktree`:** the slug is set when the session starts, based on the initial CWD (the main repo root). `EnterWorktree` changes the session's CWD but does NOT re-keyed the slug. Memory continues to load/write from the original slug. Tool calls using absolute paths (which all of mine do) work identically across the boundary. **Verified**: this tick's session started in `/Users/acehack/Documents/src/repos/Zeta`, entered a worktree at `.claude/worktrees/pr32-markdownlint`, wrote three memory files from within the worktree, and `ls ~/.claude/projects/` shows only the main-repo slug — no worktree-specific slug was created.
- **Single session that uses `EnterWorktree`:** the slug is set when the session starts, based on the initial CWD (the main repo root). `EnterWorktree` changes the session's CWD but does NOT re-key the slug. Memory continues to load/write from the original slug. Tool calls using absolute paths (which all of mine do) work identically across the boundary. **Verified**: this tick's session started in `/Users/acehack/Documents/src/repos/Zeta`, entered a worktree at `.claude/worktrees/pr32-markdownlint`, wrote three memory files from within the worktree, and `ls ~/.claude/projects/` shows only the main-repo slug — no worktree-specific slug was created.

Copilot uses AI. Check for mistakes.
Comment on lines +206 to +210
- `memory/feedback_discovered_class_outlives_fix_anti_regression_detector_pair.md` — the principle this research instantiates across 8 hazards.
- `memory/feedback_live_loop_detector_speculative_on_pr_branch.md` — the live-loop class that motivated the worktree pattern in the first place.
- `docs/research/worktree-pattern-for-live-loop-prevention-2026-04-22.md` — the prior research doc that introduced `EnterWorktree` to the factory; this doc extends it from single-worktree to parallel-worktree safety.
- `memory/feedback_kanban_factory_metaphor_blade_crystallize_materia_pipeline.md` — cartographer metaphor source.
- `memory/feedback_never_idle_speculative_work_over_waiting.md` — the rule that drives tick-cadence; parallelism must not violate it via backpressure-starvation.
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 (xref): Several items in “Related docs & memories” point to files that aren’t present in the repo at the cited paths (e.g., memory/feedback_discovered_class_outlives_fix_anti_regression_detector_pair.md, memory/feedback_live_loop_detector_speculative_on_pr_branch.md, docs/research/worktree-pattern-for-live-loop-prevention-2026-04-22.md). Please either add these files in the PR or update the references to the correct existing locations so pointer-integrity audits don’t fail.

Suggested change
- `memory/feedback_discovered_class_outlives_fix_anti_regression_detector_pair.md` — the principle this research instantiates across 8 hazards.
- `memory/feedback_live_loop_detector_speculative_on_pr_branch.md` — the live-loop class that motivated the worktree pattern in the first place.
- `docs/research/worktree-pattern-for-live-loop-prevention-2026-04-22.md` — the prior research doc that introduced `EnterWorktree` to the factory; this doc extends it from single-worktree to parallel-worktree safety.
- `memory/feedback_kanban_factory_metaphor_blade_crystallize_materia_pipeline.md` — cartographer metaphor source.
- `memory/feedback_never_idle_speculative_work_over_waiting.md` — the rule that drives tick-cadence; parallelism must not violate it via backpressure-starvation.
- The discovered-class-outlives-fix rule — the principle this research instantiates across 8 hazards.
- The live-loop detector rule for speculative work on PR branches — the live-loop class that motivated the worktree pattern in the first place.
- The prior worktree-pattern research doc that introduced `EnterWorktree` to the factory; this doc extends it from single-worktree to parallel-worktree safety.
- `memory/feedback_kanban_factory_metaphor_blade_crystallize_materia_pipeline.md` — cartographer metaphor source.
- The never-idle speculative-work-over-waiting rule — the rule that drives tick-cadence; parallelism must not violate it via backpressure-starvation.

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +5
**Date:** 2026-04-22
**Trigger:** Aaron across nine messages in one tick:

Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 (codebase convention): This doc uses the human maintainer’s personal name (“Aaron”) in narrative headings and throughout. The repo standard is to avoid name attribution in docs/skill bodies and use role refs (e.g., “human maintainer”) instead (see docs/AGENT-BEST-PRACTICES.md:284-290). Please rename the references accordingly (and keep names confined to the allowed locations).

Copilot uses AI. Check for mistakes.
**Preventive:**

- **Auto-delete branch on PR merge.** GitHub setting: *Automatically delete head branches* (Settings → General → Pull Requests). One-time toggle; subsequent PR merges auto-delete their branch.
- **Auto-delete branch on PR close (unmerged).** Same setting covers this since PR close and merge both fire the hook.
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The claim that GitHub’s “Automatically delete head branches” setting also deletes branches when a PR is closed unmerged appears incorrect; it deletes the head branch after a PR is merged. If you want deletion-on-close, document a separate mechanism (workflow/bot) or adjust the text to avoid implying the setting covers both cases.

Suggested change
- **Auto-delete branch on PR close (unmerged).** Same setting covers this since PR close and merge both fire the hook.
- **PR close (unmerged) needs a separate mechanism.** GitHub's *Automatically delete head branches* setting does **not** delete branches when a PR is closed unmerged. If we want deletion-on-close, document and ship that separately as a workflow/bot policy; otherwise rely on the audits below plus the factory's explicit branch-removal convention.

Copilot uses AI. Check for mistakes.
**Policy for the factory:**

- **Always start Claude Code from the main repo root.** Use `EnterWorktree` for worktree work. Do not `cd <worktree> && claude` — that bifurcates memory.
- Document this rule in `docs/AUTONOMOUS-LOOP.md` under "session-start checklist" (if that section exists; otherwise add one).
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 (xref): This section instructs updating docs/AUTONOMOUS-LOOP.md, but that file does not exist in the repo at this path. Please either point to the correct existing doc (if renamed) or add the missing doc/update the reference so the action item is actionable.

Suggested change
- Document this rule in `docs/AUTONOMOUS-LOOP.md` under "session-start checklist" (if that section exists; otherwise add one).
- Document this rule in `CLAUDE.md` under a session-start checklist or startup hygiene section (add that section if it does not exist yet).

Copilot uses AI. Check for mistakes.
Comment on lines +132 to +140
A worktree is a separate working directory. Files that are auto-appended-to every tick (e.g. `docs/hygiene-history/loop-tick-history.md`) will diverge between the worktree and main if the tick runs in the worktree.

**Example of the hazard (this tick almost hit it):** I entered `pr32-markdownlint` worktree on `round-42-speculative`. If I had written to `docs/hygiene-history/loop-tick-history.md` *from within the worktree* instead of *from the main repo*, the entry would have landed on the wrong branch and wrong working-tree copy. Then at tick close, the main repo wouldn't reflect the tick.

**Class-detector:** tick-history appends must happen in the main repo, not inside a worktree. Enforcement options:

1. CLAUDE.md rule: "append tick-history *after* `ExitWorktree`, never before."
2. Pre-commit hook: if a commit modifies `docs/hygiene-history/loop-tick-history.md` AND the branch is not `main`/`round-NN-speculative`, refuse.
3. A helper function `append-tick-history.sh` that `cd`s to main root before writing.
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 (xref): The referenced hygiene-history path docs/hygiene-history/loop-tick-history.md (and the docs/hygiene-history/ directory) doesn’t exist in the repo. If the canonical append-only history is stored elsewhere (e.g., ROUND-HISTORY or another log), please update the reference; otherwise mark this as a proposed new file path rather than an existing one.

Suggested change
A worktree is a separate working directory. Files that are auto-appended-to every tick (e.g. `docs/hygiene-history/loop-tick-history.md`) will diverge between the worktree and main if the tick runs in the worktree.
**Example of the hazard (this tick almost hit it):** I entered `pr32-markdownlint` worktree on `round-42-speculative`. If I had written to `docs/hygiene-history/loop-tick-history.md` *from within the worktree* instead of *from the main repo*, the entry would have landed on the wrong branch and wrong working-tree copy. Then at tick close, the main repo wouldn't reflect the tick.
**Class-detector:** tick-history appends must happen in the main repo, not inside a worktree. Enforcement options:
1. CLAUDE.md rule: "append tick-history *after* `ExitWorktree`, never before."
2. Pre-commit hook: if a commit modifies `docs/hygiene-history/loop-tick-history.md` AND the branch is not `main`/`round-NN-speculative`, refuse.
3. A helper function `append-tick-history.sh` that `cd`s to main root before writing.
A worktree is a separate working directory. Files that are auto-appended-to every tick (for example, the canonical tick-history log, wherever it lives in the repo) will diverge between the worktree and main if the tick runs in the worktree. If the project later creates `docs/hygiene-history/loop-tick-history.md`, treat that as a proposed path, not a current one.
**Example of the hazard (this tick almost hit it):** I entered `pr32-markdownlint` worktree on `round-42-speculative`. If I had written to the canonical tick-history log *from within the worktree* instead of *from the main repo*, the entry would have landed on the wrong branch and wrong working-tree copy. Then at tick close, the main repo wouldn't reflect the tick.
**Class-detector:** tick-history appends must happen in the main repo, not inside a worktree. Enforcement options:
1. CLAUDE.md rule: "append tick-history *after* `ExitWorktree`, never before."
2. Pre-commit hook: if a commit modifies the canonical tick-history log and the branch is not `main`/`round-NN-speculative`, refuse.
3. A helper function `append-tick-history.sh` that `cd`s to main root before writing to the canonical tick-history log.

Copilot uses AI. Check for mistakes.
Comment on lines +167 to +170
| Hazard | Preventive (structural) | Compensating (detector, permanent) |
|---|---|---|
| Live-lock (§2.1) | Scope-overlap registry + refusal | Merge-front throughput monitor; N-round stale-worktree audit |
| Merge conflicts (§2.2) | Scope discipline (same as §2.1) | Conflict-rate instrumentation; rework count |
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The markdown table in §3 has an extra leading | on each row (e.g., || Hazard | ...), which creates an empty first column in most renderers. Consider removing the extra pipe so the table renders as intended.

Copilot uses AI. Check for mistakes.
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.

2 participants