Motivation
Follow-up to #3219. The existing llm-worker SessionAccumulator already owns session identity, command counting, close-event ingestion, and idle readiness, but its persisted summary cannot distinguish a captured close from idle finalization or record whether expected terminal evidence was observed. It also intentionally omits close-only scanner sessions, so its population cannot provide the all-session denominator for an early-disconnect aggregate.
Relevant measured finding: 4 session IDs were reconstructable from the committed labeled corpus, with 0 close/termination events and 0 fully populated summaries.
Concrete change
Extend the existing state-summary path in llm-worker/worker.py; do not add a parallel session aggregator.
- Preserve an explicit terminal-observation value, distinguishing
cowrie.session.closed from worker idle finalization and from summaries still open after the observation window. Unknown/absent sensor evidence must remain unknown, not be inferred as a client-initiated disconnect.
- Record capture coverage sufficient to distinguish “close observed with zero commands” from “no close observed.” Do not infer a termination reason that the sensor did not emit.
- Make the all-session denominator explicit for Cowrie sessions that qualify for session analysis, or explicitly document and expose exclusions so a future aggregate can report the covered and excluded counts.
- Retain the existing
command_count, auth_success, closed, and duration_seconds compatibility contract.
Acceptance criteria
SessionAccumulator.document() and state_mapping() expose the new bounded terminal-observation/capture-coverage values without inventing a disconnect reason.
- Unit tests cover captured close, idle finalization, and still-open sessions, including zero-command close-only sessions.
- Existing session document compatibility tests still pass.
- Documentation states that terminal absence is ambiguous and must not be described as attacker abandonment or automation.
No production data query or behavior change is required for this schema/state work.
Motivation
Follow-up to #3219. The existing
llm-workerSessionAccumulatoralready owns session identity, command counting, close-event ingestion, and idle readiness, but its persisted summary cannot distinguish a captured close from idle finalization or record whether expected terminal evidence was observed. It also intentionally omits close-only scanner sessions, so its population cannot provide the all-session denominator for an early-disconnect aggregate.Relevant measured finding: 4 session IDs were reconstructable from the committed labeled corpus, with 0 close/termination events and 0 fully populated summaries.
Concrete change
Extend the existing state-summary path in
llm-worker/worker.py; do not add a parallel session aggregator.cowrie.session.closedfrom worker idle finalization and from summaries still open after the observation window. Unknown/absent sensor evidence must remain unknown, not be inferred as a client-initiated disconnect.command_count,auth_success,closed, andduration_secondscompatibility contract.Acceptance criteria
SessionAccumulator.document()andstate_mapping()expose the new bounded terminal-observation/capture-coverage values without inventing a disconnect reason.No production data query or behavior change is required for this schema/state work.