Repository navigation
Compile semantic event route v2 families into native host hooks #258
Description
Summary
Follow-on tracker for the canonical event-route families promoted in the #97 documentation audit (#97 comment) after v1 landed. v1 delivered the four existing hook families plus agent/start/agent/stop, with workspace/open honestly unavailable on every pinned host (#221).
Each family below needs the same evidence bar v1 used: pinned per-host wire schema or official contract, decode fixture, matcher/deadline semantics, immediate-output projection through the Agent Document renderer, and an honest supported/degraded/unavailable/prohibited row in inspect — not inference from similarly named events.
Promote to canonical route families
-
session/end— Claude, Codex, Cursor -
prompt/submit— ClaudeUserPromptSubmit, CodexUserPromptSubmit, CursorbeforeSubmitPrompt -
tool/failure— ClaudePostToolUseFailure, CursorpostToolUseFailure; Codex unavailable at the release-documented surface -
compact/before— Claude/CodexPreCompact, CursorpreCompact -
compact/after— Claude/CodexPostCompact; Cursor unavailable -
permission/request— Claude/CodexPermissionRequest; do not infer Cursor support from pre-tool permission -
permission/denied— ClaudePermissionDenied; other hosts unavailable until evidenced -
file/change(proposedfile/saved) — ClaudeFileChanged, CursorafterFileEdit; payload/matcher differences must stay visible -
config/change— ClaudeConfigChange; other hosts unavailable -
task/create,task/complete,agent/idle— ClaudeTaskCreated,TaskCompleted,TeammateIdle; host-specific today -
stop/failure— ClaudeStopFailure; other hosts unavailable
Keep as selectors/native variants (not new families unless fixture evidence proves loss)
Cursor beforeShellExecution/afterShellExecution, beforeMCPExecution/afterMCPExecution, beforeReadFile, and afterFileEdit overlap canonical tool-before/tool-after plus tool selectors. Add dedicated families only if fixture evidence proves the generic tool route loses required information or control.
Explicitly defer/unavailable in capability tables
- Claude-only host/UI/protocol callbacks:
Setup,UserPromptExpansion,PostToolBatch,MessageDisplay,InstructionsLoaded,CwdChanged,DirectoryAdded,PreModelSwitch,PostModelSwitch,Elicitation,ElicitationResult,WorktreeCreate,WorktreeRemove. - Claude
Notificationbelongs to Add recipient-aware notices and capability-gated delivery #99 delivery-channel evidence, not an application event route. - Cursor
afterAgentResponse,afterAgentThought,beforeTabFileRead,afterTabFileEditstay native/deferred until a canonical consumer is accepted. - Codex generated
Interruptstays deferred until release docs and a pinned CLI revision agree. - Cloud/desktop availability differences are capability dimensions, not universal-support claims.
For every deferred item, add a dated unavailable/prohibited row with the native name and reason.
Depends on
- v1 event infrastructure: feat(events): define v1 semantic route descriptors #170, feat(events): publish host family capability states #173, feat(events): render native hooks through warm runtime #180, feat(examples): adopt semantic event route #182, fix(events): correct Claude and Codex subagent hooks #194, fix(cursor): honest workspace/open, real marketplace, three-host composite intersection #221
- Agent Document renderer + warm runtime: Build a real RSC Agent Document renderer with streaming semantics #96 (feat(runtime): MCP progress projector and warm-runtime proofs (#96) #175)
- Stack plan: meta-framework: execution plan and sequencing #107 G10 family expansion rule
Non-goals
- Re-litigating v1 four-event parity or the corrected
agent/start/agent/stopmatrix - Claiming
workspace/opensupport without a sessionless native-envelope fixture
Activity
Merge pull request #351 from ScriptedAlchemy/feat/258-events-s1
ScriptedAlchemy commentedon Sep 3, 2026
v2 wave — group 1 landed:
session/end+prompt/submit(#351, merge 9b165ba)Both families are canonical event routes compiled into native host hooks, with the G10 evidence bar:
session/endprompt/submitSessionEnd, observe-only (docs: no decision control, JSON output discarded) — live capture pinnedUserPromptSubmit, deny (decision:block+reason) +additionalContext; no prompt-rewrite channel — live capture pinnedSessionEnd, observe-only (rust-v0.147.0 hassession-end.command.input.schema.jsonand no output schema; byte-pinned) — live capture pinnedUserPromptSubmitper byte-pinned input+output schemas (block + additionalContext;reasonconst-checked) — live capture pinnedsessionEnd, observe-only; cloud honestly unavailable (docs: no editor-lifetime session boundary) recorded as an availability dimensionbeforeSubmitPrompt, deny only (continue:false+user_message); no context channel — projection fails closed on contextBoth families are route-only: they ship in a separate
eventRouteOnlyHookEventsvocabulary, so no newconfig.hooks.*handler keys were added. Cursor live capture was blocked by missing authentication in the capture environment (dated evidence bullet records this); the pinned official contract is the evidence source there. Scrubbed native fixtures for Claude/Codex are checked in and replay through the #279 lifecycle machinery.Next groups staged:
tool/failure+compact/before+compact/after, then permissions +stop/failure, thenfile/change/config/change/task/*/agent/idle+ the deferral rows.feat(events): promote tool/failure and compact route families (#258 v…
ScriptedAlchemy commentedon Sep 3, 2026
Stage 2 landed in #357 (merge 2119cee):
tool/failure,compact/before, andcompact/afterpromoted with per-host fixtures, projection semantics, and dated capability evidence (Codex tool/failure and Cursor compact/after honestly unavailable; live cursor-agent capture could not authenticate, so the pinned official contract is the recorded evidence source for the Cursor rows).Stage 1 (#351) covered
session/end+prompt/submit. Remaining checklist:permission/request,permission/denied,stop/failure,file/change,config/change,task/create/task/complete/agent/idle, plus the dated deferral rows for the explicitly-deferred native callbacks.feat(events): promote permission and stop-failure route families (#258 …
feat(events): promote permission and stop-failure route families (#258 …
ScriptedAlchemy commentedon Sep 3, 2026
Stage 3 landed in #358 (merge 8c541ad):
permission/request(Claude + Codex via the pinned rust-v0.147.0 PermissionRequest contract, allow/deny decisions, reserved rewrite fails closed),permission/deniedandstop/failure(Claude observation-only; retry signalling deliberately unprojected pending canonical vocabulary). Remaining checklist:file/change,config/change,task/create/task/complete/agent/idle, plus the dated deferral rows for the explicitly-deferred callbacks.feat(events): promote lifecycle observation families (#258 v2 s4)
feat(events): promote lifecycle observation families (#258 v2 s4)
ScriptedAlchemy commentedon Sep 3, 2026
Stage 4 landed in #359:
file/change,config/change,task/create,task/complete, andagent/idlepromoted as Claude-only families with their documented decision channels (block decisions for config/task-create, continue:false for agent/idle, fail-closed observation-only for file/change and task/complete whose upstream control is side-effect/exit-code-only). Codex/Cursor/portable carry dated unavailable rows; Cursor afterFileEdit recorded as a tool/after selector variant per the selector rule. Remaining on this tracker: the dated deferral rows for the explicitly-deferred native callbacks (Setup, UserPromptExpansion, PostToolBatch, MessageDisplay, InstructionsLoaded, CwdChanged, DirectoryAdded, Pre/PostModelSwitch, Elicitation(Result), WorktreeCreate/Remove, Cursor tab/thought natives, Codex Interrupt) — these are native events with no canonical family, so they need a home in the capability tables (e.g. a deferredNativeEvents section) rather than eventRoutes rows.feat(events): promote lifecycle observation families (#258 v2 s4) (#359)
feat(events): record dated deferral rows for deferred native callbacks (
feat(events): record dated deferral rows for deferred native callbacks (
ScriptedAlchemy commentedon Sep 3, 2026
Full tracker scope delivered across five merged PRs:
session/end,prompt/submittool/failure,compact/before,compact/afterpermission/request(Claude + Codex via the byte-pinned rust-v0.147.0 PermissionRequest contract),permission/denied,stop/failurefile/change,config/change,task/create,task/complete,agent/idlewith their documented decision channels (block decisions, continue:false for TeammateIdle, fail-closed observation-only where upstream control is side-effect or exit-code-only)deferredNativeEventsrows for every explicitly deferred callback (Claude host/UI/protocol callbacks incl. Notification → Add recipient-aware notices and capability-gated delivery #99 and the policy_settings blocking exception; Cursor tab/thought and tool-selector natives per the selector rule; Codex Interrupt), enforced by a pin testEvery family met the v1 evidence bar: pinned per-host wire contract or dated official-doc citation, decode fixtures, projection through the Agent Document renderer with fail-closed semantics, honest per-host
supported/unavailablerows (no inference from similarly named events), and lifecycle-replay starters. The selector rule was honored — no dedicated families were added for Cursor's tool-overlapping natives without loss evidence.feat(notices): #99 stage-4 delivery substrate (runtime half) (#361)