Summary
Extend Agent Bundle's existing host-neutral hook names and adapter-owned native
translation into filesystem event routes with a broader capability-aware
vocabulary. The compiler maps each semantic event onto the selected host's native event,
matcher, input decoder, synchronous deadline, output envelope, and delivery
capabilities.
Authors write application behavior once. Host adapters own translation.
Problem
Agent Bundle currently normalizes four hook events: sessionStart,
beforeTool, afterTool, and stop. TraceDecay-class applications also need
session completion, prompt submission, subagent start, file saved, workspace
open, compaction, shell completion, test lifecycle, idle, and host-specific
receipts.
Copying JSON hook documents or branching on host names inside handlers does
not scale. Hosts differ in event names, fields, matchers, synchronous response
formats, deadlines, trust prompts, and whether directed feedback is possible.
Filesystem convention
src/events/
session/start.tsx
session/end.tsx
prompt/submit.tsx
agent/start.tsx
tool/before.tsx
tool/after.tsx
file/saved.tsx
workspace/open.tsx
compact/before.tsx
stop.tsx
Each route may export static configuration and an RSC result component:
export const config = {
tools: ['file.write'],
delivery: ['immediate', 'deferred'],
} satisfies AgentEventRouteConfig;
export default async function AfterTool() {
const { event, services } = await agent();
const hint = await services.hints.forEvent(event);
return hint ? <Agent.Context>{hint}</Agent.Context> : null;
}
Canonical event contract
Every event carries bounded metadata, explicit identity provenance, ordering,
an idempotency key, host contract revision, and an AbortSignal. Sensitive or
unbounded native payload fields are excluded unless an application explicitly
declares and validates them.
Host support is a state, not a Boolean:
type HostEventSupport =
| { state: 'supported'; source: 'native' | 'receipt' }
| { state: 'degraded'; reason: string }
| { state: 'unavailable'; reason: string }
| { state: 'prohibited'; reason: string };
The compiler refuses routes that require an unavailable capability unless the
route is explicitly restricted to supported targets.
Projection
The adapter registry owns:
- native event names and matchers;
- input decoding and canonical identity extraction;
- synchronous deadline and payload budgets;
- immediate output encoding (
additionalContext, hook-specific output,
denial, toast, or no response);
- trust/activation requirements;
- event fixtures and provenance.
Application routes never emit host-native JSON directly.
Failure and timing
- Hook processes acknowledge within the host deadline.
- An unavailable provider or backend produces a truthful empty/no-guidance
result, not a fabricated success.
- Slow work is handed to an explicit state/task backend and later delivery
route; a short-lived hook does not silently continue unowned work.
- Duplicate events are idempotent when a state provider is configured.
- Native payloads are size bounded before user code runs.
Non-goals
- Claiming event support from another host's similar payload.
- Built-in hint or collision algorithms.
- A mandatory event database.
- Arbitrary raw native-hook documents as the primary authoring model.
Acceptance criteria
- Unsupported and degraded mappings are visible in inspect output and fail
required routes before packaging.
- Checked-in host-native fixtures prove schema and adapter conformance for every
supported mapping; they are not evidence that a commercial host dispatched
the event.
- The handler receives canonical context and never branches on host JSON.
- Immediate output is rendered through the Agent Document projector.
- The event process never holds open for deferred output. Before the delivery
feature exists, a deferred-delivery request fails with a typed unsupported
outcome rather than pretending work will continue.
- One
tool/after route compiles into two genuinely supported native formats;
a separate file/saved fixture is reported unavailable on targets that do
not expose that event.
Design references
Stack position
Full meta-framework stack
Flight-backed event-route execution
The intended default architecture is a thin native hook client calling the
shared Agent Bundle render runtime, not a generated shell process that loads the
whole application and renderer for every event.
native hook stdin/event
-> host decoder
-> AgentEventProps { canonical, native, provenance, signal }
-> shared runtime render request
-> event route Server Component
-> Flight stream
-> Agent Document decoder/projector
-> native hook stdout/result
canonical contains the cross-host event identity used by application code.
native retains every field the host actually supplied after schema and size
validation, so an application can use host-specific evidence without receiving
fabricated fields. Both are immutable typed props and are also available through
the request context established around the Flight render.
The generated client selects a real transport per host:
- use a native
mcp_tool hook only where the host contract proves it can call
the generated server with the required input, output, cancellation, and
deadline semantics;
- otherwise use compiler-owned local IPC to the host-managed MCP/runtime
process;
- use a standalone in-process wrapper only as an explicit degraded mode when
shared runtime/state is not required.
The MCP/runtime process can amortize application startup and expose
process-lifetime providers or state across hook invocations. This is optional:
event routes that need only their props still work without durable storage, and
routes requiring shared/durable state declare that capability explicitly.
Additional acceptance criteria:
- One real generated hook sends the complete validated native envelope as
typed props through Flight and receives a valid native response before the
host deadline.
- Claude, Codex, and Cursor adapters prove their selected runtime transport or
report it degraded/unavailable; similarly named events are not evidence.
- Two consecutive events can observe the same process-lifetime provider when
the shared runtime is active without reloading the application per hook.
- Runtime absence, restart, timeout, cancellation, and artifact-epoch mismatch
have fail-closed or explicitly configured fallback behavior.
- The public hook protocol never receives raw Flight bytes or non-native output.
Summary
Extend Agent Bundle's existing host-neutral hook names and adapter-owned native
translation into filesystem event routes with a broader capability-aware
vocabulary. The compiler maps each semantic event onto the selected host's native event,
matcher, input decoder, synchronous deadline, output envelope, and delivery
capabilities.
Authors write application behavior once. Host adapters own translation.
Problem
Agent Bundle currently normalizes four hook events:
sessionStart,beforeTool,afterTool, andstop. TraceDecay-class applications also needsession completion, prompt submission, subagent start, file saved, workspace
open, compaction, shell completion, test lifecycle, idle, and host-specific
receipts.
Copying JSON hook documents or branching on host names inside handlers does
not scale. Hosts differ in event names, fields, matchers, synchronous response
formats, deadlines, trust prompts, and whether directed feedback is possible.
Filesystem convention
Each route may export static configuration and an RSC result component:
Canonical event contract
Every event carries bounded metadata, explicit identity provenance, ordering,
an idempotency key, host contract revision, and an
AbortSignal. Sensitive orunbounded native payload fields are excluded unless an application explicitly
declares and validates them.
Host support is a state, not a Boolean:
The compiler refuses routes that require an unavailable capability unless the
route is explicitly restricted to supported targets.
Projection
The adapter registry owns:
additionalContext, hook-specific output,denial, toast, or no response);
Application routes never emit host-native JSON directly.
Failure and timing
result, not a fabricated success.
route; a short-lived hook does not silently continue unowned work.
Non-goals
Acceptance criteria
required routes before packaging.
supported mapping; they are not evidence that a commercial host dispatched
the event.
feature exists, a deferred-delivery request fails with a typed unsupported
outcome rather than pretending work will continue.
tool/afterroute compiles into two genuinely supported native formats;a separate
file/savedfixture is reported unavailable on targets that donot expose that event.
Design references
Stack position
Full meta-framework stack
Flight-backed event-route execution
The intended default architecture is a thin native hook client calling the
shared Agent Bundle render runtime, not a generated shell process that loads the
whole application and renderer for every event.
canonicalcontains the cross-host event identity used by application code.nativeretains every field the host actually supplied after schema and sizevalidation, so an application can use host-specific evidence without receiving
fabricated fields. Both are immutable typed props and are also available through
the request context established around the Flight render.
The generated client selects a real transport per host:
mcp_toolhook only where the host contract proves it can callthe generated server with the required input, output, cancellation, and
deadline semantics;
process;
shared runtime/state is not required.
The MCP/runtime process can amortize application startup and expose
process-lifetime providers or state across hook invocations. This is optional:
event routes that need only their props still work without durable storage, and
routes requiring shared/durable state declare that capability explicitly.
Additional acceptance criteria:
typed props through Flight and receives a valid native response before the
host deadline.
report it degraded/unavailable; similarly named events are not evidence.
the shared runtime is active without reloading the application per hook.
have fail-closed or explicitly configured fallback behavior.