Anything observing hook activity by parsing forestage's headless NDJSON stream will under-report five of six events, which matters now that repo-settings hooks are a supported delivery surface (sideshow repo-bindings; observed on the aae-orc pilot, ArcavenAE/aae-orc#128, D8).
Expected: hook lifecycle frames (`hook_started`/`hook_response`) for each hook event that executes.
Actual: in `forestage -p ... --output-format stream-json --streaming`, only SessionStart produced lifecycle frames. PreToolUse, PostToolUse, Stop, SubagentStop, and SessionEnd all executed (proven by the dispatcher's own logs and by an honored blocking PreToolUse) but emitted no frames; the block was visible only as a `tool_result` error.
This may be upstream Claude Code stream-json behavior that forestage passes through rather than a forestage defect; the first step is establishing which side drops the frames (compare against bare `claude -p --output-format stream-json` on the same repo). If it is upstream, this issue becomes the tracking point for whatever forestage can surface instead (deriving hook events from its own subprocess plumbing, or documenting the gap).
Observed at forestage 5b6665f, built from source on the pilot machine.
Anything observing hook activity by parsing forestage's headless NDJSON stream will under-report five of six events, which matters now that repo-settings hooks are a supported delivery surface (sideshow repo-bindings; observed on the aae-orc pilot, ArcavenAE/aae-orc#128, D8).
Expected: hook lifecycle frames (`hook_started`/`hook_response`) for each hook event that executes.
Actual: in `forestage -p ... --output-format stream-json --streaming`, only SessionStart produced lifecycle frames. PreToolUse, PostToolUse, Stop, SubagentStop, and SessionEnd all executed (proven by the dispatcher's own logs and by an honored blocking PreToolUse) but emitted no frames; the block was visible only as a `tool_result` error.
This may be upstream Claude Code stream-json behavior that forestage passes through rather than a forestage defect; the first step is establishing which side drops the frames (compare against bare `claude -p --output-format stream-json` on the same repo). If it is upstream, this issue becomes the tracking point for whatever forestage can surface instead (deriving hook events from its own subprocess plumbing, or documenting the gap).
Observed at forestage 5b6665f, built from source on the pilot machine.