Show HN: Stop parallel AI coding sessions clobbering each other's handoffs

nahsuhn1 pts0 comments

GitHub - joshduffy/claude-handoff-guard: Hook-enforced ownership for AI coding session handoffs · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

joshduffy

claude-handoff-guard

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

master

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>2 Commits<br>2 Commits

hooks

hooks

rules

rules

scripts

scripts

skills/handoff

skills/handoff

.gitignore

.gitignore

LICENSE

LICENSE

README.md

README.md

package.json

package.json

settings.example.json

settings.example.json

View all files

Repository files navigation

claude-handoff-guard

Hook-enforced ownership for AI coding session handoffs.

Most "handoff" tools solve amnesia: capture state to a markdown file, restore it after compaction<br>or a new session. That problem is well covered. This one solves the problem nobody enforces:<br>concurrent clobber . When two sessions work the same repo, or you resume on a second machine, or a<br>background agent runs alongside an interactive one, they overwrite each other's handoff notes and you<br>do not find out until the context you needed is gone.

The fix here is not a better template. It is a PreToolUse hook that makes a cross-session overwrite<br>structurally blocked, not merely discouraged.

The core idea: the lock lives inside the file

Every handoff file's first line is an ownership marker:

">

There is no sidecar .lock file. Ownership travels with the artifact through git, across devices,<br>through a mv. A PreToolUse hook reads the calling session's id and compares it to the marker in the<br>content being written and the marker already on disk. Mismatch blocks the write.

The chicken-and-egg (the interesting part)

To write a handoff that says who wrote it, the session needs to know its own id. It does not. The<br>model has no native access to its session_id.

So the first write of a fresh handoff is designed to fail. The block reason carries the id:

Then retry.">Handoff write missing or wrong ownership marker.

Your session_id: `9e0d3802-4f...`.

Prepend exactly this as line 1:

Then retry.

The model copies the id from the failure and retries. One block per fresh handoff, and the file is<br>now self-identifying for every future session. The missing capability becomes a one-time handshake.

Defense across all three mutation surfaces

A model that is blocked on Write will route around you. So the guard covers every way a file can be<br>mutated:

Write validates the marker in the new content.

Edit validates the marker on disk (and blocks edits to legacy marker-less files until you take<br>ownership with a Write).

Bash matches shell redirects to handoff paths (>, >>, tee, sed -i) and blocks unowned<br>writes that try to sneak past the file tools.

It also accepts both the Claude Code tool schema (Write/Edit/Bash) and the Gemini CLI schema<br>(write_file/replace/run_shell_command) in one hook, because gating on one silently disables the<br>guard for the other client.

What ships

hooks/handoff-write-guard.mjs PreToolUse: the ownership guard<br>hooks/handoff-session-start.mjs SessionStart: surface existing handoffs + slug overlaps<br>hooks/handoff-stop-gate.mjs Stop: once-per-session "you have no handoff" nudge<br>hooks/pre-commit-staged-marker-check.mjs git pre-commit: block commits mixing two sessions' handoffs<br>hooks/test/handoff-write-guard.test.mjs node --test suite (8 cases)<br>scripts/handoff-migrate-archive.mjs archive stale, marker-less legacy handoffs<br>scripts/install-git-hooks.sh per-device installer for the pre-commit hook<br>skills/handoff/SKILL.md the /handoff slash command<br>rules/session-handoff.md the convention the hooks enforce<br>settings.example.json hook wiring to merge into ~/.claude/settings.json

Handoffs are expected under the standard Claude Code memory layout:<br>~/.claude/projects//memory/handoff--.md, where is the<br>absolute working directory with /, \, and . replaced by -.

Install

# 1. Copy hooks/skills/rules into your ~/.claude<br>cp hooks/*.mjs ~/.claude/hooks/<br>cp -r hooks/test ~/.claude/hooks/<br>cp scripts/* ~/.claude/scripts/<br>cp -r skills/handoff...

handoff hooks session claude write marker

Related Articles