@@ -2550,7 +2550,19 @@ ok = ok and owned_total == 2
25502550sys.exit(0 if ok else 1)
25512551" 2> /dev/null ||
25522552 ! grep -q ' SessionStart' " $FAKE_HOME /.claude/settings.json" 2> /dev/null ||
2553- ! grep -q ' cbm-code-discovery-gate' " $FAKE_HOME /.claude/settings.json" 2> /dev/null; then
2553+ ! cat " $FAKE_HOME /.claude/settings.json" 2> /dev/null | SELF_PATH=" $SELF_PATH " python3 -c "
2554+ # Claude's gate is registered shell-free (#1733): the binary itself as the
2555+ # command with 'hook-augment' as its argument, so no shim name can be grepped.
2556+ import json, os, sys
2557+ d = json.load(sys.stdin)
2558+ self_path = os.environ['SELF_PATH']
2559+ hooks = [h for entry in d.get('hooks', {}).get('PreToolUse', []) for h in entry.get('hooks', [])]
2560+ ok = any(h.get('args') == ['hook-augment'] and
2561+ (h.get('command') == self_path or
2562+ os.path.basename(str(h.get('command', ''))) == os.path.basename(self_path))
2563+ for h in hooks)
2564+ sys.exit(0 if ok else 1)
2565+ " 2> /dev/null; then
25542566 echo " FAIL 8aq: Devin hooks are not deduplicated against Claude SessionStart"
25552567 exit 1
25562568else
@@ -2755,9 +2767,14 @@ if cat "$FAKE_HOME/.claude/settings.json" 2>/dev/null | python3 -c "
27552767import json, sys
27562768d = json.load(sys.stdin)
27572769hooks = d.get('hooks', {})
2770+ # Shim names cover legacy shell registrations; the exec form (#1733) carries
2771+ # no shim name, so its 'hook-augment' argument is the owned marker there.
27582772found = any('cbm-code-discovery-gate' in str(h) or
27592773 'cbm-session-reminder' in str(h) or
2760- 'cbm-subagent-reminder' in str(h)
2774+ 'cbm-subagent-reminder' in str(h) or
2775+ any('hook-augment' in str(x.get('args', [])) or
2776+ 'hook-augment' in str(x.get('command', ''))
2777+ for x in h.get('hooks', []))
27612778 for entries in hooks.values() for h in entries)
27622779sys.exit(1 if found else 0)
27632780" 2> /dev/null; then
0 commit comments