Skip to main content

Module protocol

Module protocol 

Source
Expand description

Hook-protocol payload rendering for harness adapters.

Lifeloop owns the translation from neutral lifecycle inputs (event kind, adapter identity, integration mode, frame context, opaque payload envelopes, placement classes, frame-admission directives) into the adapter-shaped JSON the harness’s hook protocol consumes on stdout.

§Boundary (issue #3)

This module owns:

  • mapping a LifecycleEventKind plus an adapter id to the harness’s own hook event name (e.g. Claude’s SessionStart, Codex’s UserPromptSubmit),
  • rendering the per-event JSON payload with optional contextual payloads and frame-admission directives,
  • the neutral FrameAdmissionDirective vocabulary that lets a client tell a harness “block the next input” or “request a continuation” without naming any client-specific session policy.

This module does not own:

  • the meaning of those directives (a client decides when to block, when to allow);
  • memory, recall, promotion, compaction, or any other client continuity vocabulary;
  • receipt emission (callers wrap the rendered payload in their own receipt flow);
  • filesystem IO, hook registration, or asset installation (issue #4 host_assets owns that),
  • adapter manifest negotiation (issue #6).

§Compatibility labels

Hook event names like "SessionStart", "UserPromptSubmit", "PreCompact", "Stop", "SessionEnd" are harness-defined wire tokens, not Lifeloop semantics. They appear here only because the harness’s hook protocol contract requires them as the hookSpecificOutput.hookEventName value. They are documented here analogously to the CCD_COMPAT_* pattern in crate::host_assets: external-vocabulary tokens grouped in one auditable place.

§Format-agnostic rendering

The payload body is produced as serde_json::Value because the current harness hook protocols (Claude Code, Codex) consume JSON on stdout. The renderer entry point also exposes a string form (RenderedHookPayload::body_string) for direct stdout emission.

Structs§

ProtocolPayload
One opaque contextual payload to render into the harness’s per-event payload slot (e.g. Claude’s additionalContext).
RenderRequest
Inputs for a hook-protocol render.
RenderedHookPayload
A rendered harness hook-protocol payload, ready to be emitted on the harness’s hook stdout.

Enums§

ClaudeHookEvent
The set of Claude hook event tokens this renderer can emit.
CodexHookEvent
Codex hook event tokens this renderer can emit.
FrameAdmissionDirective
Neutral directive a client can attach to a render request to ask the harness to admit, block, or request continuation of the next lifecycle moment.
ProtocolAdapter
Adapter targeted by a render. Renderer dispatch is keyed on this.
RenderError
Why a hook-protocol render failed.

Functions§

claude_hook_event_for
Map a neutral LifecycleEventKind to the Claude hook event the adapter surfaces for it. Returns None for events Claude’s hook protocol does not expose (e.g. supervisor.tick).
codex_hook_event_for
Map a neutral LifecycleEventKind to the Codex hook event the adapter surfaces for it. Returns None for events Codex’s hook protocol does not expose.
render_hook_payload
Render a harness hook-protocol payload from neutral lifecycle inputs.