Skip to content

chore(hooks): re-sync vendored session hooks to attune-ai canonical#68

Merged
silversurfer562 merged 1 commit into
mainfrom
chore/claude-session-hooks
Jun 17, 2026
Merged

chore(hooks): re-sync vendored session hooks to attune-ai canonical#68
silversurfer562 merged 1 commit into
mainfrom
chore/claude-session-hooks

Conversation

@silversurfer562

Copy link
Copy Markdown
Member

What

Re-sync attune-author's vendored Claude Code session hooks to current attune-ai canonical. The closure grows 7 → 8 files (adds _sdk_gate.py).

The hooks vendored at P2 (#59) predate the sdk-subprocess-isolation fix. Each portable hook now calls _sdk_gate.exit_if_sdk_subprocess() first in __main__: an SDK-spawned claude subprocess is not an interactive session, and SessionStart hook stdout poisons the Agent SDK's stream-json channel — the failure that broke every SDK workflow for subscription users. Without this, attune-author's hooks carry that bug.

Changes

  • Re-vendor all 8 hooks byte-identical from attune-ai/plugin/hooks/ (verified 8/8)
  • _sdk_gate.py added to the closure, Makefile HOOK_FILES, and .canonical-sha256 (now 8 entries)
  • Behavior-test harness neutralizes ATTUNE_SDK_SUBPROCESS / CLAUDE_CODE_ENTRYPOINT so security_guard exercises its blocking path regardless of the runner env (the hooks now self-gate on those markers)
  • _sdk_gate.py is stdlib-only (os, sys) — closure stays stdlib-only at the boundary

Verification

  • tests/test_claude_hooks_drift.py + tests/test_claude_hooks_behavior.py: 17 passed
  • ruff check .claude/hooks/ tests/: clean (no reformat → byte-identity preserved)
  • .gitattributes LF pin already covers .claude/hooks/*.py (no change needed)

Context

Part of specs/sibling-claude-hooks (attune umbrella workspace). This is a canonical-drift re-sync discovered while reconciling spec status: P0 (#500) and P2 (#59) are both merged but the spec still marked them pending. attune-rag (#151) carries the same drift and needs the same re-sync (separate follow-up). P3 (attune-help) / P4 (attune-gui) remain and should vendor this 8-file canonical.

🤖 Generated with Claude Code

Bring attune-author's vendored Claude Code session hooks up to current
attune-ai canonical (closure grew 7 -> 8 files). The key change is the
new _sdk_gate.py helper and its exit_if_sdk_subprocess() call at the top
of each portable hook's __main__: an SDK-spawned `claude` subprocess is
not an interactive session, and SessionStart hook stdout poisons the
Agent SDK's stream-json channel (the failure that broke SDK workflows for
subscription users). The hooks vendored at P2 (#59) predate this fix.

- Re-vendor all 8 hooks byte-identical from attune-ai/plugin/hooks
- Add _sdk_gate.py to the closure + Makefile HOOK_FILES + .canonical-sha256
- Neutralize SDK markers in the behavior-test harness so security_guard
  exercises its blocking path regardless of the runner's environment

Refs specs/sibling-claude-hooks (canonical-drift re-sync follow-up).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant