diff --git a/CHANGELOG.md b/CHANGELOG.md
index d54e9830..f201dfaf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ This release adds the reverse of `/codex`: external hosts can now ask Claude for
- `hosts/claude.ts`: excludes the Claude outside-voice skill from Claude-host generation.
- `test/brain-sync.test.ts`: the `GSTACK_HOME` isolation test now snapshots and preserves the real config file instead of assuming local machine state.
- `model-overlays/opus-4-7.md`: restores the fanout nudge expected by the Opus overlay regression test.
+- `claude/SKILL.md.tmpl`: uses `mktemp` for diff capture in review/challenge mode instead of a `$$`-based temp path, avoiding collisions across concurrent invocations.
### Changed
diff --git a/claude/SKILL.md.tmpl b/claude/SKILL.md.tmpl
index 3944807d..94552cbe 100644
--- a/claude/SKILL.md.tmpl
+++ b/claude/SKILL.md.tmpl
@@ -151,8 +151,9 @@ Review the current branch diff with nested Claude in tool-less mode.
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
cd "$_REPO_ROOT"
+DIFF_FILE=$(mktemp /tmp/gstack-claude-diff-XXXXXX.patch)
git fetch origin --quiet 2>/dev/null || true
-git diff "origin/" > /tmp/gstack-claude-diff-$$.patch 2>/dev/null || git diff "" > /tmp/gstack-claude-diff-$$.patch
+git diff "origin/" > "$DIFF_FILE" 2>/dev/null || git diff "" > "$DIFF_FILE"
```
If the diff file is empty, stop and say:
@@ -171,7 +172,7 @@ Additional user instructions, if any:
DIFF:
EOF
-cat /tmp/gstack-claude-diff-$$.patch >> "$PROMPT_FILE"
+cat "$DIFF_FILE" >> "$PROMPT_FILE"
```
3. Run Claude:
@@ -192,7 +193,7 @@ CLAUDE SAYS (code review):
5. Cleanup:
```bash
-rm -f /tmp/gstack-claude-diff-$$.patch "$PROMPT_FILE" "$RESP_FILE" "$ERR_FILE"
+rm -f "$DIFF_FILE" "$PROMPT_FILE" "$RESP_FILE" "$ERR_FILE"
```
---
@@ -217,7 +218,7 @@ Focus area, if any:
DIFF:
EOF
-cat /tmp/gstack-claude-diff-$$.patch >> "$PROMPT_FILE"
+cat "$DIFF_FILE" >> "$PROMPT_FILE"
```
3. Run Claude:
@@ -238,7 +239,7 @@ CLAUDE SAYS (adversarial challenge):
5. Cleanup:
```bash
-rm -f /tmp/gstack-claude-diff-$$.patch "$PROMPT_FILE" "$RESP_FILE" "$ERR_FILE"
+rm -f "$DIFF_FILE" "$PROMPT_FILE" "$RESP_FILE" "$ERR_FILE"
```
---
diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts
index f6c541cc..726a5115 100644
--- a/test/gen-skill-docs.test.ts
+++ b/test/gen-skill-docs.test.ts
@@ -1615,6 +1615,8 @@ describe('Codex generation (--host codex)', () => {
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gstack-claude', 'SKILL.md'), 'utf-8');
expect(content).toContain('claude -p');
expect(content).toContain('mktemp /tmp/gstack-claude-prompt-');
+ expect(content).toContain('mktemp /tmp/gstack-claude-diff-');
+ expect(content).not.toContain('/tmp/gstack-claude-diff-$$');
expect(content).toContain('cat "$PROMPT_FILE" | claude -p');
expect(content).toContain('--disable-slash-commands');
expect(content).toContain('--tools ""');