feat(profiler/behave_shell): emit motor.paste_burst_rate
BEHAVE-EXTRACTOR.md Phase A Step 3. Same paste-event ratio as
motor.input_modality but coarser-bucketed: this is the *habit*
signal (does the operator reach for paste at all?), where
input_modality is the dominant-channel signal.
* _features/motor.py:paste_burst_rate(ctx) emits one Observation
per session in {none, occasional, habitual} with confidence
0.70 / 0.70 / 0.80.
* Thresholds: PASTE_RATE_OCCASIONAL_MIN=0.10,
PASTE_RATE_HABITUAL_MIN=0.50.
Splits YOU-sim from LW/CLAUDE-FF/CLAUDE-CL — LLM-driven sessions
paste habitually, real humans rarely paste.
Tests: pure-typed → none; 1-paste-in-10 → occasional;
paste-majority → habitual; output-only → no observation; habitual
confidence > occasional confidence.
This commit is contained in:
@@ -11,10 +11,14 @@ from typing import Callable, Iterable
|
||||
from decnet_behave_core.spec.envelope import Observation
|
||||
|
||||
from decnet.profiler.behave_shell._ctx import SessionContext
|
||||
from decnet.profiler.behave_shell._features.motor import input_modality
|
||||
from decnet.profiler.behave_shell._features.motor import (
|
||||
input_modality,
|
||||
paste_burst_rate,
|
||||
)
|
||||
|
||||
FeatureFn = Callable[[SessionContext], Iterable[Observation]]
|
||||
|
||||
FEATURES: tuple[FeatureFn, ...] = (
|
||||
input_modality,
|
||||
paste_burst_rate,
|
||||
)
|
||||
|
||||
@@ -14,6 +14,8 @@ from decnet.profiler.behave_shell._features._emit import make_observation
|
||||
from decnet.profiler.behave_shell._thresholds import (
|
||||
MODALITY_PASTED_MIN,
|
||||
MODALITY_TYPED_MAX,
|
||||
PASTE_RATE_HABITUAL_MIN,
|
||||
PASTE_RATE_OCCASIONAL_MIN,
|
||||
)
|
||||
|
||||
|
||||
@@ -43,3 +45,34 @@ def input_modality(ctx: SessionContext) -> Iterator[Observation]:
|
||||
value=modality,
|
||||
confidence=confidence,
|
||||
)
|
||||
|
||||
|
||||
def paste_burst_rate(ctx: SessionContext) -> Iterator[Observation]:
|
||||
"""Emit ``motor.paste_burst_rate`` ∈ {none, occasional, habitual}.
|
||||
|
||||
Same paste-event ratio as ``input_modality`` but coarser-bucketed:
|
||||
this primitive is the *habit* signal (does the operator reach for
|
||||
paste at all?), where input_modality is the dominant-channel
|
||||
signal (is the session paste-driven overall?). Splits YOU-sim from
|
||||
LW/CLAUDE-FF/CLAUDE-CL — LLM-driven sessions paste habitually,
|
||||
real humans don't.
|
||||
"""
|
||||
n = len(ctx.input_events)
|
||||
if n == 0:
|
||||
return
|
||||
ratio = ctx.paste_event_count / n
|
||||
if ratio >= PASTE_RATE_HABITUAL_MIN:
|
||||
level = "habitual"
|
||||
confidence = 0.80
|
||||
elif ratio >= PASTE_RATE_OCCASIONAL_MIN:
|
||||
level = "occasional"
|
||||
confidence = 0.70
|
||||
else:
|
||||
level = "none"
|
||||
confidence = 0.70
|
||||
yield make_observation(
|
||||
ctx,
|
||||
primitive="motor.paste_burst_rate",
|
||||
value=level,
|
||||
confidence=confidence,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user