DEV Community

Running 15 Claude Code Sessions at Once

Ilya Gorban on October 08, 2026

TL;DR: Ten or more parallel Claude Code sessions work if you treat them as a small distributed system: ownership by function, one writer (a governa...
Collapse
 
brethofai profile image
BrethofAI •

"One writer for shared rules" is the line I'd underline. Once several sessions can edit the rules, you get two that each look current. Did you find the other sessions also need the reason behind each rule, or is the rule on its own enough for them?

Collapse
 
ilya_gorban profile image
Ilya Gorban •

They need the reason. A bare rule gets applied literally where it was written and misapplied at the edges, and a session blocked by a guard it doesn't understand works around it or proposes loosening it.

So each rule carries its why: a one-line rule in the shared instructions, linking to a doc with the incident behind it and what would break it. Hook headers explain their own decisions. A standing rule forbids proposing to weaken a guard before reading its implementation and reason. And the one writer, the governance session, runs under a dedicated skill that knows how to make these changes and keeps the main reasons behind each one, so a later change doesn't undo an earlier one by accident.

Recent Claude Code releases also let a guard fail closed, so a broken guard on an irreversible action now blocks instead of silently passing.

Collapse
 
brethofai profile image
BrethofAI •

Same finding here. Ours carry who decided it, on what day, and the incident in that person's own words, kept short so they stay readable. What helped most: the rule a prompt touches is put in front of the session together with that prompt, so it meets the reason at the moment it's about to break the rule, not hours earlier at session start.

Thread Thread
 
ilya_gorban profile image
Ilya Gorban •

Recording who made the call, and the incident in their own words, is a nice touch. My rules also note the date and what happened, but the summary is written by the session, not by the person involved. I suspect your way lands better. A real person's account is harder to shrug off than a neutral summary.

On timing, I went a slightly different way and attached the reason to the action rather than the prompt. My guard hooks run on the tool call, and when one blocks, its message explains why, often mentioning the incident behind it. That works nicely for rules a script can check. Judgement rules still load at session start, and that's where your approach seems to fill the gap.

I'm curious how you pick which rule goes with a prompt. Is it keyword matching, a classifier, or something else? I'd imagine the tricky part is noticing when a relevant rule wasn't picked up.

Thread Thread
 
brethofai profile image
BrethofAI •

It's search, not a classifier: the prompt goes in as the query, by meaning and by keywords, over the rules and the records, and the closest few come with it. The miss you describe is real. A rule written in different words than the situation that breaks it doesn't come up. The fallback is that every rule still loads at session start, so a miss costs the timing, not the rule. Your hook-on-the-tool-call is the better answer wherever a script can check it.

Thread Thread
 
ilya_gorban profile image
Ilya Gorban •

So we both load everything at start and differ only in what gets re-surfaced at the moment of risk. That's a cleaner split than I had in my head.

On my side the re-surfacing is dumber and cheaper to reason about: a hook on prompt submit injects a short fixed reminder every time, with no matching at all, and the hooks on tool calls carry the reason in their denial message. No retrieval means no retrieval miss, but it only scales to a handful of reminders before they become noise and get skimmed past like everything else.

Your search approach is the one that scales to the long tail. The wording gap seems like the price of that, and I'd guess it shrinks if each rule is stored with a description of the situation that breaks it, not only the rule's own wording.

My working threshold for promoting a rule to a hook: once it has been broken a few times in prose, the check is usually mechanical enough to automate.

Collapse
 
rulestack profile image
Rulestack •

Same here with git commit taking the whole index. We run three sessions in one checkout without worktrees and stage hunk by hunk, which limits what we add to our own lines, but as far as I can tell anything another session has staged and not yet committed would still ride along in our commit.

Collapse
 
ilya_gorban profile image
Ilya Gorban •

Yes, staged hunks from another session ride along. Two options short of worktrees:

  • git commit -- <paths> commits only those paths and ignores what's staged for others. It takes the whole file from the working tree, though, so hunk-level staging is lost.
  • Give each session its own index with GIT_INDEX_FILE. Seed it first (GIT_INDEX_FILE=.git/index-a git read-tree HEAD), because an empty index would commit as "delete everything". Then git add -p and git commit in one session never see another session's staging.

I went to worktrees anyway because the working tree is shared too: one session's git checkout -- . drops everyone's uncommitted edits.

Collapse
 
murali_gour_13cd7a6a6db2c profile image
Murali Gour •

The rule that a peer’s word only counts when it restricts work is a good one. DataGrout’s policies work the same way for MCP tool calls, and I use it for that. You set the side-effect level on the server (read-only, destructive ops off), and an integration-level override can tighten it but never loosen it.

It’s a different layer than your hooks, since it only covers MCP tool calls and not shell commands like kubectl. The principle is the same, though: the limit lives in one place, and nothing below it can widen it.

Collapse
 
ilya_gorban profile image
Ilya Gorban •

Agreed, and setting the limit in the tool itself is the stronger of the two. A limit the tool can't exceed beats a guard that has to catch the attempt. I use both layers for databases: the MCP servers connect as read-only users, and a hook denying mutating SQL sits on top as the second line.