Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Parallel Sessions

ASecurity

How to keep several agent threads from colliding when each one starts a long-running process such as a dev server, a database, an emulator, or a browser profile. Covers the triage for "am I looking at my own output", the mechanism for giving every checkout its own ports and its own names, and the Windows path limit that makes worktrees undeletable.

9 stars
0 votes
0 copies
0 views
Added 9/21/2026
ai-agentspythonshellnodegitdatabase

Works with

terminal

Security Analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned 9/21/2026

$npx -y skills add Ethanon/developer.ai --skill parallel-sessions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Parallel Sessions?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Parallel Sessions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ethanon-parallel-sessions/badge)](https://www.skillsdirectory.com/skills/ethanon-parallel-sessions)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: parallel-sessions
description: How to keep several agent threads from colliding when each one starts a long-running process such as a dev server, a database, an emulator, or a browser profile. Covers the triage for "am I looking at my own output", the mechanism for giving every checkout its own ports and its own names, and the Windows path limit that makes worktrees undeletable.
source: https://github.com/Ethanon/developer.ai
license: MIT
---

# Parallel Sessions

`PR_WORKFLOW.md` puts every thread in its own worktree. That stops threads overwriting each other's *files*. It does not stop them overwriting each other's *processes*. The moment a thread starts a dev server, a database, an emulator, or a headless browser, it competes for a fixed port and a fixed name with every other thread on the machine.

That collision is worse than the file one, because it does not fail. The second bind loses, the first process keeps answering, and the losing thread reads another branch's output as its own. What that looks like in practice is a green test run against code that was never loaded, or a screenshot of a screen that does not exist in your source.

## Triage: am I looking at my own output?

Run these before believing a screenshot, a log line, or a bug report. They are in rough order of how often each turns out to be the answer.

1. **Ask what this checkout thinks it owns.** Use whatever your project has for reporting its own state, or read the file the port was written to. If it names the default port and you are in a worktree, the tooling does not know you are in one. Skip to item 4.
2. **Ask the running process which branch it is serving.** Request something only your branch has: a symbol in a bundle, a route that does not exist on the default branch, a version string. Something answering on the port is not the same as *your* thing answering.
3. **Ask the machine who else is up.** List the processes or devices and check how many are candidates. A second one belonging to another thread is normal. A second one on *your* name is not.
4. **Check the worktree is somewhere the tooling recognises.** This is the silent one. When identity is derived from the directory path, and it should be, a worktree placed outside the recognised directories resolves to the *main checkout's* identity and shares its ports with whoever else is there.

Design against that fourth case explicitly, because it is invisible from inside the session. Git already knows the answer. A worktree's `.git` is a *file* naming the real git directory, while a checkout's `.git` is a *directory*. When git says worktree and your path convention says otherwise, print that in the status output rather than leaving it to be discovered.

## The mechanism

Derive identity from the checkout's own directory. Do not keep a registry of which thread holds which port. A registry has to be cleaned up when a session dies, and sessions die.

**Give every checkout a slot, and move all of its ports together.** If a project serves on 3000, 5432 and 8080, then slot 1 serves on 3100, 5532 and 8180. One offset is applied to every port at once, so a checkout's ports share a prefix and a human reading `5532` knows whose it is.

Moving them together matters because independent scans overlap. Give each service its own range and the ranges collide with each other. A port that one service has claimed but not yet bound reads as free to the next service's scan, so a checkout can double-book itself. A single offset makes that arithmetically impossible.

**Take a slot by creating a file exclusively, not by checking and then writing.** This is the part that is easy to get wrong and hard to notice:

```
probe the ports        ← both threads see them free
write the claim        ← both threads write
```

Two threads starting in the same millisecond both pass the probe. The window is small, and it is exactly the case the scheme exists for. Use an exclusive create on a per-slot file in the shared repository root: `O_EXCL`, which is `{ flag: 'wx' }` in Node and `open(..., 'x')` in Python. Only one creator can win. The create has to happen *before* the first `await` in the claim path, not after it.

Then keep three rules straight.

- **A slot you already hold is kept, whatever is listening on it.** Your own server answering on your own port is the normal case. Re-probing liveness and reading a busy port as proof the slot was lost will push a session off its own ports mid-run.
- **A slot you are newly taking has to be clear of everything**, including processes that have nothing to do with your project.
- **A slot whose owner is no longer on disk is free.** That owner is a removed worktree. This is how the register cleans itself up without anybody sweeping it.

**Probe by connecting, not by binding.** On Windows, `SO_REUSEADDR` is the default, so a second bind to a port another process is already listening on *succeeds*. A refused connection is the only answer that means nobody is home. Treat a timeout as occupied rather than free.

**Name every other shared resource the same way.** Anything else a thread starts and could collide on gets the checkout's name appended: an emulator or VM image, a container, a database, a browser profile directory. A teardown command can then stop what *this* checkout started and leave the rest alone, which is what makes it safe to run at all.

`workspace.mjs` in this directory implements all of the above in about 170 lines with no dependencies. Port the shape rather than the file.

## Recognise a worktree whichever tool made it

Different AI tools put worktrees in different places: `.claude/worktrees/`, `.codex/worktrees/`, or a plain `.worktrees/`. If your identity function matches only the directory your primary tool uses, every worktree made by a second tool reads as the main checkout. Same ports, same emulator, same database, no warning. Match all of them, and add new spellings as tools appear.

The same asymmetry bites dependency linking. An agent harness that links dependencies into worktrees it creates does nothing for worktrees a different tool created, because that tool never read the first tool's configuration. Put the link in the package manager's pre-install step, where it runs regardless of who made the directory.

## Windows: the 260-character limit

Two switches, both needed, both idempotent. Setup should assert them rather than a document describing them.

| Switch | Scope | Privilege | Covers |
|---|---|---|---|
| `git config core.longpaths true` | one repository | none | git's own operations: `worktree remove`, `clean`, `checkout` |
| `LongPathsEnabled=1` under `HKLM\SYSTEM\CurrentControlSet\Control\FileSystem` | the machine | administrator | everything else: package managers, build tools, your own scripts |

Setting only the first leaves your package manager failing on paths git now handles, which reads as a broken install rather than a path limit.

**Prompt for the elevation only when a human is at the terminal.** Check for a TTY, and report the one-line fix otherwise. A UAC dialog raised inside an agent's shell is a command that never returns.

The failure all of this prevents: a worktree that installed its own dependency tree sits at a path deep enough that Windows will not delete it. `git worktree remove` then fails with `Filename too long` after it has already unregistered the worktree, and the directory stays until somebody finds the incantation.

## What this does not replace

The rule that every thread starts in a worktree belongs in your always-loaded steering document, not in this skill. A skill loads when its description matches the task at hand, and the case that breaks that is a session which begins as a question and ends as a change. Most sessions do. Keep the invariant always-on, and use this skill for the mechanism and the triage behind it.

Attribution

EthanonEthanon
View sourceSee grades on GitHubMore from Ethanon →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698621 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →