feat: channel seam hooks for premium coordination gating (#553)#668
feat: channel seam hooks for premium coordination gating (#553)#668laynepenney merged 2 commits intosprint-18from
Conversation
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add register_message_hook() to channel.py so premium can wire in @mention storage and wake emission without coupling into the OSS substrate. Default hooks auto-register for backward compatibility. Gate coordination action handlers (directive, claim, board, mute, kick, broadcast) behind premium in the action registry. Without the premium plugin installed, these actions show as "locked" and return upgrade messages. Premium registers them via register_coordination_handlers(). 228 channel tests pass (192 existing + 11 hook + 25 registry). Premium boundary: core OSS (channel substrate + action registry seam). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
All contributors have signed the CLA. Thank you! |
laynepenney
left a comment
There was a problem hiding this comment.
Opus review (1/2): Hook mechanism
Clean extraction. The hook pattern in _append_message is the right abstraction: OSS fires hooks after write, premium can replace or extend them via _clear_message_hooks() + register_message_hook(). Exception safety (bare except + pass) is appropriate for best-effort hooks.
One nit: from typing import Callable at line ~135 inside the file body rather than at top with other imports. Not blocking but worth noting for consistency.
Default hooks auto-registering at module load time maintains backward compatibility. LGTM.
laynepenney
left a comment
There was a problem hiding this comment.
Opus review (2/2): Gating + boundary
The coordination action gating is well-structured: without premium, directive/claim/board/etc. return "requires premium" instead of silently failing. register_coordination_handlers() is the public API premium calls to unlock them.
Tests are thorough: 11 hook tests + 5 registry gating tests cover the critical paths. The tearDown/setUp pattern properly resets global state between tests.
Premium boundary: OSS (channel substrate + action registry seam). Correct.
LGTM. Ready for merge after Layne's review.
laynepenney
left a comment
There was a problem hiding this comment.
Sentinel self-review (1/2) -- channel hook seam.
Design decisions:
- Hooks are a list (not a single callback) so premium can add multiple hooks or replace them
- Default hooks auto-register at module load for backward compatibility
- _clear_message_hooks() exposed for tests and for premium to reset before registering its own
- Hooks are best-effort (exceptions caught) so a broken hook never prevents message delivery
- _set_dirty_flags stays in _append_message (not a hook) because it's OSS unread infrastructure
Test coverage: 11 hook tests + 5 registry gating tests + 192 existing channel tests = 228 total.
|
Sentinel self-review (2/2) -- sprint checklist.
Depends on: nothing (standalone OSS change) |
|
Review pass: no new blocking issue from this slice. The OSS hook seam and action-registry gating line up with the current Sprint 18 boundary: substrate + registry seam stay OSS; coordination handlers stay on the premium side. My earlier packaging concern was on the provider seam PRs, not this channel split slice. |
|
Follow-up on CI state: the matrix is currently red on an unrelated existing test failure in Tracker: recall#669 |
|
I have read the CLA Document and I hereby sign the CLA |
|
recheck |
1 similar comment
|
recheck |
Summary
register_message_hook()to channel.py — premium coordination layer can wire in @mention storage and wake emission without coupling into the OSS substratePremium boundary: core OSS (channel substrate + action registry seam).
Paired with premium PR for the coordination plugin module.
Test plan
🤖 Generated with Claude Code