The `issue.comment.created` handler read `payload.issueId`, which the current
Paperclip host never sends — the issue id arrives in `event.entityId` and the
payload carries `commentId`/`bodySnippet`/`reopened` instead. So the handler
hit "missing issueId, skipping" on every user comment and the documented
"user comment → CEO" routing was silently dead.
Diagnosed on case 8124-09-24 (CMPA): a question commented on an analyst's
`done` sub-issue never reached the CEO. The plugin skipped; Paperclip's native
reopen-on-comment wake then targeted the sub-issue's assignee (the analyst) and
the queued CEO run was cancelled with `issue_assignee_changed`.
Fix:
- issueId from `event.entityId` (fallback `payload.issueId` for host-version skew).
- Resolve full comment body by matching `payload.commentId` in listComments
(payload only has a truncated `bodySnippet`); fall back to latest/snippet.
- Dedup guard: when the comment reopened an issue ALREADY assigned to the CEO,
the host's native wake covers it — skip to avoid double-running the CEO.
For issues owned by any other agent we still route to the CEO.
Invariants: upholds the "user comment routes through CEO" contract (CLAUDE.md);
touches only the platform-port shell (plugin), per G12/X15. No new parallel path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>