You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: v3.5.0 commit 2 -- signal descriptors + validation
descriptors.py
Descriptor gains signal_only: bool = False field. When True, the descriptor
requires a signal-enabled rollout; the loop validates this at startup.
RolloutTrace gains three optional signal history fields:
signal_emission_history: (T,) mean emission activity per trace step
signal_reception_history: (T,) mean |reception response| per trace step
signal_retention: float final_mass / initial_mass scalar
slice() updated to preserve all three fields.
Three new signal descriptor compute functions:
compute_emission_activity: mean emission over trace tail, normalized by
0.05 (max emission_rate). Measures dynamic emission, not just the
emission_rate parameter. Zero for non-signal traces.
compute_receptor_sensitivity: mean |reception response| over trace tail,
normalized by 0.5. Measures chemical responsiveness. Zero for non-signal.
compute_signal_retention: final_mass / initial_mass clipped to [0,1].
High = conservative emitter, low = aggressive broadcaster. 1.0 for
non-signal traces (no mass lost).
All three registered in REGISTRY with signal_only=True.
Ecological roles: broadcaster (high emit, low retain), listener (low emit,
high sensitivity), predator candidate (high emit + high sensitivity + high alpha).
rollout.py
emission_np and reception_np buffers allocated only for signal rollouts.
Per-step: emission activity = G_pos_mean * rate; reception = |dot(signal_mean,
receptor_profile)|. Both captured into trace tail. signal_retention_val
computed as final_mass / initial_mass. All three passed to RolloutTrace.
loop.py
After resolve_descriptors(), validate that no signal_only descriptor is
active when signal_field=False. Raises ValueError with message pointing
to --signal-field if violated.
tests
test_descriptors.py: 15 new tests for all three signal descriptors covering
zero-for-non-signal, zero-for-empty, scaling, clipping, unit interval.
test_descriptor_registry.py: registry count updated 15→18; expected names
set updated with emission_activity, receptor_sensitivity, signal_retention.
test_loop.py: 3 new validation tests covering error-on-signal-only-without-
signal-field, no-error-with-signal-field, no-error-for-standard-descriptors.
422 passed, 0 errors, 0 warnings
0 commit comments