fix(session_exec): stop duplicate session:start for raw sessions — emit session:config instead - #79
Merged
Conversation
…tart for raw mode
Root cause (Bug 2):
When session.raw=True, the Rust kernel emits session:start once (the
base event), then calls emit_raw_field_if_configured() which emitted
session:start a SECOND TIME with the raw config payload. Every session
with raw=True got two session:start events per execute() call, separated
by 13+ seconds (the time for redact_secrets() on a 900KB+ config and
hook dispatch overhead).
Fix:
Change emit_raw_field_if_configured() to emit 'session:config' instead
of re-emitting the base event (session:start or session:resume). The
raw config payload is now in a dedicated event. Consumers that need the
raw mount plan should subscribe to 'session:config'.
The 'event_base' parameter is retained for API compatibility but is no
longer used as the emitted event name.
Performance impact:
The 13s startup delay (observed in sessions 98320ded and 69ab20de) came
from hook chains processing a 900KB session:start payload twice. With
this fix, the raw config is emitted as session:config (still slow for
large configs, but at least it's not mistaken for a lifecycle event).
Migration:
Downstream consumers (e.g. hook-context-intelligence) that read the raw
config from session:start must now subscribe to session:config.
Tests:
- test_session_start_dedup.py (new): 4 tests asserting
1. session:start emitted exactly once for raw sessions
2. session:config emitted with raw payload
3. session:start still emitted (guard against over-correction)
4. non-raw sessions unaffected (still emit session:start exactly once)
Brian Krabach (bkrabach)
force-pushed
the
fix/dedup-session-start-raw-emit
branch
from
May 18, 2026 10:49
ee16758 to
6d56a7e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bug 2 from session lifecycle investigation: when
session.raw=True, every call toexecute()was emitting twosession:startevents separated by 7–13 seconds:session:start(small payload, no raw config)emit_raw_field_if_configured()emits a secondsession:startwith the full 900KB+ raw configThe 13s gap is the time for
redact_secrets(config)on a massive config + hook dispatch overhead.Root Cause
_session_exec.py::emit_raw_field_if_configured()was designed to emit the raw config on the base session event name (session:start,session:resume). But the Rust kernel already emitted the base event synchronously before calling this helper, so both emits hit the samesession:startevent type.Fix
Change
emit_raw_field_if_configured()to emitsession:configinstead of re-emittingsession:start. The raw mount plan is now in a dedicated event.API compatibility: The
event_baseparameter is retained in the function signature but is no longer used as the event name.Migration
Downstream consumers that read raw config from
session:startmust subscribe tosession:configinstead. Known affected systems:hook-context-intelligence— reads raw session config for graph enrichment (separate PR needed)Evidence
Observed in sessions
3dca44c1and69ab20defrombehavior-provenanceworkspace:After fix: single
session:start+ separatesession:configevent.TDD Red-Green Cycle
RED (before fix):
test_session_start_emitted_exactly_once_for_raw_mode→ FAILED (count=2)test_raw_config_captured_in_session_config_event→ FAILED (no session:config event)GREEN (after fix):
Files Changed
python/amplifier_core/_session_exec.pyevent_baseto"session:config"bindings/python/tests/test_session_start_dedup.pyTest Results